diff --git a/AUTHORS b/AUTHORS index a20adc5..07ee1ea 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -1133,6 +1133,7 @@ Saikrishna Arcot <saiarcot895@gmail.com> Sajal Khandelwal <skhandelwa22@bloomberg.net> Sajeesh Sidharthan <sajeesh.sidharthan@amd.corp-partner.google.com> +Sakib Shabir <s1.tantray@samsung.com> Saksham Mittal <gotlouemail@gmail.com> Salvatore Iovene <salvatore.iovene@intel.com> Sam James <sam@gentoo.org>
diff --git a/DEPS b/DEPS index 55b626d..73a0586 100644 --- a/DEPS +++ b/DEPS
@@ -314,15 +314,15 @@ # 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': '382920373b20cb807dfb2972ecfaf8eef22548a9', + 'skia_revision': 'c6413673d2d4d6e3a4837d3cecfe152243042415', # 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': '42b3deee7cc595ffeb9b77505cabe460f7e71b91', + 'v8_revision': '160c55f1d4b89c8a9e249130838d9e729325b528', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '91ef1f3cfd307b1b48ef692b5ab44520563a22c4', + 'angle_revision': 'eb0d59973d21f845b5785563f5d56b8ebb617478', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -330,7 +330,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '71c92d906915cb0f0d8bedc5c81b154d954f0034', + 'pdfium_revision': '1dc2fc9894094165089a60b2fb75164e592bcb8c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -365,7 +365,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': 'd7b63a966bdedeb52511913bc9d7de170b213d7e', + 'freetype_revision': 'babe6af16740f3fa3c19ef4b689f29d574c5fbc8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -405,7 +405,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '94b88f0598f5c47288b7f5493490bbfe372dabaa', + 'devtools_frontend_revision': '614e1c8242dfa60a241368d72c31384c14afaba3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -445,7 +445,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': '5ca21ed720844ddd5b10547f0758564cfc59997a', + 'dawn_revision': '9f1bd725eb44c9da63066842cd1fa6842d1157c8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -501,7 +501,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. - 'libunwind_revision': 'd9b4abf6b6c3e4541766df4eedaf534ed1322a8e', + 'libunwind_revision': '244575ffb656e4d2a2c88410c624dfbd5af68044', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -521,7 +521,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '7cee6b00d34adc4da2ff2a4d373e44fc27a9a223', + 'libcxx_revision': '3e8a3b3c5d497eb7250566a63432046baf95481a', # GN CIPD package version. 'gn_version': 'git_revision:991530ce394efb58fcd848195469022fa17ae126', @@ -814,7 +814,7 @@ }, 'src/chrome/test/data/autofill/captured_sites/artifacts': { - 'url': Var('chrome_git') + '/chrome/test/captured_sites/autofill.git' + '@' + 'd6062d44fe4e2216148d600e0ec195cfc4954ce1', + 'url': Var('chrome_git') + '/chrome/test/captured_sites/autofill.git' + '@' + 'd880bea5e920cce2e74ff9eeb929a38ceaf5c1ba', 'condition': 'checkout_chromium_autofill_test_dependencies', }, @@ -845,7 +845,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '55f9354534a9170aebc212260f3a8e73c2804a32', + 'e3a3ec407403dece9002c87d4de7130e2ab877e4', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1051,7 +1051,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'Bhz5Zr8-PhtdWdHbfxFeMvoDSibSwm6VTSAEh8QyoHsC', + 'version': 'tp63GXhagjuqaueX7s18Dpuf8fE1dvEDPtr1mfnlR1IC', }, ], 'condition': 'checkout_android', @@ -1260,7 +1260,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '220e3a70773a42e87b7356e7ae3f70327df04101', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0a79963e8dbec43dd3b16f43f81b3b8591972453', 'condition': 'checkout_chromeos', }, @@ -1301,7 +1301,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '86e6e655de96ade68a60ac01e940b9bfc5fb05ee', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '616289d464d11fbcc8c8b063af4d2b6c372f5e14', 'condition': 'checkout_src_internal', }, @@ -1790,7 +1790,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'e5ad1783507a8eadfee5b8f8fad200a66db59fee', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '15336a4d7f58ebec9421237bd888145095bf9aca', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1830,7 +1830,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'WptUn43oi_BkFPtEyZTdUD9wZo1yy8OPVqFwdP3jmqoC', + 'version': 'f6AwZX-cIa-qdx2fK93cJy9cfTg9ZqO2PkBWDNUMZXQC', }, ], 'condition': 'checkout_android', @@ -1972,10 +1972,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'f4bf599a8b575df685c31d9c4729a70a04e377ed', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'be1210e145e89e7a2943947d983f9592495e0f52', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'cff8019fdd22c52e711ae90ed0659cf4ac0a8509', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '090699a01bfc2f91af97e6461ff126bef996905a', + Var('webrtc_git') + '/src.git' + '@' + '4b583c732301ea096a867287e974604d15a6af74', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -4033,7 +4033,7 @@ # Dependencies from src_internal 'src/chromeos/assistant/internal': { 'url': Var('chrome_git') + '/chrome/assistant.git' + '@' + - '000d2387867d26ced802a4e18ef0ef970e17a755', + '5c8d934c2f1056cf21a80ba7896d6a65977dd580', 'condition': 'checkout_src_internal and checkout_chromeos', }, @@ -4227,7 +4227,7 @@ 'src/components/resources/default_200_percent/google_chrome': { 'url': Var('chrome_git') + '/chrome/components/default_200_percent/google_chrome.git' + '@' + - '66e7e3c423b0a795a3706ab63d3e9adfd8c5a646', + '753a08f83909054e694a46f0ca1b06408aee8bd1', 'condition': 'checkout_src_internal', }, @@ -4269,7 +4269,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '8dee0d1c5ee5e14dde381c8a1ec44b82e9d0eaec', + '6e026a76cf60b32d9e8ac71e7aaacca05a6b1c37', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 3c23d94a..4b5b864 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -28,7 +28,6 @@ import("//third_party/jni_zero/jni_zero.gni") import("//tools/grit/repack.gni") import("//tools/resources/generate_resource_allowlist.gni") -import("//weblayer/variables.gni") assert(!is_cronet_build) @@ -71,7 +70,6 @@ # It's used to define the allowlist of resources to be pulled out of language # splits. See |shared_resources_allowlist_target|. standalone_system_webview_apk_tmpl("system_webview_no_weblayer_apk") { - exclude_weblayer_java = true apk_name = "SystemWebViewNoWebLayer" # Don't include any code to speed up compilation. This is used only for the @@ -435,10 +433,6 @@ # Contains all Java dependencies used by WebView. java_group("android_webview_java") { deps = [ ":android_webview_no_weblayer_java" ] - - if (webview_includes_weblayer) { - deps += [ "//weblayer/browser/java" ] - } } # An empty group included in //BUILD.gn to make this and other WebView build @@ -912,11 +906,6 @@ repack_allowlist = system_webview_pak_allowlist deps += [ ":system_webview_pak_allowlist" ] } - - if (webview_includes_weblayer) { - sources += [ "$root_gen_dir/weblayer/weblayer_resources.pak" ] - deps += [ "//weblayer:resources" ] - } } repack("repack_100_percent") { @@ -934,10 +923,6 @@ repack_allowlist = system_webview_pak_allowlist deps += [ ":system_webview_pak_allowlist" ] } - if (webview_includes_weblayer) { - sources += [ "$target_gen_dir/components_resources_100_percent.pak" ] - deps += [ ":generate_components_scaled_resources" ] - } } android_assets("pak_file_assets") { @@ -1059,10 +1044,6 @@ script = "//mojo/public/tools/bindings/concatenate-files.py" inputs = [ "//android_webview/ui/grit_resources_allowlist.txt" ] - if (webview_includes_weblayer) { - inputs += [ "//weblayer/grit_resources_allowlist.txt" ] - } - outputs = [ "$target_gen_dir/grit_resources_allowlist.txt" ] args = rebase_path(inputs, root_build_dir) + rebase_path(outputs, root_build_dir) @@ -1115,31 +1096,6 @@ } } -if (webview_includes_weblayer) { - grit("generate_components_scaled_resources") { - source = "../components/resources/components_scaled_resources.grd" - - # See :generate_webui_resources for an explanation of the allowlist - _allowlist = rebase_path("$target_gen_dir/grit_resources_allowlist.txt", - root_build_dir) - - grit_flags = [ - "-w", - _allowlist, - ] - outputs = [ - "grit/components_scaled_resources.h", - "grit/components_scaled_resources_map.cc", - "grit/components_scaled_resources_map.h", - "components_resources_100_percent.pak", - "components_resources_200_percent.pak", - "components_resources_300_percent.pak", - ] - - deps = [ ":concatenate_resources_allowlists" ] - } -} - grit("generate_components_strings") { source = "../components/components_strings.grd"
diff --git a/android_webview/browser/BUILD.gn b/android_webview/browser/BUILD.gn index 050c962..7ac1e73 100644 --- a/android_webview/browser/BUILD.gn +++ b/android_webview/browser/BUILD.gn
@@ -113,8 +113,6 @@ "aw_web_contents_view_delegate.h", "aw_web_ui_controller_factory.cc", "aw_web_ui_controller_factory.h", - "component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc", - "component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h", "component_updater/loader_policies/empty_component_loader_policy.cc", "component_updater/loader_policies/empty_component_loader_policy.h", "component_updater/loader_policies/origin_trials_component_loader_policy.cc",
diff --git a/android_webview/browser/aw_feature_list_creator.cc b/android_webview/browser/aw_feature_list_creator.cc index bdf84e4..739d97e 100644 --- a/android_webview/browser/aw_feature_list_creator.cc +++ b/android_webview/browser/aw_feature_list_creator.cc
@@ -102,14 +102,6 @@ variations::prefs::kVariationsLastFetchTime, variations::prefs::kVariationsSeedDate, - // A dictionary that caches 'AppPackageNameLoggingRule' object which decides - // whether the app package name should be recorded in UMA or not. - prefs::kMetricsAppPackageNameLoggingRule, - - // The last time the apps package name allowlist was queried from the - // component update service, regardless if it was successful or not. - prefs::kAppPackageNameLoggingRuleLastUpdateTime, - // The state of the previous background tracing session. tracing::kBackgroundTracingSessionState,
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc deleted file mode 100644 index de62978..0000000 --- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc +++ /dev/null
@@ -1,302 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h" - -#include <stdint.h> -#include <stdio.h> - -#include <cstring> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "android_webview/browser/metrics/aw_metrics_service_client.h" -#include "android_webview/common/aw_features.h" -#include "android_webview/common/aw_switches.h" -#include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h" -#include "android_webview/common/metrics/app_package_name_logging_rule.h" -#include "base/command_line.h" -#include "base/containers/flat_map.h" -#include "base/feature_list.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/functional/bind.h" -#include "base/functional/callback.h" -#include "base/logging.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_util.h" -#include "base/task/thread_pool.h" -#include "base/time/time.h" -#include "base/values.h" -#include "base/version.h" -#include "components/component_updater/android/component_loader_policy.h" -#include "components/optimization_guide/core/bloom_filter.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace android_webview { - -const base::TimeDelta kWebViewAppsMinAllowlistThrottleTimeDelta = - base::Hours(1); -const base::TimeDelta kWebViewAppsMaxAllowlistThrottleTimeDelta = base::Days(2); - -namespace { - -// Persisted to logs, should never change. -constexpr char kAppsPackageNamesAllowlistMetricsSuffix[] = - "WebViewAppsPackageNamesAllowlist"; -constexpr int kBitsPerByte = 8; - -using AllowlistPraseStatus = - AwAppsPackageNamesAllowlistComponentLoaderPolicy::AllowlistPraseStatus; - -struct AllowListLookupResult { - AllowlistPraseStatus parse_status; - absl::optional<AppPackageNameLoggingRule> record_rule; -}; - -void RecordAndReportResult(AllowListLookupCallback lookup_callback, - AllowListLookupResult result) { - DCHECK(lookup_callback); - - UMA_HISTOGRAM_ENUMERATION( - "Android.WebView.Metrics.PackagesAllowList.ParseStatus", - result.parse_status); - std::move(lookup_callback).Run(result.record_rule); -} - -// Lookup the `package_name` in `allowlist_fd`, returns a null -// an `AllowListLookupResult` containing an `AppPackageNameLoggingRule` if it -// fails. -// -// `allowlist_fd` the fd of a file the contain a bloomfilter that represents an -// allowlist of apps package names. -// `num_hash` the number of hash functions to use in the -// `optimization_guide::BloomFilter`. -// `num_bits` the number of bits in the `optimization_guide::BloomFilter`. -// `package_name` the app package name to look up in the allowlist. -// `version` the allowlist version. -// `expiry_date` the expiry date of the allowlist, i.e the date after which -// this allowlist shouldn't be used. -AllowListLookupResult GetAppPackageNameLoggingRule( - base::ScopedFD allowlist_fd, - int num_hash, - int num_bits, - const std::string& package_name, - const base::Version& version, - const base::Time& expiry_date) { - // Transfer the ownership of the file from `allowlist_fd` to `file_stream`. - base::ScopedFILE file_stream(fdopen(allowlist_fd.release(), "r")); - if (!file_stream.get()) { - return {AllowlistPraseStatus::kIOError}; - } - - // TODO(https://crbug.com/1219496): use mmap instead of reading the whole - // file. - std::string bloom_filter_data; - if (!base::ReadStreamToString(file_stream.get(), &bloom_filter_data) || - bloom_filter_data.empty()) { - return {AllowlistPraseStatus::kIOError}; - } - - // Make sure the bloomfilter binary data is of the correct length. - if (bloom_filter_data.size() != - size_t((num_bits + kBitsPerByte - 1) / kBitsPerByte)) { - return {AllowlistPraseStatus::kMalformedBloomFilter}; - } - - if (optimization_guide::BloomFilter(num_hash, num_bits, bloom_filter_data) - .Contains(package_name)) { - return {AllowlistPraseStatus::kSuccess, - AppPackageNameLoggingRule(version, expiry_date)}; - } else { - return {AllowlistPraseStatus::kSuccess, - AppPackageNameLoggingRule(version, base::Time::Min())}; - } -} - -void SetAppPackageNameLoggingRule( - absl::optional<AppPackageNameLoggingRule> record) { - auto* metrics_service_client = AwMetricsServiceClient::GetInstance(); - DCHECK(metrics_service_client); - metrics_service_client->SetAppPackageNameLoggingRule(record); - metrics_service_client->SetAppPackageNameLoggingRuleLastUpdateTime( - base::Time::Now()); - - if (!record.has_value()) { - VLOG(2) << "Failed to load WebView apps package allowlist"; - return; - } - - VLOG(2) << "WebView apps package allowlist version " - << record.value().GetVersion() << " is loaded"; - if (record.value().IsAppPackageNameAllowed()) { - VLOG(2) << "App package name should be recorded until " - << record.value().GetExpiryDate(); - } else { - VLOG(2) << "App package name shouldn't be recorded"; - } -} - -bool ShouldThrottleAppPackageNamesAllowlistComponent( - base::Time last_update, - absl::optional<AppPackageNameLoggingRule> cached_record) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kWebViewDisablePackageAllowlistThrottling) || - last_update.is_null()) { - return false; - } - base::TimeDelta throttle_time_delta( - kWebViewAppsMinAllowlistThrottleTimeDelta); - if (cached_record.has_value()) { - base::Time expiry_date = cached_record.value().GetExpiryDate(); - bool in_the_allowlist = !expiry_date.is_min(); - bool is_allowlist_expired = expiry_date <= base::Time::Now(); - if (!in_the_allowlist || !is_allowlist_expired) { - throttle_time_delta = kWebViewAppsMaxAllowlistThrottleTimeDelta; - } - } - return base::Time::Now() - last_update <= throttle_time_delta; -} - -} // namespace - -AwAppsPackageNamesAllowlistComponentLoaderPolicy:: - AwAppsPackageNamesAllowlistComponentLoaderPolicy( - std::string app_package_name, - absl::optional<AppPackageNameLoggingRule> cached_record, - AllowListLookupCallback lookup_callback) - : app_package_name_(std::move(app_package_name)), - cached_record_(cached_record), - lookup_callback_(std::move(lookup_callback)) { - DCHECK(!app_package_name_.empty()); - DCHECK(lookup_callback_); -} - -AwAppsPackageNamesAllowlistComponentLoaderPolicy:: - ~AwAppsPackageNamesAllowlistComponentLoaderPolicy() = default; - -// `manifest` represents a JSON object that looks like this: -// { -// "name": "WebViewAppsPackageNamesAllowlist", -// -// /* The component version string, matches the param `version`. */ -// "version": "xxxx.xx.xx.xx", -// -// /* Bloomfilter parameters, set by the server side */ -// /* int32: number of hash functions used by the bloomfilter */ -// "bloomfilter_num_hash": xx -// /* int32: number of bits in the bloomfilter binary array */ -// "bloomfilter_num_bits": xx -// -// /* The allowlist expiry date after which the allowlist shouldn't be used. -// Its format is an int64 number representing the number of milliseconds -// after UNIX Epoch. */ -// "expiry_date": 12345678910 -// } -void AwAppsPackageNamesAllowlistComponentLoaderPolicy::ComponentLoaded( - const base::Version& version, - base::flat_map<std::string, base::ScopedFD>& fd_map, - base::Value::Dict manifest) { - DCHECK(version.IsValid()); - - // Have to use double because base::DictionaryValue doesn't support int64 - // values. - absl::optional<double> expiry_date_ms = - manifest.FindDoubleByDottedPath(kExpiryDateKey); - absl::optional<int> num_hash = - manifest.FindIntByDottedPath(kBloomFilterNumHashKey); - absl::optional<int> num_bits = - manifest.FindIntByDottedPath(kBloomFilterNumBitsKey); - // Being conservative and consider the allowlist expired when a valid expiry - // date is absent. - if (!expiry_date_ms.has_value() || !num_hash.has_value() || - !num_bits.has_value() || num_hash.value() <= 0 || num_bits.value() <= 0) { - RecordAndReportResult(std::move(lookup_callback_), - {AllowlistPraseStatus::kMissingFields}); - return; - } - - base::Time expiry_date = base::Time::UnixEpoch() + - base::Milliseconds(expiry_date_ms.value_or(0.0)); - if (expiry_date <= base::Time::Now()) { - RecordAndReportResult(std::move(lookup_callback_), - {AllowlistPraseStatus::kExpiredAllowlist}); - return; - } - - if (cached_record_.has_value() && - cached_record_.value().GetVersion() == version) { - RecordAndReportResult(std::move(lookup_callback_), - {AllowlistPraseStatus::kUsingCache, cached_record_}); - return; - } - - auto allowlist_iterator = fd_map.find(kAllowlistBloomFilterFileName); - if (allowlist_iterator == fd_map.end()) { - RecordAndReportResult(std::move(lookup_callback_), - {AllowlistPraseStatus::kMissingAllowlistFile}); - return; - } - - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&GetAppPackageNameLoggingRule, - std::move(allowlist_iterator->second), num_hash.value(), - num_bits.value(), std::move(app_package_name_), version, - expiry_date), - base::BindOnce(&RecordAndReportResult, std::move(lookup_callback_))); -} - -void AwAppsPackageNamesAllowlistComponentLoaderPolicy::ComponentLoadFailed( - component_updater::ComponentLoadResult /*error*/) { - DCHECK(lookup_callback_); - // TODO(crbug.com/1216200): Record the error in a histogram in the - // ComponentLoader for each component. - std::move(lookup_callback_).Run(absl::optional<AppPackageNameLoggingRule>()); -} - -void AwAppsPackageNamesAllowlistComponentLoaderPolicy::GetHash( - std::vector<uint8_t>* hash) const { - GetWebViewAppsPackageNamesAllowlistPublicKeyHash(hash); -} - -std::string AwAppsPackageNamesAllowlistComponentLoaderPolicy::GetMetricsSuffix() - const { - return kAppsPackageNamesAllowlistMetricsSuffix; -} - -void LoadPackageNamesAllowlistComponent( - component_updater::ComponentLoaderPolicyVector& policies, - AwMetricsServiceClient* metrics_service_client) { - DCHECK(metrics_service_client); - - // Prevent loading of client-side allowlist if using server-side allowlist - if (base::FeatureList::IsEnabled( - android_webview::features:: - kWebViewAppsPackageNamesServerSideAllowlist)) { - return; - } - absl::optional<AppPackageNameLoggingRule> cached_record = - metrics_service_client->GetCachedAppPackageNameLoggingRule(); - base::Time last_update = - metrics_service_client->GetAppPackageNameLoggingRuleLastUpdateTime(); - - bool should_throttle = ShouldThrottleAppPackageNamesAllowlistComponent( - last_update, cached_record); - UMA_HISTOGRAM_BOOLEAN( - "Android.WebView.Metrics.PackagesAllowList.ThrottleStatus", - should_throttle); - if (should_throttle) { - return; - } - - policies.push_back( - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - metrics_service_client->GetAppPackageName(), std::move(cached_record), - base::BindOnce(&SetAppPackageNameLoggingRule))); -} - -} // namespace android_webview
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h deleted file mode 100644 index 8458065..0000000 --- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h +++ /dev/null
@@ -1,107 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_LOADER_POLICIES_AW_APPS_PACKAGE_NAMES_ALLOWLIST_COMPONENT_LOADER_POLICY_H_ -#define ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_LOADER_POLICIES_AW_APPS_PACKAGE_NAMES_ALLOWLIST_COMPONENT_LOADER_POLICY_H_ - -#include <stdint.h> -#include <string> -#include <vector> - -#include "android_webview/common/metrics/app_package_name_logging_rule.h" -#include "base/containers/flat_map.h" -#include "base/files/scoped_file.h" -#include "base/functional/callback.h" -#include "base/values.h" -#include "components/component_updater/android/component_loader_policy.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace base { -class Time; -class Version; -} // namespace base - -namespace android_webview { - -class AwMetricsServiceClient; - -// All these constants have to be kept in sync with the allowlist generation -// server, see http://go/aw-package-names-allowlist-bloomfilter. -constexpr char kAllowlistBloomFilterFileName[] = "allowlistbloomfilter"; -constexpr char kBloomFilterNumHashKey[] = "bloomfilter_num_hash"; -constexpr char kBloomFilterNumBitsKey[] = "bloomfilter_num_bits"; -constexpr char kExpiryDateKey[] = "expiry_date"; - -// Minimum time to throttle querying the app package names allowlist from the -// component updater service, used when there is no valid cached allowlist -// result. Exposed for testing only. -extern const base::TimeDelta kWebViewAppsMinAllowlistThrottleTimeDelta; -// Maximum time to throttle querying the app package names allowlist from the -// component updater service, used when there is a valid cached allowlist -// result. Exposed for testing only. -extern const base::TimeDelta kWebViewAppsMaxAllowlistThrottleTimeDelta; - -// A callback for the result of loading and looking up the allowlist. If the -// allowlist loading fails, it will be called with a null record. -using AllowListLookupCallback = - base::OnceCallback<void(absl::optional<AppPackageNameLoggingRule>)>; - -// Defines a loader responsible for receiving the allowlist for apps package -// names that can be included in UMA records and lookup the embedding app's name -// in that list. -class AwAppsPackageNamesAllowlistComponentLoaderPolicy - : public component_updater::ComponentLoaderPolicy { - public: - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - enum class AllowlistPraseStatus { - kSuccess = 0, - kUsingCache = 1, - kMissingFields = 2, - kExpiredAllowlist = 3, - kMissingAllowlistFile = 4, - kIOError = 5, - kMalformedBloomFilter = 6, - kMaxValue = kMalformedBloomFilter, - }; - - // `app_package_name` the embedding app package name. - // `cached_record` the cached lookup result of a previous successfully - // loaded allowlist, if any. - // `lookup_callback` callback to report the result of looking up - // `app_package_name` in the packages names allowlist. - AwAppsPackageNamesAllowlistComponentLoaderPolicy( - std::string app_package_name, - absl::optional<AppPackageNameLoggingRule> cached_record, - AllowListLookupCallback lookup_callback); - ~AwAppsPackageNamesAllowlistComponentLoaderPolicy() override; - - AwAppsPackageNamesAllowlistComponentLoaderPolicy( - const AwAppsPackageNamesAllowlistComponentLoaderPolicy&) = delete; - AwAppsPackageNamesAllowlistComponentLoaderPolicy& operator=( - const AwAppsPackageNamesAllowlistComponentLoaderPolicy&) = delete; - - // The following methods override ComponentLoaderPolicy. - void ComponentLoaded(const base::Version& version, - base::flat_map<std::string, base::ScopedFD>& fd_map, - base::Value::Dict manifest) override; - void ComponentLoadFailed( - component_updater::ComponentLoadResult error) override; - void GetHash(std::vector<uint8_t>* hash) const override; - std::string GetMetricsSuffix() const override; - - private: - std::string app_package_name_; - absl::optional<AppPackageNameLoggingRule> cached_record_; - - AllowListLookupCallback lookup_callback_; -}; - -void LoadPackageNamesAllowlistComponent( - component_updater::ComponentLoaderPolicyVector& policies, - AwMetricsServiceClient* metrics_service_client); - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_LOADER_POLICIES_AW_APPS_PACKAGE_NAMES_ALLOWLIST_COMPONENT_LOADER_POLICY_H_
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc deleted file mode 100644 index b63c57d2..0000000 --- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc +++ /dev/null
@@ -1,438 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h" - -#include <fcntl.h> -#include <stdio.h> -#include <unistd.h> - -#include <utility> - -#include "android_webview/browser/metrics/aw_metrics_service_client.h" -#include "android_webview/common/aw_features.h" -#include "android_webview/common/metrics/app_package_name_logging_rule.h" -#include "base/containers/flat_map.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/metrics/user_metrics.h" -#include "base/run_loop.h" -#include "base/sequence_checker.h" -#include "base/test/bind.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/task_environment.h" -#include "base/time/time.h" -#include "base/values.h" -#include "base/version.h" -#include "components/component_updater/android/component_loader_policy.h" -#include "components/optimization_guide/core/bloom_filter.h" -#include "components/prefs/testing_pref_service.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace android_webview { - -using AllowlistPraseStatus = - AwAppsPackageNamesAllowlistComponentLoaderPolicy::AllowlistPraseStatus; - -namespace { - -constexpr int kNumHash = 11; -constexpr int kNumBitsPerEntry = 16; -constexpr char kTestAllowlistVersion[] = "123.456.789.10"; -const std::string kTestAllowlist[] = {"com.example.test", "my.fake.app", - "yet.another.app"}; -constexpr char kAllowlistPraseStatusHistogramName[] = - "Android.WebView.Metrics.PackagesAllowList.ParseStatus"; - -double MillisFromUnixEpoch(const base::Time& time) { - return (time - base::Time::UnixEpoch()).InMillisecondsF(); -} - -base::Value::Dict BuildTestManifest() { - base::Value::Dict manifest; - manifest.Set(kBloomFilterNumHashKey, base::Value(kNumHash)); - manifest.Set(kBloomFilterNumBitsKey, base::Value(3 * kNumBitsPerEntry)); - manifest.Set( - kExpiryDateKey, - base::Value(MillisFromUnixEpoch(base::Time::Now() + base::Days(1)))); - - return manifest; -} - -} // namespace - -class AwAppsPackageNamesAllowlistComponentLoaderPolicyTest - : public ::testing::Test { - public: - void SetUp() override { - ASSERT_TRUE(base::CreateTemporaryFile(&allowlist_path_)); - } - - void TearDown() override { - base::DeleteFile(allowlist_path_); - } - - void WriteAllowListToFile(const std::vector<uint8_t>& data) { - ASSERT_TRUE(base::WriteFile(allowlist_path_, data)); - } - - void WritePackageNamesAllowListToFile() { - auto filter = std::make_unique<optimization_guide::BloomFilter>( - kNumHash, kNumBitsPerEntry * std::size(kTestAllowlist)); - for (const auto& package : kTestAllowlist) { - filter->Add(package); - } - WriteAllowListToFile(filter->bytes()); - } - - base::ScopedFD OpenAndGetAllowlistFd() { - int allowlist_fd = open(allowlist_path_.value().c_str(), O_RDONLY); - CHECK(allowlist_fd) << "Failed to open FD for " << allowlist_path_; - return base::ScopedFD(allowlist_fd); - } - - void LookupConfirmationCallback( - absl::optional<AppPackageNameLoggingRule> record) { - EXPECT_TRUE(checker_.CalledOnValidSequence()); - allowlist_lookup_result_ = record; - lookup_run_loop_.Quit(); - } - - protected: - base::test::TaskEnvironment env_; - // Has to be init after TaskEnvironment. - base::SequenceCheckerImpl checker_; - base::RunLoop lookup_run_loop_; - base::HistogramTester histogram_tester_; - - absl::optional<AppPackageNameLoggingRule> allowlist_lookup_result_; - - private: - base::FilePath allowlist_path_; -}; - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestExistingPackageName) { - WritePackageNamesAllowListToFile(); - base::flat_map<std::string, base::ScopedFD> fd_map; - fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd(); - base::Value::Dict manifest = BuildTestManifest(); - base::Time one_day_from_now = base::Time::Now() + base::Days(1); - manifest.Set(kExpiryDateKey, MillisFromUnixEpoch(one_day_from_now)); - base::Version new_version(kTestAllowlistVersion); - - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - kTestAllowlist[1], - AppPackageNameLoggingRule(base::Version("123.456.789.0"), - base::Time::Min()), - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(new_version, fd_map, std::move(manifest)); - - lookup_run_loop_.Run(); - ASSERT_TRUE(allowlist_lookup_result_.has_value()); - EXPECT_TRUE(allowlist_lookup_result_.value().IsAppPackageNameAllowed()); - EXPECT_EQ(allowlist_lookup_result_.value().GetVersion(), new_version); - EXPECT_EQ(allowlist_lookup_result_.value().GetExpiryDate(), one_day_from_now); - - histogram_tester_.ExpectBucketCount(kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kSuccess, 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestSameVersionAsCache) { - base::flat_map<std::string, base::ScopedFD> fd_map; - base::Time one_day_from_now = base::Time::Now() + base::Days(1); - base::Version version(kTestAllowlistVersion); - - AppPackageNameLoggingRule expected_record(version, one_day_from_now); - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - "test.some.app", expected_record, - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(version, fd_map, BuildTestManifest()); - - lookup_run_loop_.Run(); - ASSERT_TRUE(allowlist_lookup_result_.has_value()); - EXPECT_TRUE(allowlist_lookup_result_.value().IsAppPackageNameAllowed()); - EXPECT_TRUE(expected_record.IsSameAs(allowlist_lookup_result_.value())); - - histogram_tester_.ExpectBucketCount(kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kUsingCache, 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestNonExistingPackageName) { - WritePackageNamesAllowListToFile(); - base::flat_map<std::string, base::ScopedFD> fd_map; - fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd(); - base::Version new_version(kTestAllowlistVersion); - - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - "non.existent.app", absl::optional<AppPackageNameLoggingRule>(), - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(new_version, fd_map, BuildTestManifest()); - - lookup_run_loop_.Run(); - ASSERT_TRUE(allowlist_lookup_result_.has_value()); - EXPECT_EQ(allowlist_lookup_result_.value().GetVersion(), new_version); - EXPECT_FALSE(allowlist_lookup_result_.value().IsAppPackageNameAllowed()); - - histogram_tester_.ExpectBucketCount(kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kSuccess, 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestAllowlistFileNotInMap) { - base::flat_map<std::string, base::ScopedFD> fd_map; - fd_map["another_file"] = OpenAndGetAllowlistFd(); - - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(), - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(base::Version(kTestAllowlistVersion), fd_map, - BuildTestManifest()); - - lookup_run_loop_.Run(); - EXPECT_FALSE(allowlist_lookup_result_.has_value()); - - histogram_tester_.ExpectBucketCount( - kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kMissingAllowlistFile, 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestMissingBloomFilterParams) { - WritePackageNamesAllowListToFile(); - base::flat_map<std::string, base::ScopedFD> fd_map; - fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd(); - - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(), - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(base::Version(kTestAllowlistVersion), fd_map, - /*manifest=*/base::Value::Dict()); - - lookup_run_loop_.Run(); - EXPECT_FALSE(allowlist_lookup_result_.has_value()); - - histogram_tester_.ExpectBucketCount(kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kMissingFields, 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestTooShortBloomFilter) { - WriteAllowListToFile(std::vector<uint8_t>(2, 0xff)); - base::flat_map<std::string, base::ScopedFD> fd_map; - fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd(); - - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(), - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(base::Version(kTestAllowlistVersion), fd_map, - BuildTestManifest()); - - lookup_run_loop_.Run(); - EXPECT_FALSE(allowlist_lookup_result_.has_value()); - - histogram_tester_.ExpectBucketCount( - kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kMalformedBloomFilter, 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestTooLongBloomFilter) { - WriteAllowListToFile(std::vector<uint8_t>(2000, 0xff)); - base::flat_map<std::string, base::ScopedFD> fd_map; - fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd(); - - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(), - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(base::Version(kTestAllowlistVersion), fd_map, - BuildTestManifest()); - - lookup_run_loop_.Run(); - EXPECT_FALSE(allowlist_lookup_result_.has_value()); - - histogram_tester_.ExpectBucketCount( - kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kMalformedBloomFilter, 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestExpiredAllowlist) { - WritePackageNamesAllowListToFile(); - base::flat_map<std::string, base::ScopedFD> fd_map; - fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd(); - base::Value::Dict manifest = BuildTestManifest(); - manifest.Set( - kExpiryDateKey, - base::Value(MillisFromUnixEpoch(base::Time::Now() - base::Days(1)))); - - auto policy = - std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>( - kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(), - base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest:: - LookupConfirmationCallback, - base::Unretained(this))); - - policy->ComponentLoaded(base::Version(kTestAllowlistVersion), fd_map, - std::move(manifest)); - - lookup_run_loop_.Run(); - EXPECT_FALSE(allowlist_lookup_result_.has_value()); - - histogram_tester_.ExpectBucketCount(kAllowlistPraseStatusHistogramName, - AllowlistPraseStatus::kExpiredAllowlist, - 1); - histogram_tester_.ExpectTotalCount(kAllowlistPraseStatusHistogramName, 1); -} - -// Helper functions for throttling tests, defining them near tests body for -// better readability. -namespace { -class AwMetricsServiceClientTestDelegate - : public AwMetricsServiceClient::Delegate { - void RegisterAdditionalMetricsProviders( - metrics::MetricsService* service) override {} - void AddWebViewAppStateObserver(WebViewAppStateObserver* observer) override {} - bool HasAwContentsEverCreated() const override { return false; } -}; - -void TestThrottling(base::Time time, - AwMetricsServiceClient* client, - bool expect_throttling) { - if (!time.is_null()) { - client->SetAppPackageNameLoggingRuleLastUpdateTime(time); - } - - component_updater::ComponentLoaderPolicyVector policies; - LoadPackageNamesAllowlistComponent(policies, client); - EXPECT_EQ(policies.size(), expect_throttling ? 0 : 1u); -} - -void TestThrottlingAllowlist(absl::optional<AppPackageNameLoggingRule> rule, - bool expect_throttling) { - TestingPrefServiceSimple prefs; - AwMetricsServiceClient::RegisterMetricsPrefs(prefs.registry()); - AwMetricsServiceClient client( - std::make_unique<AwMetricsServiceClientTestDelegate>()); - client.Initialize(&prefs); - client.SetAppPackageNameLoggingRule(rule); - - // No previous last_update record: should never throttle. - TestThrottling(base::Time(), &client, /*expect_throttling=*/false); - - // last_update record > max_throttle_time : should never throttle. - TestThrottling(base::Time::Now() - kWebViewAppsMaxAllowlistThrottleTimeDelta - - base::Days(1), - &client, - /*expect_throttling=*/false); - - // min_throttle_time < last_update record < max_throttle_time : maybe - // throttle. - TestThrottling(base::Time::Now() - kWebViewAppsMaxAllowlistThrottleTimeDelta + - kWebViewAppsMinAllowlistThrottleTimeDelta, - &client, - /*expect_throttling=*/expect_throttling); - - // last_update record < min_throttle_time : should always throttle. - TestThrottling(base::Time::Now() - kWebViewAppsMinAllowlistThrottleTimeDelta + - base::Minutes(30), - &client, - /*expect_throttling=*/true); -} - -} // namespace - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestThrottlingAllowlist_AbsentCache) { - // Since the server-side allowlist is now enabled by default, - // the simplest thing to do in order to preserve the same testing logic - // is to disable it. - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - base::SetRecordActionTaskRunner(env_.GetMainThreadTaskRunner()); - - TestThrottlingAllowlist(absl::optional<AppPackageNameLoggingRule>(), - /*expect_throttling=*/false); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestThrottlingAllowlist_ValidCacheAllowedApp) { - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - base::SetRecordActionTaskRunner(env_.GetMainThreadTaskRunner()); - - TestThrottlingAllowlist( - AppPackageNameLoggingRule(base::Version(kTestAllowlistVersion), - base::Time::Now() + base::Days(1)), - /*expect_throttling=*/true); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestThrottlingAllowlist_ValidCacheNotAllowedApp) { - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - base::SetRecordActionTaskRunner(env_.GetMainThreadTaskRunner()); - - TestThrottlingAllowlist( - AppPackageNameLoggingRule(base::Version(kTestAllowlistVersion), - base::Time::Min()), - /*expect_throttling=*/true); -} - -TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest, - TestThrottlingAllowlist_ExpiredAllowedCache) { - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - base::SetRecordActionTaskRunner(env_.GetMainThreadTaskRunner()); - - TestThrottlingAllowlist( - AppPackageNameLoggingRule(base::Version(kTestAllowlistVersion), - base::Time::Now() - base::Days(1)), - /*expect_throttling=*/false); -} - -} // namespace android_webview
diff --git a/android_webview/browser/component_updater/registration.cc b/android_webview/browser/component_updater/registration.cc index 9f2f76a..c43c563 100644 --- a/android_webview/browser/component_updater/registration.cc +++ b/android_webview/browser/component_updater/registration.cc
@@ -4,7 +4,6 @@ #include "android_webview/browser/component_updater/registration.h" -#include "android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h" #include "android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.h" #include "android_webview/browser/component_updater/origin_trials_component_loader.h" #include "android_webview/browser/component_updater/trust_token_key_commitments_component_loader.h" @@ -16,8 +15,6 @@ component_updater::ComponentLoaderPolicyVector policies; LoadTrustTokenKeyCommitmentsComponent(policies); LoadOriginTrialsComponent(policies); - LoadPackageNamesAllowlistComponent(policies, - AwMetricsServiceClient::GetInstance()); LoadEmptyComponent(policies); return policies; }
diff --git a/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc b/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc index 3c59dca..f3f7743 100644 --- a/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc +++ b/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc
@@ -9,8 +9,6 @@ #include <vector> #include "android_webview/browser/metrics/aw_metrics_service_client.h" -#include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h" -#include "android_webview/common/metrics/app_package_name_logging_rule.h" #include "components/component_updater/android/components_info_holder.h" #include "components/component_updater/component_updater_service.h" #include "components/metrics/component_metrics_provider.h" @@ -29,28 +27,8 @@ // only info WebView keeps about components. // TODO(https://crbug.com/1228535): record the component's Omaha fingerprint. std::vector<ComponentInfo> AwComponentMetricsProviderDelegate::GetComponents() { - std::vector<ComponentInfo> components = - component_updater::ComponentsInfoHolder::GetInstance()->GetComponents(); - - // WebViewAppsPackageNamesAllowlist component has a special case because it - // caches the result from previous loads of the component. We want to record - // the info of the component that is actually used (cached) regardless of the - // info the ComponentsInfoHolder has. - components.erase( - std::remove_if(components.begin(), components.end(), - [](const ComponentInfo& c) { - return c.id == - kWebViewAppsPackageNamesAllowlistComponentId; - }), - components.end()); - absl::optional<AppPackageNameLoggingRule> record = - client_->GetCachedAppPackageNameLoggingRule(); - if (record.has_value()) { - components.emplace_back(kWebViewAppsPackageNamesAllowlistComponentId, "", - std::u16string(), record.value().GetVersion(), ""); - } - - return components; + return component_updater::ComponentsInfoHolder::GetInstance() + ->GetComponents(); } } // namespace android_webview
diff --git a/android_webview/browser/metrics/aw_component_metrics_provider_delegate_unittests.cc b/android_webview/browser/metrics/aw_component_metrics_provider_delegate_unittests.cc index 6fa93f2..8b4a77e 100644 --- a/android_webview/browser/metrics/aw_component_metrics_provider_delegate_unittests.cc +++ b/android_webview/browser/metrics/aw_component_metrics_provider_delegate_unittests.cc
@@ -11,8 +11,6 @@ #include "android_webview/browser/lifecycle/webview_app_state_observer.h" #include "android_webview/browser/metrics/aw_metrics_service_client.h" -#include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h" -#include "android_webview/common/metrics/app_package_name_logging_rule.h" #include "base/memory/scoped_refptr.h" #include "base/test/test_simple_task_runner.h" #include "base/time/time.h" @@ -73,52 +71,6 @@ EXPECT_TRUE(system_profile.chrome_component().empty()); } -TEST_F(AwComponentMetricsProviderDelegateTest, - TestAppsPackageNamesComponent_Loaded) { - metrics::ComponentMetricsProvider provider( - std::make_unique<AwComponentMetricsProviderDelegate>(GetClient())); - - std::string allowlist_version = "123.456.78.9"; - GetClient()->SetAppPackageNameLoggingRule(AppPackageNameLoggingRule( - base::Version(allowlist_version), base::Time::Now())); - - metrics::SystemProfileProto system_profile; - provider.ProvideSystemProfileMetrics(&system_profile); - ASSERT_EQ(1, system_profile.chrome_component().size()); - metrics::SystemProfileProto::ChromeComponent allowlist_component = - system_profile.chrome_component()[0]; - EXPECT_EQ( - metrics:: - SystemProfileProto_ComponentId_WEBVIEW_APPS_PACKAGE_NAMES_ALLOWLIST, - allowlist_component.component_id()); - EXPECT_EQ(allowlist_version, allowlist_component.version()); -} - -TEST_F(AwComponentMetricsProviderDelegateTest, - TestAppsPackageNamesComponent_CachedIsDifferentFromLoaded) { - metrics::ComponentMetricsProvider provider( - std::make_unique<AwComponentMetricsProviderDelegate>(GetClient())); - - std::string allowlist_version = "123.456.78.9"; - GetClient()->SetAppPackageNameLoggingRule(AppPackageNameLoggingRule( - base::Version(allowlist_version), base::Time::Now())); - - component_updater::ComponentsInfoHolder::GetInstance()->AddComponent( - kWebViewAppsPackageNamesAllowlistComponentId, - base::Version("222.333.444.555")); - - metrics::SystemProfileProto system_profile; - provider.ProvideSystemProfileMetrics(&system_profile); - ASSERT_EQ(1, system_profile.chrome_component().size()); - metrics::SystemProfileProto::ChromeComponent allowlist_component = - system_profile.chrome_component()[0]; - EXPECT_EQ( - metrics:: - SystemProfileProto_ComponentId_WEBVIEW_APPS_PACKAGE_NAMES_ALLOWLIST, - allowlist_component.component_id()); - EXPECT_EQ(allowlist_version, allowlist_component.version()); -} - TEST_F(AwComponentMetricsProviderDelegateTest, TestMultipleComponents) { AwComponentMetricsProviderDelegate delegate(GetClient()); @@ -126,9 +78,6 @@ base::Version fake_component_version("123.456.78.9"); component_updater::ComponentsInfoHolder::GetInstance()->AddComponent( fake_component_id, fake_component_version); - component_updater::ComponentsInfoHolder::GetInstance()->AddComponent( - kWebViewAppsPackageNamesAllowlistComponentId, - base::Version("222.333.444.555")); std::vector<ComponentInfo> components = delegate.GetComponents(); ASSERT_EQ(1u, components.size());
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.cc b/android_webview/browser/metrics/aw_metrics_service_client.cc index 8eab70e..1557405 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client.cc +++ b/android_webview/browser/metrics/aw_metrics_service_client.cc
@@ -10,7 +10,6 @@ #include "android_webview/browser/metrics/android_metrics_provider.h" #include "android_webview/browser_jni_headers/AwMetricsServiceClient_jni.h" #include "android_webview/common/aw_features.h" -#include "android_webview/common/metrics/app_package_name_logging_rule.h" #include "base/android/callback_android.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" @@ -65,11 +64,6 @@ AwMetricsServiceClient* g_aw_metrics_service_client = nullptr; -bool IsAppPackageNameServerSideAllowlistEnabled() { - return base::FeatureList::IsEnabled( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); -} - int GetBaseSampleRatePerMille() { // Down-sample unknown channel as a precaution in case it ends up being // shipped to Stable users. @@ -133,106 +127,19 @@ std::string AwMetricsServiceClient::GetAppPackageNameIfLoggable() { AndroidMetricsServiceClient::InstallerPackageType installer_type = GetInstallerPackageType(); - // Always record the app package name of system apps even if it's not in the - // allowlist. + // Always record the app package name of system apps and apps + // from the play store if (installer_type == InstallerPackageType::SYSTEM_APP || - (installer_type == InstallerPackageType::GOOGLE_PLAY_STORE && - ShouldRecordPackageName())) { + installer_type == InstallerPackageType::GOOGLE_PLAY_STORE) { return GetAppPackageName(); } return std::string(); } bool AwMetricsServiceClient::ShouldRecordPackageName() { - // Record app package name when app consent, user consent, - // and server-side allowlist is used - if (IsAppPackageNameServerSideAllowlistEnabled()) { - return true; - } - base::UmaHistogramEnumeration( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - package_name_record_status_); - - if (!cached_package_name_record_.has_value() || - !cached_package_name_record_.value().IsAppPackageNameAllowed()) { - return false; - } - // Recording as a count not times histogram because time histograms offers - // reacording (milliseconds and microseconds) which is too granular. Expiry - // time can range from 0 up to 6 weeks (1008 hours). Although values over 1000 - // will go to the max bucket, it should be fine for this, as we care only - // about small buckets when the allowlist is about to expire. - base::UmaHistogramCounts1000( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", - (cached_package_name_record_.value().GetExpiryDate() - base::Time::Now()) - .InHours()); return true; } -void AwMetricsServiceClient::SetAppPackageNameLoggingRule( - absl::optional<AppPackageNameLoggingRule> record) { - absl::optional<AppPackageNameLoggingRule> cached_record = - GetCachedAppPackageNameLoggingRule(); - if (!record.has_value()) { - package_name_record_status_ = - cached_record.has_value() - ? AppPackageNameLoggingRuleStatus::kNewVersionFailedUseCache - : AppPackageNameLoggingRuleStatus::kNewVersionFailedNoCache; - return; - } - - if (cached_record.has_value() && - record.value().IsSameAs(cached_package_name_record_.value())) { - package_name_record_status_ = - AppPackageNameLoggingRuleStatus::kSameVersionAsCache; - return; - } - - PrefService* local_state = pref_service(); - DCHECK(local_state); - local_state->SetDict(prefs::kMetricsAppPackageNameLoggingRule, - record.value().ToDictionary()); - cached_package_name_record_ = record; - package_name_record_status_ = - AppPackageNameLoggingRuleStatus::kNewVersionLoaded; - - UmaHistogramTimes( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", - base::Time::Now() - time_created_); -} - -absl::optional<AppPackageNameLoggingRule> -AwMetricsServiceClient::GetCachedAppPackageNameLoggingRule() { - if (cached_package_name_record_.has_value()) { - return cached_package_name_record_; - } - - PrefService* local_state = pref_service(); - DCHECK(local_state); - cached_package_name_record_ = AppPackageNameLoggingRule::FromDictionary( - local_state->GetDict(prefs::kMetricsAppPackageNameLoggingRule)); - if (cached_package_name_record_.has_value()) { - package_name_record_status_ = - AppPackageNameLoggingRuleStatus::kNotLoadedUseCache; - } - return cached_package_name_record_; -} - -base::Time AwMetricsServiceClient::GetAppPackageNameLoggingRuleLastUpdateTime() - const { - PrefService* local_state = pref_service(); - DCHECK(local_state); - return local_state->GetTime(prefs::kAppPackageNameLoggingRuleLastUpdateTime); -} - -void AwMetricsServiceClient::SetAppPackageNameLoggingRuleLastUpdateTime( - base::Time update_time) { - PrefService* local_state = pref_service(); - DCHECK(local_state); - local_state->SetTime(prefs::kAppPackageNameLoggingRuleLastUpdateTime, - update_time); -} - // Used below in AwMetricsServiceClient::OnMetricsStart. void RecordAppDataDirectorySize() { TRACE_EVENT_BEGIN0("android_webview", "RecordAppDataDirectorySize"); @@ -349,15 +256,4 @@ base::android::ScopedJavaGlobalRef<jobject>(listener))); } -// static -void JNI_AwMetricsServiceClient_SetAppPackageNameLoggingRuleForTesting( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& version, - jlong expiry_date_ms) { - AwMetricsServiceClient::GetInstance()->SetAppPackageNameLoggingRule( - AppPackageNameLoggingRule( - base::Version(base::android::ConvertJavaStringToUTF8(env, version)), - base::Time::UnixEpoch() + base::Milliseconds(expiry_date_ms))); -} - } // namespace android_webview
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.h b/android_webview/browser/metrics/aw_metrics_service_client.h index 9d95ceb..2b823118 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client.h +++ b/android_webview/browser/metrics/aw_metrics_service_client.h
@@ -9,7 +9,6 @@ #include <string> #include "android_webview/browser/lifecycle/webview_app_state_observer.h" -#include "android_webview/common/metrics/app_package_name_logging_rule.h" #include "base/metrics/field_trial.h" #include "base/no_destructor.h" #include "base/sequence_checker.h" @@ -23,11 +22,6 @@ namespace android_webview { -namespace prefs { -extern const char kMetricsAppPackageNameLoggingRule[]; -extern const char kAppPackageNameLoggingRuleLastUpdateTime[]; -} // namespace prefs - // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. // TODO(https://crbug.com/1012025): remove this when the kInstallDate pref has @@ -99,16 +93,6 @@ // the client ID (generating a new ID if there was none). If this client is in // the sample, it then calls MetricsService::Start(). If consent was not // granted, MaybeStartMetrics() instead clears the client ID, if any. -// -// Similarly, when -// `android_webview::features::kWebViewAppsPackageNamesAllowlist` is enabled, -// WebView will try to lookup the embedding app's package name in a list of apps -// whose package names are allowed to be recorded. This operation takes place on -// a background thread. The result of the lookup is then posted back on the UI -// thread and SetAppPackageNameLoggingRule() will be called. Unlike user's -// consent, the metrics service doesn't currently block on the allowlist lookup -// result. If the result isn't present at the moment of creating a metrics log, -// it assumes that the app package name isn't allowed to be logged. class AwMetricsServiceClient : public ::metrics::AndroidMetricsServiceClient, public WebViewAppStateObserver { @@ -135,19 +119,6 @@ virtual bool HasAwContentsEverCreated() const = 0; }; - // An enum to track the status of AppPackageNameLoggingRule used in - // ShouldRecordPackageName. These values are persisted to logs. Entries should - // not be renumbered and numeric values should never be reused. - enum class AppPackageNameLoggingRuleStatus { - kNotLoadedNoCache = 0, - kNotLoadedUseCache = 1, - kNewVersionFailedNoCache = 2, - kNewVersionFailedUseCache = 3, - kNewVersionLoaded = 4, - kSameVersionAsCache = 5, - kMaxValue = kSameVersionAsCache, - }; - static AwMetricsServiceClient* GetInstance(); static void SetInstance( std::unique_ptr<AwMetricsServiceClient> aw_metrics_service_client); @@ -179,36 +150,9 @@ // returns the empty string. std::string GetAppPackageNameIfLoggable() override; - // If `android_webview::features::kWebViewAppsPackageNamesAllowlist` is - // enabled: - // - It returns `true` if the app is in the list of allowed apps. - // - It returns `false` if the app isn't in the allowlist or if the lookup - // operation fails or hasn't finished yet. - // - // If the feature isn't enabled, the default sampling behaviour in - // `::metrics::AndroidMetricsServiceClient::ShouldRecordPackageName` is used. + // Always returns `true`, indicating to record the package name bool ShouldRecordPackageName() override; - // Sets that the embedding app's package name is allowed to be recorded in - // UMA logs. This is determened by looking up the app package name in a - // dynamically downloaded allowlist of apps see - // `AwAppsPackageNamesAllowlistComponentLoaderPolicy`. - // - // `record` If it has a null value, then it will be ignored and the cached - // record will be used if any. - void SetAppPackageNameLoggingRule( - absl::optional<AppPackageNameLoggingRule> record); - - // Get the cached record of the app package names allowlist set by - // `SetAppPackageNameLoggingRule` if any. - absl::optional<AppPackageNameLoggingRule> - GetCachedAppPackageNameLoggingRule(); - - // The last time the apps package name allowlist was queried from the - // component update service, regardless if it was successful or not. - base::Time GetAppPackageNameLoggingRuleLastUpdateTime() const; - void SetAppPackageNameLoggingRuleLastUpdateTime(base::Time update_time); - // If `android_webview::features::kWebViewMetricsFiltering` is // enabled: // - return `true` if client used to be sampled out. @@ -226,10 +170,6 @@ bool app_in_foreground_ = false; base::Time time_created_; std::unique_ptr<Delegate> delegate_; - - absl::optional<AppPackageNameLoggingRule> cached_package_name_record_; - AppPackageNameLoggingRuleStatus package_name_record_status_ = - AppPackageNameLoggingRuleStatus::kNotLoadedNoCache; }; } // namespace android_webview
diff --git a/android_webview/browser/metrics/aw_metrics_service_client_sample_rate_unittest.cc b/android_webview/browser/metrics/aw_metrics_service_client_sample_rate_unittest.cc index 71dd97b..91bc9c50 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client_sample_rate_unittest.cc +++ b/android_webview/browser/metrics/aw_metrics_service_client_sample_rate_unittest.cc
@@ -19,9 +19,6 @@ namespace android_webview { -using AppPackageNameLoggingRuleStatus = - AwMetricsServiceClient::AppPackageNameLoggingRuleStatus; - using InstallerPackageType = metrics::AndroidMetricsServiceClient::InstallerPackageType;
diff --git a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc index 97cbe8d..f84534d1 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc +++ b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
@@ -7,7 +7,6 @@ #include <memory> #include "android_webview/common/aw_features.h" -#include "android_webview/common/metrics/app_package_name_logging_rule.h" #include "base/metrics/histogram.h" #include "base/metrics/user_metrics.h" #include "base/test/metrics/histogram_tester.h" @@ -26,16 +25,11 @@ namespace android_webview { -using AppPackageNameLoggingRuleStatus = - AwMetricsServiceClient::AppPackageNameLoggingRuleStatus; - using InstallerPackageType = metrics::AndroidMetricsServiceClient::InstallerPackageType; namespace { -constexpr char kTestAllowlistVersion[] = "123.456.789.10"; - class AwMetricsServiceClientTestDelegate : public AwMetricsServiceClient::Delegate { void RegisterAdditionalMetricsProviders( @@ -105,279 +99,11 @@ } // namespace -TEST_F(AwMetricsServiceClientTest, TestShouldRecordPackageName_CacheNotSet) { - base::HistogramTester histogram_tester; - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - - AwMetricsServiceClient* client = GetClient(); - EXPECT_FALSE(client->ShouldRecordPackageName()); - EXPECT_FALSE(client->GetCachedAppPackageNameLoggingRule().has_value()); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", 0); - histogram_tester.ExpectBucketCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - AppPackageNameLoggingRuleStatus::kNotLoadedNoCache, 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", 0); -} - -TEST_F(AwMetricsServiceClientTest, TestShouldRecordPackageName_WithCache) { - base::HistogramTester histogram_tester; - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - - AwMetricsServiceClient* client = GetClient(); - TestingPrefServiceSimple* prefs = GetPrefs(); - - base::TimeDelta expiry_time = base::Days(1); - AppPackageNameLoggingRule expected_record( - base::Version(kTestAllowlistVersion), base::Time::Now() + expiry_time); - prefs->SetDict(prefs::kMetricsAppPackageNameLoggingRule, - expected_record.ToDictionary()); - - absl::optional<AppPackageNameLoggingRule> cached_record = - client->GetCachedAppPackageNameLoggingRule(); - EXPECT_TRUE(client->ShouldRecordPackageName()); - ASSERT_TRUE(cached_record.has_value()); - EXPECT_TRUE(expected_record.IsSameAs(cached_record.value())); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", 0); - histogram_tester.ExpectBucketCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - AppPackageNameLoggingRuleStatus::kNotLoadedUseCache, 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", 1); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", 1); - histogram_tester.ExpectUniqueSample( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", - expiry_time.InHours(), 1); -} - -TEST_F(AwMetricsServiceClientTest, - TestShouldRecordPackageName_TestShouldNotRecordPackageName) { - base::HistogramTester histogram_tester; - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - - AwMetricsServiceClient* client = GetClient(); - AppPackageNameLoggingRule expected_record( - base::Version(kTestAllowlistVersion), base::Time::Min()); - client->SetAppPackageNameLoggingRule(expected_record); - absl::optional<AppPackageNameLoggingRule> cached_record = - client->GetCachedAppPackageNameLoggingRule(); - - EXPECT_FALSE(client->ShouldRecordPackageName()); - ASSERT_TRUE(cached_record.has_value()); - EXPECT_TRUE(expected_record.IsSameAs(cached_record.value())); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", 1); - histogram_tester.ExpectBucketCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - AppPackageNameLoggingRuleStatus::kNewVersionLoaded, 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", 0); -} - -TEST_F(AwMetricsServiceClientTest, - TestShouldRecordPackageName_TestShouldRecordPackageName) { - base::HistogramTester histogram_tester; - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - - AwMetricsServiceClient* client = GetClient(); - - base::TimeDelta expiry_time = base::Days(1); - AppPackageNameLoggingRule expected_record( - base::Version(kTestAllowlistVersion), base::Time::Now() + expiry_time); - client->SetAppPackageNameLoggingRule(expected_record); - absl::optional<AppPackageNameLoggingRule> cached_record = - client->GetCachedAppPackageNameLoggingRule(); - - EXPECT_TRUE(client->ShouldRecordPackageName()); - ASSERT_TRUE(cached_record.has_value()); - EXPECT_TRUE(expected_record.IsSameAs(cached_record.value())); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", 1); - histogram_tester.ExpectBucketCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - AppPackageNameLoggingRuleStatus::kNewVersionLoaded, 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", 1); - histogram_tester.ExpectUniqueSample( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", - expiry_time.InHours(), 1); -} - TEST_F( AwMetricsServiceClientTest, TestServerSideAllowlist_TestShouldRecordPackageNameWithServerSideAllowlistEnabled) { AwMetricsServiceClient* client = GetClient(); EXPECT_TRUE(client->ShouldRecordPackageName()); - EXPECT_FALSE(client->GetCachedAppPackageNameLoggingRule().has_value()); -} - -TEST_F(AwMetricsServiceClientTest, - TestShouldRecordPackageName_TestFailureAfterValidResult) { - base::HistogramTester histogram_tester; - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - - AwMetricsServiceClient* client = GetClient(); - - base::TimeDelta expiry_time = base::Days(1); - AppPackageNameLoggingRule expected_record( - base::Version(kTestAllowlistVersion), base::Time::Now() + expiry_time); - client->SetAppPackageNameLoggingRule(expected_record); - client->SetAppPackageNameLoggingRule( - absl::optional<AppPackageNameLoggingRule>()); - absl::optional<AppPackageNameLoggingRule> cached_record = - client->GetCachedAppPackageNameLoggingRule(); - - EXPECT_TRUE(client->ShouldRecordPackageName()); - ASSERT_TRUE(cached_record.has_value()); - EXPECT_TRUE(expected_record.IsSameAs(cached_record.value())); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", 1); - histogram_tester.ExpectBucketCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - AppPackageNameLoggingRuleStatus::kNewVersionFailedUseCache, 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", 1); - histogram_tester.ExpectUniqueSample( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", - expiry_time.InHours(), 1); -} - -TEST_F(AwMetricsServiceClientTest, TestShouldRecordPackageName_FailedResult) { - base::HistogramTester histogram_tester; - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - - AwMetricsServiceClient* client = GetClient(); - client->SetAppPackageNameLoggingRule( - absl::optional<AppPackageNameLoggingRule>()); - - EXPECT_FALSE(client->ShouldRecordPackageName()); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", 0); - histogram_tester.ExpectBucketCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - AppPackageNameLoggingRuleStatus::kNewVersionFailedNoCache, 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", 0); -} - -TEST_F(AwMetricsServiceClientTest, TestShouldRecordPackageName_SameAsCache) { - base::HistogramTester histogram_tester; - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - - AwMetricsServiceClient* client = GetClient(); - TestingPrefServiceSimple* prefs = GetPrefs(); - - base::TimeDelta expiry_time = base::Days(1); - AppPackageNameLoggingRule record(base::Version(kTestAllowlistVersion), - base::Time::Now() + expiry_time); - prefs->SetDict(prefs::kMetricsAppPackageNameLoggingRule, - record.ToDictionary()); - client->SetAppPackageNameLoggingRule(record); - - EXPECT_TRUE(client->ShouldRecordPackageName()); - - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.ResultReceivingDelay", 0); - histogram_tester.ExpectBucketCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", - AppPackageNameLoggingRuleStatus::kSameVersionAsCache, 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.RecordStatus", 1); - histogram_tester.ExpectTotalCount( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", 1); - histogram_tester.ExpectUniqueSample( - "Android.WebView.Metrics.PackagesAllowList.TimeToExpire", - expiry_time.InHours(), 1); -} - -TEST_F(AwMetricsServiceClientTest, TestGetAppPackageNameIfLoggable) { - class TestClient : public AwMetricsServiceClient { - public: - TestClient() - : AwMetricsServiceClient( - std::make_unique<AwMetricsServiceClientTestDelegate>()) {} - ~TestClient() override = default; - - bool ShouldRecordPackageName() override { - return should_record_package_name_; - } - - void SetShouldRecordPackageName(bool value) { - should_record_package_name_ = value; - } - - InstallerPackageType GetInstallerPackageType() override { - return installer_type_; - } - - void SetInstallerPackageType(InstallerPackageType installer_type) { - installer_type_ = installer_type; - } - - private: - bool should_record_package_name_; - InstallerPackageType installer_type_; - }; - - TestClient client; - - // Package names of system apps are always loggable even if they are not in - // the allowlist of apps. - client.SetInstallerPackageType(InstallerPackageType::SYSTEM_APP); - client.SetShouldRecordPackageName(false); - EXPECT_FALSE(client.GetAppPackageNameIfLoggable().empty()); - client.SetShouldRecordPackageName(true); - EXPECT_FALSE(client.GetAppPackageNameIfLoggable().empty()); - - // Package names of APPs that are installed by the Play Store are loggable if - // they are in the allowlist of apps. - client.SetInstallerPackageType(InstallerPackageType::GOOGLE_PLAY_STORE); - client.SetShouldRecordPackageName(false); - EXPECT_TRUE(client.GetAppPackageNameIfLoggable().empty()); - client.SetShouldRecordPackageName(true); - EXPECT_FALSE(client.GetAppPackageNameIfLoggable().empty()); - - // Package names of APPs that are not system apps nor installed by the Play - // Store are not loggable. - client.SetInstallerPackageType(InstallerPackageType::OTHER); - client.SetShouldRecordPackageName(false); - EXPECT_TRUE(client.GetAppPackageNameIfLoggable().empty()); - client.SetShouldRecordPackageName(true); - EXPECT_TRUE(client.GetAppPackageNameIfLoggable().empty()); } TEST_F(
diff --git a/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider.cc b/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider.cc index 6d2d2e6..1496c5cf 100644 --- a/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider.cc +++ b/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider.cc
@@ -9,13 +9,6 @@ #include "components/embedder_support/android/metrics/android_metrics_service_client.h" #include "third_party/metrics_proto/system_profile.pb.h" -namespace { -bool IsServerSideAllowlistEnabled() { - return base::FeatureList::IsEnabled( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); -} -} // namespace - namespace android_webview { AwServerSideAllowlistMetricsProvider::AwServerSideAllowlistMetricsProvider() : client_(nullptr) {} @@ -26,12 +19,6 @@ void AwServerSideAllowlistMetricsProvider::ProvideSystemProfileMetrics( metrics::SystemProfileProto* system_profile) { - if (!IsServerSideAllowlistEnabled()) { - system_profile->set_app_package_name_allowlist_filter( - metrics::SystemProfileProto:: - NO_SERVER_SIDE_FILTER_REQUIRED_DUE_TO_CLIENT_FILTERING); - return; - } if (IsAppPackageNameSystemApp()) { system_profile->set_app_package_name_allowlist_filter(
diff --git a/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider_unittests.cc b/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider_unittests.cc index ec22e1f..56616fdc4 100644 --- a/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider_unittests.cc +++ b/android_webview/browser/metrics/aw_server_side_allowlist_metrics_provider_unittests.cc
@@ -68,26 +68,6 @@ metrics::SystemProfileProto::SERVER_SIDE_FILTER_REQUIRED); } -TEST_F( - AwServerSideAllowlistMetricsProviderTest, - TestServerSideAllowlist_TestNoServerSideFilteringDueToClientSideFiltering) { - base::test::ScopedFeatureList scoped_list; - TestClient client; - AwServerSideAllowlistMetricsProvider test_provider(&client); - metrics::ChromeUserMetricsExtension uma_proto; - - client.SetInstallerPackageType(InstallerPackageType::GOOGLE_PLAY_STORE); - scoped_list.InitAndDisableFeature( - android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist); - test_provider.ProvideSystemProfileMetrics(uma_proto.mutable_system_profile()); - EXPECT_TRUE(uma_proto.mutable_system_profile() - ->has_app_package_name_allowlist_filter()); - EXPECT_TRUE( - uma_proto.mutable_system_profile()->app_package_name_allowlist_filter() == - metrics::SystemProfileProto:: - NO_SERVER_SIDE_FILTER_REQUIRED_DUE_TO_CLIENT_FILTERING); -} - TEST_F(AwServerSideAllowlistMetricsProviderTest, TestServerSideAllowlist_TestNoServerSideFilteringForSystemApp) { TestClient client;
diff --git a/android_webview/common/BUILD.gn b/android_webview/common/BUILD.gn index 2fa05e1..46d1866 100644 --- a/android_webview/common/BUILD.gn +++ b/android_webview/common/BUILD.gn
@@ -22,15 +22,11 @@ "aw_resource_bundle.h", "aw_switches.cc", "aw_switches.h", - "components/aw_apps_package_names_allowlist_component_utils.cc", - "components/aw_apps_package_names_allowlist_component_utils.h", "crash_reporter/aw_crash_reporter_client.cc", "crash_reporter/aw_crash_reporter_client.h", "crash_reporter/crash_keys.cc", "crash_reporter/crash_keys.h", "devtools_instrumentation.h", - "metrics/app_package_name_logging_rule.cc", - "metrics/app_package_name_logging_rule.h", "url_constants.cc", "url_constants.h", ] @@ -78,14 +74,3 @@ "//url/mojom:url_mojom_gurl", ] } - -source_set("tests") { - testonly = true - - sources = [ "metrics/app_package_name_logging_rule_unittests.cc" ] - deps = [ - ":common", - "//base", - "//base/test:test_support", - ] -}
diff --git a/android_webview/common/aw_features.cc b/android_webview/common/aw_features.cc index 41b47bb..bdca8f5 100644 --- a/android_webview/common/aw_features.cc +++ b/android_webview/common/aw_features.cc
@@ -11,14 +11,6 @@ // Alphabetical: -// Enables package name logging for the most popular WebView embedders that are -// on a dynamically generated allowlist. -// The filtering for package names will be done on the server side using this -// flag -BASE_FEATURE(kWebViewAppsPackageNamesServerSideAllowlist, - "WebViewAppsPackageNamesServerSideAllowlist", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enable brotli compression support in WebView. BASE_FEATURE(kWebViewBrotliSupport, "WebViewBrotliSupport",
diff --git a/android_webview/common/aw_features.h b/android_webview/common/aw_features.h index 10b6370..c827f853 100644 --- a/android_webview/common/aw_features.h +++ b/android_webview/common/aw_features.h
@@ -16,7 +16,6 @@ // alongside the definition of their values in the .cc file. // Alphabetical: -BASE_DECLARE_FEATURE(kWebViewAppsPackageNamesServerSideAllowlist); BASE_DECLARE_FEATURE(kWebViewBrotliSupport); BASE_DECLARE_FEATURE(kWebViewCheckReturnResources); BASE_DECLARE_FEATURE(kWebViewConnectionlessSafeBrowsing);
diff --git a/android_webview/common/aw_switches.cc b/android_webview/common/aw_switches.cc index 62317fad..81ef88c 100644 --- a/android_webview/common/aw_switches.cc +++ b/android_webview/common/aw_switches.cc
@@ -60,11 +60,6 @@ const char kWebViewEnableModernCookieSameSite[] = "webview-enable-modern-cookie-same-site"; -// Disables throttling querying apps package names allowlist components in -// WebView clients. -const char kWebViewDisablePackageAllowlistThrottling[] = - "webview-disable-package-allowlist-throttling"; - // Enables use selective image inversion to automatically darken page, it will // be used when WebView is in dark mode, but website doesn't provide dark style. const char kWebViewSelectiveImageInversionDarkening[] =
diff --git a/android_webview/common/aw_switches.h b/android_webview/common/aw_switches.h index b0ac9a9a..3e60d2ce 100644 --- a/android_webview/common/aw_switches.h +++ b/android_webview/common/aw_switches.h
@@ -19,7 +19,6 @@ extern const char kFinchSeedMinDownloadPeriod[]; extern const char kFinchSeedMinUpdatePeriod[]; extern const char kWebViewEnableModernCookieSameSite[]; -extern const char kWebViewDisablePackageAllowlistThrottling[]; extern const char kWebViewSelectiveImageInversionDarkening[]; extern const char kWebViewFencedFrames[]; extern const char kWebViewDisableAppRecovery[];
diff --git a/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.cc b/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.cc deleted file mode 100644 index aca7e44e..0000000 --- a/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.cc +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h" - -#include "base/check.h" - -namespace android_webview { - -constexpr char kWebViewAppsPackageNamesAllowlistComponentId[] = - "aemllinfpjdgcldgaelcgakpjmaekbai"; - -namespace { -// The SHA256 of the SubjectPublicKeyInfo used to sign the extension. -// The extension id is: aemllinfpjdgcldgaelcgakpjmaekbai -const uint8_t kWebViewAppsPackageNamesAllowlistPublicKeySHA256[32] = { - 0x04, 0xcb, 0xb8, 0xd5, 0xf9, 0x36, 0x2b, 0x36, 0x04, 0xb2, 0x60, - 0xaf, 0x9c, 0x04, 0xa1, 0x08, 0xa3, 0xe9, 0xdc, 0x92, 0x46, 0xe7, - 0xae, 0xc8, 0x3e, 0x32, 0x6f, 0x74, 0x43, 0x02, 0xf3, 0x7e}; - -} // namespace - -void GetWebViewAppsPackageNamesAllowlistPublicKeyHash( - std::vector<uint8_t>* hash) { - DCHECK(hash); - hash->assign(kWebViewAppsPackageNamesAllowlistPublicKeySHA256, - kWebViewAppsPackageNamesAllowlistPublicKeySHA256 + - std::size(kWebViewAppsPackageNamesAllowlistPublicKeySHA256)); -} - -} // namespace android_webview
diff --git a/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h b/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h deleted file mode 100644 index 15358de2..0000000 --- a/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_COMMON_COMPONENTS_AW_APPS_PACKAGE_NAMES_ALLOWLIST_COMPONENT_UTILS_H_ -#define ANDROID_WEBVIEW_COMMON_COMPONENTS_AW_APPS_PACKAGE_NAMES_ALLOWLIST_COMPONENT_UTILS_H_ - -#include <stdint.h> - -#include <vector> - -namespace android_webview { - -extern const char kWebViewAppsPackageNamesAllowlistComponentId[]; - -void GetWebViewAppsPackageNamesAllowlistPublicKeyHash( - std::vector<uint8_t>* hash); - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_COMMON_COMPONENTS_AW_APPS_PACKAGE_NAMES_ALLOWLIST_COMPONENT_UTILS_H_
diff --git a/android_webview/common/metrics/app_package_name_logging_rule.cc b/android_webview/common/metrics/app_package_name_logging_rule.cc deleted file mode 100644 index c4f2c1b1..0000000 --- a/android_webview/common/metrics/app_package_name_logging_rule.cc +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/common/metrics/app_package_name_logging_rule.h" - -#include "base/json/values_util.h" -#include "base/time/time.h" -#include "base/values.h" -#include "base/version.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace android_webview { - -namespace { -constexpr char kExpiryDateKey[] = "expiry-date"; -constexpr char kVersionKey[] = "allowlist-version"; -} // namespace - -AppPackageNameLoggingRule::AppPackageNameLoggingRule( - const base::Version& version, - const base::Time& expiry_date) - : version_(version), expiry_date_(expiry_date) { - DCHECK(version.IsValid()); - DCHECK(!expiry_date.is_null()); -} - -base::Version AppPackageNameLoggingRule::GetVersion() const { - return version_; -} - -base::Time AppPackageNameLoggingRule::GetExpiryDate() const { - return expiry_date_; -} - -bool AppPackageNameLoggingRule::IsAppPackageNameAllowed() const { - return expiry_date_ >= base::Time::Now(); -} - -bool AppPackageNameLoggingRule::IsSameAs( - const AppPackageNameLoggingRule& record) const { - if (record.GetVersion() == GetVersion()) { - DCHECK(record.GetExpiryDate() == GetExpiryDate()); - return true; - } - return false; -} - -// static -absl::optional<AppPackageNameLoggingRule> -AppPackageNameLoggingRule::FromDictionary(const base::Value::Dict& dict) { - const std::string* version_string = dict.FindString(kVersionKey); - if (!version_string) { - return absl::optional<AppPackageNameLoggingRule>(); - } - base::Version version(*version_string); - if (!version.IsValid()) { - return absl::optional<AppPackageNameLoggingRule>(); - } - - const base::Value* expiry_date_value = dict.Find(kExpiryDateKey); - if (!expiry_date_value) { - return AppPackageNameLoggingRule(version, base::Time::Min()); - } - absl::optional<base::Time> expiry_date = - base::ValueToTime(*expiry_date_value); - if (!expiry_date.has_value()) { - return AppPackageNameLoggingRule(version, base::Time::Min()); - } - - return AppPackageNameLoggingRule(version, expiry_date.value()); -} - -base::Value::Dict AppPackageNameLoggingRule::ToDictionary() { - base::Value::Dict dict; - - dict.Set(kVersionKey, version_.GetString()); - if (!expiry_date_.is_min()) { - dict.Set(kExpiryDateKey, base::TimeToValue(expiry_date_)); - } - return dict; -} - -} // namespace android_webview
diff --git a/android_webview/common/metrics/app_package_name_logging_rule.h b/android_webview/common/metrics/app_package_name_logging_rule.h deleted file mode 100644 index 900e7fe..0000000 --- a/android_webview/common/metrics/app_package_name_logging_rule.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_COMMON_METRICS_APP_PACKAGE_NAME_LOGGING_RULE_H_ -#define ANDROID_WEBVIEW_COMMON_METRICS_APP_PACKAGE_NAME_LOGGING_RULE_H_ - -#include "base/time/time.h" -#include "base/values.h" -#include "base/version.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace android_webview { - -// A class to hold the state of whether an app package name should be recorded -// in UMA metrics log or not. This represent the result of looking the app -// package name in a list of allowed apps. -class AppPackageNameLoggingRule { - public: - AppPackageNameLoggingRule(const base::Version& version, - const base::Time& expiry_date); - ~AppPackageNameLoggingRule() = default; - - AppPackageNameLoggingRule(const AppPackageNameLoggingRule&) = default; - AppPackageNameLoggingRule& operator=(const AppPackageNameLoggingRule&) = - default; - AppPackageNameLoggingRule(AppPackageNameLoggingRule&&) = default; - AppPackageNameLoggingRule& operator=(AppPackageNameLoggingRule&&) = default; - - base::Version GetVersion() const; - base::Time GetExpiryDate() const; - - // Return `true` is the app is in the allowlist and the result hasn't expired, - // `false` otherwise. - bool IsAppPackageNameAllowed() const; - - // If it has the same version and expiry_date as `record`. - bool IsSameAs(const AppPackageNameLoggingRule& record) const; - - base::Value::Dict ToDictionary(); - - // Creates a valid AppPackageNameLoggingRule from a dictionary, or null if - // the dictionary have invalid values. - static absl::optional<AppPackageNameLoggingRule> FromDictionary( - const base::Value::Dict& dict); - - private: - base::Version version_; - base::Time expiry_date_; -}; - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_COMMON_METRICS_APP_PACKAGE_NAME_LOGGING_RULE_H_
diff --git a/android_webview/common/metrics/app_package_name_logging_rule_unittests.cc b/android_webview/common/metrics/app_package_name_logging_rule_unittests.cc deleted file mode 100644 index 7886dbf..0000000 --- a/android_webview/common/metrics/app_package_name_logging_rule_unittests.cc +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/common/metrics/app_package_name_logging_rule.h" - -#include "base/time/time.h" -#include "base/version.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace android_webview { - -namespace { - -constexpr char kTestAllowlistVersion[] = "123.456.789.10"; -} // namespace - -class AppPackageNameLoggingRuleTest : public testing::Test { - public: - AppPackageNameLoggingRuleTest() = default; - - AppPackageNameLoggingRuleTest& operator=( - const AppPackageNameLoggingRuleTest&) = delete; - AppPackageNameLoggingRuleTest(AppPackageNameLoggingRuleTest&&) = delete; - AppPackageNameLoggingRuleTest& operator=(AppPackageNameLoggingRuleTest&&) = - delete; -}; - -TEST_F(AppPackageNameLoggingRuleTest, TestFromDictionary) { - base::Version version(kTestAllowlistVersion); - base::Time one_day_from_now = base::Time::Now() + base::Days(1); - { - AppPackageNameLoggingRule expected_record(version, one_day_from_now); - absl::optional<AppPackageNameLoggingRule> record = - AppPackageNameLoggingRule::FromDictionary( - expected_record.ToDictionary()); - ASSERT_TRUE(record.has_value()); - EXPECT_TRUE(expected_record.IsSameAs(record.value())); - } - - { - AppPackageNameLoggingRule expected_record(version, base::Time::Min()); - absl::optional<AppPackageNameLoggingRule> record = - AppPackageNameLoggingRule::FromDictionary( - expected_record.ToDictionary()); - ASSERT_TRUE(record.has_value()); - EXPECT_TRUE(expected_record.IsSameAs(record.value())); - } - - { - absl::optional<AppPackageNameLoggingRule> record = - AppPackageNameLoggingRule::FromDictionary(base::Value::Dict()); - EXPECT_FALSE(record.has_value()); - } -} - -} // namespace android_webview
diff --git a/android_webview/docs/architecture.md b/android_webview/docs/architecture.md index 0e559db..801bf60 100644 --- a/android_webview/docs/architecture.md +++ b/android_webview/docs/architecture.md
@@ -4,8 +4,8 @@ Android WebView is a [content embedder](/content/README.md), meaning it depends on code in `//content/` and lower layers (ex. `//net/`, `//base/`), but does not -depend on sibling layers such as `//chrome/` or `//weblayer/`. Android WebView -can also depend on [components](/components/README.md). +depend on sibling layers such as `//chrome/`. Android WebView can also depend on +[components](/components/README.md). ## Java and C++
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 863802e..6cefe87a 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -150,9 +150,6 @@ Flag.baseFeature(AwFeatures.WEBVIEW_CONNECTIONLESS_SAFE_BROWSING, "Uses GooglePlayService's 'connectionless' APIs for Safe Browsing " + "security checks."), - Flag.baseFeature(AwFeatures.WEBVIEW_APPS_PACKAGE_NAMES_SERVER_SIDE_ALLOWLIST, - "Enables usage of server-side allowlist filtering of" - + " app package names."), Flag.baseFeature(AwFeatures.WEBVIEW_BROTLI_SUPPORT, "Enables brotli compression support in WebView."), Flag.baseFeature(NetFeatures.ZSTD_CONTENT_ENCODING, @@ -245,9 +242,6 @@ + "accessory."), Flag.baseFeature(NetworkServiceFeatures.PRIVATE_STATE_TOKENS, "Enables the prototype Private State Tokens API."), - Flag.commandLine(AwSwitches.WEBVIEW_DISABLE_PACKAGE_ALLOWLIST_THROTTLING, - "Disables throttling querying apps package names allowlist components in" - + "WebView clients."), Flag.baseFeature(AwFeatures.WEBVIEW_EMPTY_COMPONENT_LOADER_POLICY, "Enables loading a fake empty (no-op) component during WebView startup."), Flag.commandLine(AwSwitches.WEBVIEW_SELECTIVE_IMAGE_INVERSION_DARKENING,
diff --git a/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java b/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java index e8dddd16..ec704df 100644 --- a/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java +++ b/android_webview/java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java
@@ -42,18 +42,11 @@ AwMetricsServiceClientJni.get().setOnFinalMetricsCollectedListenerForTesting(listener); } - public static void setAppPackageNameLoggingRuleForTesting(String version, long expiryDateMs) { - ThreadUtils.assertOnUiThread(); - AwMetricsServiceClientJni.get().setAppPackageNameLoggingRuleForTesting( - version, expiryDateMs); - } - @NativeMethods interface Natives { void setHaveMetricsConsent(boolean userConsent, boolean appConsent); void setFastStartupForTesting(boolean fastStartupForTesting); void setUploadIntervalForTesting(long uploadIntervalMs); void setOnFinalMetricsCollectedListenerForTesting(Runnable listener); - void setAppPackageNameLoggingRuleForTesting(String version, long expiryDateMs); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java index ffc37fb86..c6c3be7a 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java
@@ -4,8 +4,6 @@ package org.chromium.android_webview.test; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -25,7 +23,6 @@ import org.chromium.android_webview.AwBrowserProcess; import org.chromium.android_webview.AwContents; -import org.chromium.android_webview.common.AwFeatures; import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.android_webview.metrics.AwMetricsServiceClient; import org.chromium.android_webview.metrics.MetricsFilteringDecorator; @@ -381,12 +378,6 @@ AwBrowserProcess.setWebViewPackageName(appPackageName); AndroidMetricsServiceClient.setInstallerPackageTypeForTesting( InstallerPackageType.GOOGLE_PLAY_STORE); - // A valid version string and non expired date means the app package name should be - // recorded. - AwMetricsServiceClient.setAppPackageNameLoggingRuleForTesting( - /* allowlistComponentVersion= */ "123.456.78.9", - /* allowlistExpiryDateMs= */ System.currentTimeMillis() - + TimeUnit.DAYS.toMillis(1)); }); // Disregard the first UMA log because it's recorded before loading the allowlist. @@ -436,41 +427,6 @@ @Test @MediumTest @Feature({"AndroidWebView"}) - public void testMetadata_chromeComponents() throws Throwable { - final String allowlistComponentVersion = "123.456.78.9"; - // A fake expiry date, the allowlist component info should be recorded regardless of the - // expiry date. - final long allowlistExpiryDateMs = 1234567891011L; - TestThreadUtils.runOnUiThreadBlocking(() -> { - AwMetricsServiceClient.setAppPackageNameLoggingRuleForTesting( - allowlistComponentVersion, allowlistExpiryDateMs); - }); - - // Ignore the first log because it will likely be recorded before setting the allowlist - // version above. - mPlatformServiceBridge.waitForNextMetricsLog(); - - // The start of a page load should be enough to indicate to the MetricsService that the app - // is "in use" and it's OK to upload the next record. - mRule.loadUrlAsync(mAwContents, "about:blank"); - ChromeUserMetricsExtension log = mPlatformServiceBridge.waitForNextMetricsLog(); - SystemProfileProto systemProfile = log.getSystemProfile(); - - assertEquals( - "Should have exactly one component", systemProfile.getChromeComponentCount(), 1); - ChromeComponent expectedAllowlistComponent = - ChromeComponent.newBuilder() - .setComponentId( - SystemProfileProto.ComponentId.WEBVIEW_APPS_PACKAGE_NAMES_ALLOWLIST) - .setVersion(allowlistComponentVersion) - .build(); - assertThat(systemProfile.getChromeComponentList(), - contains(matchesChromeComponent(expectedAllowlistComponent))); - } - - @Test - @MediumTest - @Feature({"AndroidWebView"}) public void testPageLoadsEnableMultipleUploads() throws Throwable { mPlatformServiceBridge.waitForNextMetricsLog(); @@ -575,19 +531,4 @@ assertEquals(filter, SystemProfileProto.AppPackageNameAllowlistFilter.SERVER_SIDE_FILTER_REQUIRED); } - - @Test - @MediumTest - @Feature({"AndroidWebView"}) - @CommandLineFlags. - Add("disable-features=" + AwFeatures.WEBVIEW_APPS_PACKAGE_NAMES_SERVER_SIDE_ALLOWLIST) - public void testServerSideAllowlistFilteringNotRequiredDueToClientSideFiltering() - throws Throwable { - ChromeUserMetricsExtension log = mPlatformServiceBridge.waitForNextMetricsLog(); - SystemProfileProto.AppPackageNameAllowlistFilter filter = - log.getSystemProfile().getAppPackageNameAllowlistFilter(); - assertEquals(filter, - SystemProfileProto.AppPackageNameAllowlistFilter - .NO_SERVER_SIDE_FILTER_REQUIRED_DUE_TO_CLIENT_FILTERING); - } }
diff --git a/android_webview/lib/BUILD.gn b/android_webview/lib/BUILD.gn index d0c52ee..b7c2d29 100644 --- a/android_webview/lib/BUILD.gn +++ b/android_webview/lib/BUILD.gn
@@ -4,7 +4,6 @@ import("//build/config/android/config.gni") import("//components/spellcheck/spellcheck_build_features.gni") -import("//weblayer/variables.gni") source_set("lib") { sources = [ @@ -64,10 +63,4 @@ "//base", ] sources = [ "webview_entry_point.cc" ] - defines = [] - - if (webview_includes_weblayer) { - defines += [ "WEBVIEW_INCLUDES_WEBLAYER" ] - deps += [ "//weblayer:weblayer_lib" ] - } }
diff --git a/android_webview/lib/webview_entry_point.cc b/android_webview/lib/webview_entry_point.cc index ce2a0dd1..a2ddf8b 100644 --- a/android_webview/lib/webview_entry_point.cc +++ b/android_webview/lib/webview_entry_point.cc
@@ -7,10 +7,6 @@ #include "base/android/jni_android.h" #include "base/android/library_loader/library_loader_hooks.h" -#if defined(WEBVIEW_INCLUDES_WEBLAYER) -#include "weblayer/app/jni_onload.h" -#endif - namespace { bool NativeInit(base::android::LibraryProcessType library_process_type) { @@ -27,12 +23,6 @@ case base::android::PROCESS_WEBVIEW_NONEMBEDDED: return base::android::OnJNIOnLoadInit(); -#if defined(WEBVIEW_INCLUDES_WEBLAYER) - case base::android::PROCESS_WEBLAYER: - case base::android::PROCESS_WEBLAYER_CHILD: - return weblayer::OnJNIOnLoadInit(); -#endif - default: NOTREACHED(); return false;
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index 09eed4b..abd35e0a 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -181,8 +181,6 @@ "component_updater/aw_component_update_service.h", "component_updater/aw_component_updater_configurator.cc", "component_updater/aw_component_updater_configurator.h", - "component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.cc", - "component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.h", "component_updater/registration.cc", "component_updater/registration.h", "net/network_fetcher_task.cc",
diff --git a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.cc b/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.cc deleted file mode 100644 index d3a01686..0000000 --- a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.cc +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.h" - -#include <cstdint> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h" -#include "android_webview/nonembedded/component_updater/aw_component_installer_policy.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_refptr.h" -#include "base/path_service.h" -#include "base/values.h" -#include "base/version.h" -#include "components/component_updater/component_installer.h" -#include "components/component_updater/component_updater_paths.h" - -namespace { - -const char kWebViewAppsPackageNamesAllowlistName[] = - "WebViewAppsPackageNamesAllowlist"; - -} // namespace - -namespace android_webview { - -AwPackageNamesAllowlistComponentInstallerPolicy:: - AwPackageNamesAllowlistComponentInstallerPolicy() = default; - -AwPackageNamesAllowlistComponentInstallerPolicy:: - ~AwPackageNamesAllowlistComponentInstallerPolicy() = default; - -update_client::CrxInstaller::Result -AwPackageNamesAllowlistComponentInstallerPolicy::OnCustomInstall( - const base::Value::Dict& manifest, - const base::FilePath& install_dir) { - // Nothing custom here. - return update_client::CrxInstaller::Result(/* error = */ 0); -} - -void RegisterWebViewAppsPackageNamesAllowlistComponent( - base::OnceCallback<bool(const component_updater::ComponentRegistration&)> - register_callback, - base::OnceClosure registration_finished) { - base::MakeRefCounted<component_updater::ComponentInstaller>( - std::make_unique<AwPackageNamesAllowlistComponentInstallerPolicy>()) - ->Register(std::move(register_callback), - std::move(registration_finished)); -} - -bool AwPackageNamesAllowlistComponentInstallerPolicy:: - SupportsGroupPolicyEnabledComponentUpdates() const { - return true; -} - -bool AwPackageNamesAllowlistComponentInstallerPolicy:: - RequiresNetworkEncryption() const { - return false; -} - -bool AwPackageNamesAllowlistComponentInstallerPolicy::VerifyInstallation( - const base::Value::Dict& manifest, - const base::FilePath& install_dir) const { - return true; -} - -base::FilePath -AwPackageNamesAllowlistComponentInstallerPolicy::GetRelativeInstallDir() const { - return base::FilePath(FILE_PATH_LITERAL("WebViewAppsPackageNamesAllowlist")); -} - -void AwPackageNamesAllowlistComponentInstallerPolicy::GetHash( - std::vector<uint8_t>* hash) const { - GetWebViewAppsPackageNamesAllowlistPublicKeyHash(hash); -} - -std::string AwPackageNamesAllowlistComponentInstallerPolicy::GetName() const { - return kWebViewAppsPackageNamesAllowlistName; -} - -update_client::InstallerAttributes -AwPackageNamesAllowlistComponentInstallerPolicy::GetInstallerAttributes() - const { - return update_client::InstallerAttributes(); -} - -} // namespace android_webview
diff --git a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.h b/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.h deleted file mode 100644 index 5896fe7..0000000 --- a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_NONEMBEDDED_COMPONENT_UPDATER_INSTALLER_POLICIES_AW_PACKAGE_NAMES_ALLOWLIST_COMPONENT_INSTALLER_POLICY_H_ -#define ANDROID_WEBVIEW_NONEMBEDDED_COMPONENT_UPDATER_INSTALLER_POLICIES_AW_PACKAGE_NAMES_ALLOWLIST_COMPONENT_INSTALLER_POLICY_H_ - -#include <cstdint> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "android_webview/nonembedded/component_updater/aw_component_installer_policy.h" -#include "base/functional/callback.h" -#include "base/values.h" - -namespace base { -class FilePath; -} // namespace base - -namespace android_webview { - -class AwPackageNamesAllowlistComponentInstallerPolicy - : public AwComponentInstallerPolicy { - public: - AwPackageNamesAllowlistComponentInstallerPolicy(); - ~AwPackageNamesAllowlistComponentInstallerPolicy() override; - AwPackageNamesAllowlistComponentInstallerPolicy( - const AwPackageNamesAllowlistComponentInstallerPolicy&) = delete; - AwPackageNamesAllowlistComponentInstallerPolicy& operator=( - const AwPackageNamesAllowlistComponentInstallerPolicy&) = delete; - - void GetHash(std::vector<uint8_t>* hash) const override; - - protected: - // The following methods override ComponentInstallerPolicy. - bool SupportsGroupPolicyEnabledComponentUpdates() const override; - bool RequiresNetworkEncryption() const override; - update_client::CrxInstaller::Result OnCustomInstall( - const base::Value::Dict& manifest, - const base::FilePath& install_dir) override; - bool VerifyInstallation(const base::Value::Dict& manifest, - const base::FilePath& install_dir) const override; - base::FilePath GetRelativeInstallDir() const override; - std::string GetName() const override; - update_client::InstallerAttributes GetInstallerAttributes() const override; -}; - -// Call once during startup to make the component update service aware of -// the package name logging component. -void RegisterWebViewAppsPackageNamesAllowlistComponent( - base::OnceCallback<bool(const component_updater::ComponentRegistration&)> - register_callback, - base::OnceClosure registration_finished); - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_NONEMBEDDED_COMPONENT_UPDATER_INSTALLER_POLICIES_AW_PACKAGE_NAMES_ALLOWLIST_COMPONENT_INSTALLER_POLICY_H_
diff --git a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc b/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc deleted file mode 100644 index fd7a146c..0000000 --- a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.h" - -#include <vector> - -#include "android_webview/common/aw_switches.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_refptr.h" -#include "base/test/task_environment.h" -#include "base/values.h" -#include "base/version.h" -#include "components/update_client/utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace android_webview { - -const uint8_t kWebViewAppsPackageNamesAllowlistPublicKeySHA256[32] = { - 0x04, 0xcb, 0xb8, 0xd5, 0xf9, 0x36, 0x2b, 0x36, 0x04, 0xb2, 0x60, - 0xaf, 0x9c, 0x04, 0xa1, 0x08, 0xa3, 0xe9, 0xdc, 0x92, 0x46, 0xe7, - 0xae, 0xc8, 0x3e, 0x32, 0x6f, 0x74, 0x43, 0x02, 0xf3, 0x7e}; - -class AwPackageNamesAllowlistComponentInstallerPolicyTest - : public ::testing::Test { - public: - AwPackageNamesAllowlistComponentInstallerPolicyTest() = default; - - protected: - base::test::TaskEnvironment env_; -}; - -// TODO(crbug.com/1202702): Add a test that calls -// RegisterWebViewAppsPackageNamesAllowlistComponent() and checks that -// registration_finished is called. - -TEST_F(AwPackageNamesAllowlistComponentInstallerPolicyTest, ComponentHash) { - auto policy = - std::make_unique<AwPackageNamesAllowlistComponentInstallerPolicy>(); - - std::vector<uint8_t> expected; - expected.assign( - kWebViewAppsPackageNamesAllowlistPublicKeySHA256, - kWebViewAppsPackageNamesAllowlistPublicKeySHA256 + - std::size(kWebViewAppsPackageNamesAllowlistPublicKeySHA256)); - - std::vector<uint8_t> actual; - policy->GetHash(&actual); - - EXPECT_EQ(expected, actual); - - std::string expected_id = "aemllinfpjdgcldgaelcgakpjmaekbai"; - std::string actual_id = update_client::GetCrxIdFromPublicKeyHash(actual); - - EXPECT_EQ(expected_id, actual_id); -} - -} // namespace android_webview
diff --git a/android_webview/nonembedded/component_updater/registration.cc b/android_webview/nonembedded/component_updater/registration.cc index 6f71e28..8e0108e 100644 --- a/android_webview/nonembedded/component_updater/registration.cc +++ b/android_webview/nonembedded/component_updater/registration.cc
@@ -8,7 +8,6 @@ #include "android_webview/common/aw_switches.h" #include "android_webview/nonembedded/component_updater/aw_component_installer_policy_shim.h" -#include "android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy.h" #include "base/barrier_closure.h" #include "base/command_line.h" #include "base/functional/callback.h" @@ -73,9 +72,6 @@ [](const std::string& raw_commitments) { NOTREACHED(); })), register_callback, barrier_closure); } - - RegisterWebViewAppsPackageNamesAllowlistComponent(register_callback, - barrier_closure); } } // namespace android_webview
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index e78fe5a..29139b8 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -14,8 +14,6 @@ import("//components/crash/android/silent_java_assert_reporting.gni") import("//device/vr/buildflags/buildflags.gni") import("//tools/v8_context_snapshot/v8_context_snapshot.gni") -import("//weblayer/variables.gni") -import("//weblayer/weblayer_resource_exclusions.gni") declare_args() { # Android package name to use when compiling the system_webview_apk and @@ -98,13 +96,11 @@ forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY + [ - "exclude_weblayer_java", "is_64_bit_browser", "is_trichrome", "include_32_bit_webview", "include_64_bit_webview", "manifest_package", - "weblayer_product_config_java_package", "webview_framework_dep", "webview_product_config_java_package", "webview_devui_show_icon", @@ -112,8 +108,6 @@ ]) _is_bundle_module = _target_type == "android_app_bundle_module" - _exclude_weblayer_java = - defined(invoker.exclude_weblayer_java) && invoker.exclude_weblayer_java _omit_dex = defined(invoker.omit_dex) && invoker.omit_dex if (!defined(min_sdk_version) && _is_trichrome) { @@ -132,46 +126,13 @@ "//android_webview:pak_file_assets", ] - if (_exclude_weblayer_java) { - deps += [ "//android_webview:android_webview_no_weblayer_java" ] - } else { - if (_is_bundle_module && webview_includes_weblayer) { - deps += [ - # TODO(crbug.com/1105096): WebLayer resources are added to the base - # module for now because of bugs with shared resources in splits. - ":${target_name}__all_weblayer_resources", - "//android_webview:android_webview_no_weblayer_java", - "//weblayer/browser/java:base_module_java", - ] - } else { - deps += [ "//android_webview:android_webview_java" ] - } - - # Resources from this target will be kept in the base bundle module - # instead of in language splits. - if (!defined(shared_resources_allowlist_target)) { - shared_resources_allowlist_target = - "//android_webview:system_webview_no_weblayer_apk" - } - } + deps += [ "//android_webview:android_webview_no_weblayer_java" ] if (!_omit_dex) { product_config_java_packages = [ invoker.webview_product_config_java_package ] } - if (webview_includes_weblayer) { - if (_is_bundle_module) { - deps += [ "//weblayer:bundle_locale_pak_assets" ] - } else { - deps += [ "//weblayer:locale_pak_assets" ] - } - if (!_omit_dex) { - product_config_java_packages += - [ invoker.weblayer_product_config_java_package ] - } - } - if (!defined(alternative_android_sdk_dep)) { alternative_android_sdk_dep = invoker.webview_framework_dep } @@ -259,38 +220,12 @@ } } - _include_arcore = - webview_includes_weblayer && enable_arcore && !_exclude_weblayer_java && - (_include_secondary_support || _include_primary_support) - - if (_include_arcore) { - # Do not add manifest entries because embedders are the ones that will need to add them. - deps += [ "//third_party/arcore-android-sdk-client:com_google_ar_core_J__unpack_aar" ] - _libarcore_dir = get_label_info( - "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)", - "target_out_dir") + "/com_google_ar_core_java/jni" - if (!_is_bundle_module) { - deps += [ - "//third_party/arcore-android-sdk-client:arcore_remove_manifest_java", - ] - } - } - if (_include_primary_support) { deps += [ "//android_webview:webview_primary_abi_assets", "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline", ] loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ] - if (webview_includes_weblayer) { - deps += [ "//base/android/linker:chromium_android_linker" ] - loadable_modules += - [ "$root_out_dir/libchromium_android_linker$shlib_extension" ] - } - if (_include_arcore) { - loadable_modules += - [ "$_libarcore_dir/$android_app_abi/libarcore_sdk_c.so" ] - } } if (_include_secondary_support) { _trampoline = "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)" @@ -301,15 +236,6 @@ _secondary_out_dir = get_label_info(_trampoline, "root_out_dir") secondary_abi_loadable_modules = [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ] - if (webview_includes_weblayer) { - deps += [ "//base/android/linker:chromium_android_linker($android_secondary_abi_toolchain)" ] - secondary_abi_loadable_modules += - [ "$_secondary_out_dir/libchromium_android_linker$shlib_extension" ] - } - if (_include_arcore) { - secondary_abi_loadable_modules += - [ "$_libarcore_dir/$android_app_secondary_abi/libarcore_sdk_c.so" ] - } } aapt_locale_allowlist = platform_pak_locales @@ -317,15 +243,6 @@ resource_exclusion_regex = common_resource_exclusion_regex resource_exclusion_exceptions = common_resource_exclusion_exceptions - if (webview_includes_weblayer) { - resource_values_filter_rules = weblayer_resource_values_filter_rules - resource_exclusion_exceptions += weblayer_resource_exclusion_exceptions - - # Note: WebLayer's resource exclusion regex deliberately does not start - # with "|". - resource_exclusion_regex += "|" + weblayer_resource_exclusion_regex - } - # We only optimize resources for bundles since APKs are not shipped. # Resources only live in the base module atm as such we only need to set # these on the base module
diff --git a/android_webview/system_webview_bundle.gni b/android_webview/system_webview_bundle.gni index 73fa22ff..ce3af8f 100644 --- a/android_webview/system_webview_bundle.gni +++ b/android_webview/system_webview_bundle.gni
@@ -6,87 +6,12 @@ import("//build/config/locales.gni") import("//components/crash/android/silent_java_assert_reporting.gni") import("//device/vr/buildflags/buildflags.gni") -import("//weblayer/variables.gni") template("system_webview_bundle") { _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome assert(_is_trichrome == defined(invoker.static_library_provider)) - if (webview_includes_weblayer) { - _base_target_name = get_label_info(invoker.base_module_target, "name") - _base_target_gen_dir = - get_label_info(invoker.base_module_target, "target_gen_dir") - _base_module_build_config = - "$_base_target_gen_dir/${_base_target_name}.build_config.json" - _rebased_base_module_build_config = - rebase_path(_base_module_build_config, root_build_dir) - _base_module_version_code = - "@FileArg($_rebased_base_module_build_config:deps_info:version_code)" - - # TODO(crbug.com/1105096): If WebView starts using - # //components/module_installer, it will probably make sense to refactor - # chrome_feature_module() to be used here. - _base_module_build_config_target = - "${invoker.base_module_target}$build_config_target_suffix" - _weblayer_module_target = "${target_name}__weblayer_bundle_module" - _weblayer_module_desc = { - name = "weblayer" - module_target = ":${_weblayer_module_target}" - } - - # TODO(crbug.com/1105096): This target is needed to add all WebLayer - # resources to the base module because of bugs with shared resources in - # splits. - android_resources("${_base_target_name}__all_weblayer_resources") { - recursive_resource_deps = true - deps = [ "//weblayer/browser/java" ] - if (defined(invoker.weblayer_deps)) { - deps += invoker.weblayer_deps - } - } - - android_app_bundle_module(_weblayer_module_target) { - forward_variables_from(invoker, - [ - "base_module_target", - "min_sdk_version", - ]) - android_manifest = "//weblayer/browser/java/AndroidManifest.xml" - - # The manifest depends on the package name from the base build config. - android_manifest_dep = _base_module_build_config_target - deps = [ - "//weblayer/browser/java", - _base_module_build_config_target, - ] - if (defined(invoker.weblayer_deps)) { - deps += invoker.weblayer_deps - } - if (enable_arcore) { - deps += [ - "//third_party/arcore-android-sdk-client:arcore_remove_manifest_java", - ] - } - aapt_locale_allowlist = platform_pak_locales - proguard_enabled = !is_java_debug - module_name = "weblayer" - package_id = 126 - version_name = - "@FileArg($_rebased_base_module_build_config:deps_info:version_name)" - version_code = _base_module_version_code - manifest_package = - "@FileArg($_rebased_base_module_build_config:deps_info:package_name)" - if (!defined(min_sdk_version) && _is_trichrome) { - min_sdk_version = 29 - } - - if (enable_silent_java_assert_reporting) { - custom_assertion_handler = crash_reporting_assertion_handler - } - } - } - android_app_bundle(target_name) { command_line_flags_file = "webview-command-line" if (!is_java_debug) { @@ -97,9 +22,6 @@ if (_is_trichrome) { min_sdk_version = 29 } - if (webview_includes_weblayer) { - extra_modules = [ _weblayer_module_desc ] - } system_image_locale_allowlist = platform_pak_locales is_multi_abi = android_64bit_target_cpu && (!defined(invoker.include_64_bit_webview) ||
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index 352fb8e..51e9ba4c 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -648,7 +648,6 @@ "//android_webview/browser/lifecycle", "//android_webview/browser/metrics", "//android_webview/common", - "//android_webview/common:tests", "//android_webview/nonembedded", "//base/test:proto_test_support", "//base/test:test_support", @@ -706,7 +705,6 @@ "../browser/aw_pac_processor_unittest.cc", "../browser/aw_permission_manager_unittest.cc", "../browser/aw_user_agent_metadata_unittest.cc", - "../browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc", "../browser/enterprise_authentication_app_link_policy_handler_unittest.cc", "../browser/gfx/begin_frame_source_webview_unittest.cc", "../browser/gfx/browser_view_renderer_unittest.cc", @@ -737,7 +735,6 @@ "../nonembedded/component_updater/aw_component_installer_policy_unittest.cc", "../nonembedded/component_updater/aw_component_update_service_test.cc", "../nonembedded/component_updater/aw_component_updater_configurator_unittest.cc", - "../nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc", ] }
diff --git a/android_webview/variables.gni b/android_webview/variables.gni index 0b7e34d..f387628 100644 --- a/android_webview/variables.gni +++ b/android_webview/variables.gni
@@ -4,7 +4,6 @@ import("//build/config/android/channel.gni") import("//build/config/android/config.gni") -import("//weblayer/variables.gni") declare_args() { # Show a launcher icon to open WebView developer UI. This is enabled by @@ -21,8 +20,4 @@ "//content/public/android:identity_credentials_public_impl_java", ] -if (webview_includes_weblayer) { - upstream_only_webview_deps += [ "//weblayer/browser/java:upstream_java" ] -} - webview_product_config_java_package = "org.chromium.android_webview"
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index e816aab..d992345 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -310,6 +310,8 @@ "booting/booting_animation_view.cc", "booting/booting_animation_view.h", "bubble/bubble_constants.h", + "bubble/bubble_event_filter.cc", + "bubble/bubble_event_filter.h", "bubble/bubble_utils.cc", "bubble/bubble_utils.h", "bubble/simple_grid_layout.cc", @@ -622,6 +624,8 @@ "frame_throttler/frame_throttling_controller.cc", "frame_throttler/frame_throttling_controller.h", "frame_throttler/frame_throttling_observer.h", + "game_dashboard/game_dashboard_button.cc", + "game_dashboard/game_dashboard_button.h", "game_dashboard/game_dashboard_context.cc", "game_dashboard/game_dashboard_context.h", "game_dashboard/game_dashboard_controller.cc", @@ -3149,6 +3153,7 @@ "assistant/ui/main_stage/ui_element_container_view_unittest.cc", "assistant/util/deep_link_util_unittest.cc", "assistant/util/resource_util_unittest.cc", + "bubble/bubble_event_filter_unittest.cc", "bubble/bubble_utils_unittest.cc", "capture_mode/capture_audio_mixing_unittests.cc", "capture_mode/capture_mode_camera_unittests.cc",
diff --git a/ash/ambient/metrics/ambient_metrics.cc b/ash/ambient/metrics/ambient_metrics.cc index 720a5dd..30cc564 100644 --- a/ash/ambient/metrics/ambient_metrics.cc +++ b/ash/ambient/metrics/ambient_metrics.cc
@@ -204,7 +204,8 @@ AmbientModePhotoSource AmbientSettingsToPhotoSource( const AmbientSettings& settings) { - if (settings.topic_source == ash::AmbientModeTopicSource::kArtGallery) { + if (settings.topic_source == + ash::personalization_app::mojom::TopicSource::kArtGallery) { return AmbientModePhotoSource::kArtGallery; }
diff --git a/ash/ambient/metrics/ambient_metrics_unittest.cc b/ash/ambient/metrics/ambient_metrics_unittest.cc index 0dfbb05..c561d39c 100644 --- a/ash/ambient/metrics/ambient_metrics_unittest.cc +++ b/ash/ambient/metrics/ambient_metrics_unittest.cc
@@ -27,10 +27,11 @@ namespace metrics { using AmbientMetricsTest = testing::Test; using ash::personalization_app::mojom::AmbientTheme; +using ash::personalization_app::mojom::TopicSource; TEST_F(AmbientMetricsTest, AmbientModePhotoSourceArt) { AmbientSettings settings; - settings.topic_source = AmbientModeTopicSource::kArtGallery; + settings.topic_source = TopicSource::kArtGallery; EXPECT_EQ(AmbientModePhotoSource::kArtGallery, AmbientSettingsToPhotoSource(settings)); @@ -38,7 +39,7 @@ TEST_F(AmbientMetricsTest, AmbientModePhotoSourceGooglePhotosEmpty) { AmbientSettings settings; - settings.topic_source = AmbientModeTopicSource::kGooglePhotos; + settings.topic_source = TopicSource::kGooglePhotos; settings.selected_album_ids.clear(); EXPECT_EQ(AmbientModePhotoSource::kGooglePhotosEmpty, @@ -47,7 +48,7 @@ TEST_F(AmbientMetricsTest, AmbientModePhotoSourceGooglePhotosRecentHighlights) { AmbientSettings settings; - settings.topic_source = AmbientModeTopicSource::kGooglePhotos; + settings.topic_source = TopicSource::kGooglePhotos; settings.selected_album_ids.clear(); settings.selected_album_ids.push_back( ash::kAmbientModeRecentHighlightsAlbumId); @@ -58,7 +59,7 @@ TEST_F(AmbientMetricsTest, AmbientModePhotoSourceGooglePhotosBoth) { AmbientSettings settings; - settings.topic_source = AmbientModeTopicSource::kGooglePhotos; + settings.topic_source = TopicSource::kGooglePhotos; settings.selected_album_ids.clear(); settings.selected_album_ids.push_back( ash::kAmbientModeRecentHighlightsAlbumId); @@ -70,7 +71,7 @@ TEST_F(AmbientMetricsTest, AmbientModePhotoSourceGooglePhotosPersonalAlbum) { AmbientSettings settings; - settings.topic_source = AmbientModeTopicSource::kGooglePhotos; + settings.topic_source = TopicSource::kGooglePhotos; settings.selected_album_ids.clear(); settings.selected_album_ids.push_back("abcde");
diff --git a/ash/app_list/app_list_bubble_event_filter.cc b/ash/app_list/app_list_bubble_event_filter.cc index b8ae23d9..287199d 100644 --- a/ash/app_list/app_list_bubble_event_filter.cc +++ b/ash/app_list/app_list_bubble_event_filter.cc
@@ -4,6 +4,7 @@ #include "ash/app_list/app_list_bubble_event_filter.h" +#include "ash/bubble/bubble_event_filter.h" #include "ash/bubble/bubble_utils.h" #include "ash/shelf/hotseat_widget.h" #include "ash/shelf/shelf.h" @@ -15,61 +16,25 @@ #include "base/functional/callback.h" #include "ui/aura/window.h" #include "ui/events/event.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/rect.h" #include "ui/views/widget/widget.h" namespace ash { AppListBubbleEventFilter::AppListBubbleEventFilter( - views::Widget* widget, + views::Widget* bubble_widget, views::View* button, base::RepeatingCallback<void()> on_click_outside) - : widget_(widget), button_(button), on_click_outside_(on_click_outside) { - DCHECK(widget_); - DCHECK(on_click_outside_); - Shell::Get()->AddPreTargetHandler(this); + : BubbleEventFilter(bubble_widget, button, on_click_outside) { + CHECK(bubble_widget); + CHECK(on_click_outside); } -AppListBubbleEventFilter::~AppListBubbleEventFilter() { - Shell::Get()->RemovePreTargetHandler(this); -} +AppListBubbleEventFilter::~AppListBubbleEventFilter() = default; -void AppListBubbleEventFilter::SetButton(views::View* button) { - button_ = button; -} - -void AppListBubbleEventFilter::OnMouseEvent(ui::MouseEvent* event) { - if (event->type() == ui::ET_MOUSE_PRESSED) - ProcessPressedEvent(*event); -} - -void AppListBubbleEventFilter::OnTouchEvent(ui::TouchEvent* event) { - if (event->type() == ui::ET_TOUCH_PRESSED) - ProcessPressedEvent(*event); -} - -void AppListBubbleEventFilter::ProcessPressedEvent( +bool AppListBubbleEventFilter::ShouldRunOnClickOutsideCallback( const ui::LocatedEvent& event) { - // Check the general rules for closing bubbles. - if (!bubble_utils::ShouldCloseBubbleForEvent(event)) - return; - - gfx::Point event_location = event.target() - ? event.target()->GetScreenLocation(event) - : event.root_location(); - // Ignore clicks inside the widget. - if (widget_->GetWindowBoundsInScreen().Contains(event_location)) - return; - - // Ignore clicks that hit the button (which usually spawned the widget). - // Use HitTestPoint() because the shelf home button has a custom view targeter - // that handles clicks outside its bounds, like in the corner of the screen. - if (button_) { - gfx::Point point_in_button = event_location; - views::View::ConvertPointFromScreen(button_, &point_in_button); - if (button_->HitTestPoint(point_in_button)) - return; + if (!BubbleEventFilter::ShouldRunOnClickOutsideCallback(event)) { + return false; } if (aura::Window* const target = static_cast<aura::Window*>(event.target())) { @@ -79,11 +44,11 @@ const aura::Window* status_window = shelf->shelf_widget()->status_area_widget()->GetNativeWindow(); if (status_window && status_window->Contains(target)) { - return; + return false; } } - on_click_outside_.Run(); + return true; } } // namespace ash
diff --git a/ash/app_list/app_list_bubble_event_filter.h b/ash/app_list/app_list_bubble_event_filter.h index 0cd1e2e..f694101 100644 --- a/ash/app_list/app_list_bubble_event_filter.h +++ b/ash/app_list/app_list_bubble_event_filter.h
@@ -6,9 +6,8 @@ #define ASH_APP_LIST_APP_LIST_BUBBLE_EVENT_FILTER_H_ #include "ash/ash_export.h" +#include "ash/bubble/bubble_event_filter.h" #include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "ui/events/event_handler.h" namespace ui { class LocatedEvent; @@ -21,38 +20,19 @@ namespace ash { -// Observes mouse and touch events. Invokes a callback when a press event -// happens outside the bubble widget's bounds and also outside the button that -// spawned the bubble. Tests the button bounds because otherwise a click on the -// button will result in the bubble being closed then immediately reopened. -// Similar to TrayEventFilter, but only deals with a single widget, and is not -// coupled to system tray details. -class ASH_EXPORT AppListBubbleEventFilter : public ui::EventHandler { +// Handles events for the app list bubble, the given callback will be triggered +// when an event happens and `ShouldRunOnClickOutsideCallback()` is satisfied. +class ASH_EXPORT AppListBubbleEventFilter : public BubbleEventFilter { public: - // See class comment. Runs `on_click_outside` when a click or tap occurs - // outside the bounds of `widget` and `button`. - AppListBubbleEventFilter(views::Widget* widget, + AppListBubbleEventFilter(views::Widget* bubble_widget, views::View* button, base::RepeatingClosure on_click_outside); AppListBubbleEventFilter(const AppListBubbleEventFilter&) = delete; AppListBubbleEventFilter& operator=(const AppListBubbleEventFilter&) = delete; ~AppListBubbleEventFilter() override; - // Changes the button to check (see class comment). Useful if the app list - // has changed displays, so a different home button needs to be checked. - void SetButton(views::View* button); - - // ui::EventHandler: - void OnMouseEvent(ui::MouseEvent* event) override; - void OnTouchEvent(ui::TouchEvent* event) override; - - private: - void ProcessPressedEvent(const ui::LocatedEvent& event); - - const raw_ptr<views::Widget, ExperimentalAsh> widget_; - raw_ptr<views::View, DanglingUntriaged | ExperimentalAsh> - button_; // May be null. - base::RepeatingClosure on_click_outside_; + // BubbleEventFilter + bool ShouldRunOnClickOutsideCallback(const ui::LocatedEvent& event) override; }; } // namespace ash
diff --git a/ash/app_list/app_list_bubble_event_filter_unittest.cc b/ash/app_list/app_list_bubble_event_filter_unittest.cc index 055c0d2..7a0c61a3 100644 --- a/ash/app_list/app_list_bubble_event_filter_unittest.cc +++ b/ash/app_list/app_list_bubble_event_filter_unittest.cc
@@ -6,15 +6,14 @@ #include <memory> +#include "ash/root_window_controller.h" #include "ash/shell.h" +#include "ash/system/status_area_widget.h" #include "ash/test/ash_test_base.h" #include "ash/test/test_widget_builder.h" #include "base/memory/raw_ptr.h" -#include "base/run_loop.h" #include "base/test/bind.h" -#include "base/test/mock_callback.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/interaction/expect_call_in_scope.h" namespace ash { namespace { @@ -67,39 +66,17 @@ AppListBubbleEventFilterTest, testing::Bool()); -TEST_P(AppListBubbleEventFilterTest, ClickOutsideWidgetRunsCallback) { +TEST_P(AppListBubbleEventFilterTest, ClickOnStatusAreaDoesNotRunCallback) { int callback_count = 0; auto callback = base::BindLambdaForTesting([&]() { ++callback_count; }); AppListBubbleEventFilter filter(widget_.get(), view_, callback); - // Click outside the widget. - gfx::Point point_outside_widget = widget_->GetWindowBoundsInScreen().origin(); - point_outside_widget.Offset(-1, -1); - ClickOrTapAt(point_outside_widget); + // Click on the status area widget should not trigger the callback. + auto* status_area = + Shell::Get()->GetPrimaryRootWindowController()->GetStatusAreaWidget(); + ClickOrTapAt(status_area->GetWindowBoundsInScreen().CenterPoint()); - EXPECT_EQ(callback_count, 1); -} - -TEST_P(AppListBubbleEventFilterTest, ClickInsideWidgetDoesNotRunCallback) { - bool callback_ran = false; - auto callback = base::BindLambdaForTesting([&]() { callback_ran = true; }); - AppListBubbleEventFilter filter(widget_.get(), view_, callback); - - // Click inside the widget. - ClickOrTapAt(widget_->GetWindowBoundsInScreen().CenterPoint()); - - EXPECT_FALSE(callback_ran); -} - -TEST_P(AppListBubbleEventFilterTest, ClickInsideViewDoesNotRunCallback) { - bool callback_ran = false; - auto callback = base::BindLambdaForTesting([&]() { callback_ran = true; }); - AppListBubbleEventFilter filter(widget_.get(), view_, callback); - - // Click inside the view. - ClickOrTapAt(view_->GetBoundsInScreen().CenterPoint()); - - EXPECT_FALSE(callback_ran); + EXPECT_EQ(callback_count, 0); } } // namespace
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc index 3bc2fa8a..daef82b 100644 --- a/ash/app_list/app_list_presenter_unittest.cc +++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -137,7 +137,6 @@ const std::string& result_id) { auto suggestion_result = std::make_unique<TestSearchResult>(); suggestion_result->set_result_id(result_id); - suggestion_result->set_is_omnibox_search(true); suggestion_result->set_best_match(true); suggestion_result->set_display_type(SearchResultDisplayType::kList); SearchResultActions actions;
diff --git a/ash/app_list/app_list_test_view_delegate.cc b/ash/app_list/app_list_test_view_delegate.cc index a9ebd7f0..35e39e9b 100644 --- a/ash/app_list/app_list_test_view_delegate.cc +++ b/ash/app_list/app_list_test_view_delegate.cc
@@ -49,9 +49,6 @@ for (size_t i = 0; i < results->item_count(); ++i) { if (results->GetItemAt(i)->id() == result_id) { open_search_result_counts_[i]++; - if (results->GetItemAt(i)->is_omnibox_search()) { - ++open_assistant_ui_count_; - } break; } }
diff --git a/ash/app_list/app_list_test_view_delegate.h b/ash/app_list/app_list_test_view_delegate.h index 38129a6d..0c71f83 100644 --- a/ash/app_list/app_list_test_view_delegate.h +++ b/ash/app_list/app_list_test_view_delegate.h
@@ -41,7 +41,6 @@ int dismiss_count() const { return dismiss_count_; } int open_search_result_count() const { return open_search_result_count_; } - int open_assistant_ui_count() const { return open_assistant_ui_count_; } std::map<size_t, int>& open_search_result_counts() { return open_search_result_counts_; } @@ -135,7 +134,6 @@ int dismiss_count_ = 0; int open_search_result_count_ = 0; - int open_assistant_ui_count_ = 0; int next_profile_app_count_ = 0; int show_wallpaper_context_menu_count_ = 0; AppListState app_list_page_ = AppListState::kInvalidState;
diff --git a/ash/app_list/model/search/search_result.h b/ash/app_list/model/search/search_result.h index e4ce65c..e816fa0 100644 --- a/ash/app_list/model/search/search_result.h +++ b/ash/app_list/model/search/search_result.h
@@ -145,11 +145,6 @@ const Actions& actions() const { return metadata_->actions; } void SetActions(const Actions& sets); - bool is_omnibox_search() const { return metadata_->is_omnibox_search; } - void set_is_omnibox_search(bool is_omnibox_search) { - metadata_->is_omnibox_search = is_omnibox_search; - } - bool is_visible() const { return is_visible_; } void set_is_visible(bool is_visible) { is_visible_ = is_visible; }
diff --git a/ash/app_list/views/app_drag_icon_proxy.cc b/ash/app_list/views/app_drag_icon_proxy.cc index 4918fb7..a960beb 100644 --- a/ash/app_list/views/app_drag_icon_proxy.cc +++ b/ash/app_list/views/app_drag_icon_proxy.cc
@@ -84,26 +84,16 @@ shadow_->ObserveColorProviderSource(drag_image_widget_.get()); if (is_folder_icon) { - ui::Layer* blurred_layer; - float corner_radius; - - if (features::IsAppCollectionFolderRefreshEnabled()) { - // For the refreshed icon, the blur should be only added on the background - // circle, where none of any exising layer is bounded to that area. - // Therefore, the `blurred_background_layer_` is needed here to explicitly - // blur the background of the icon. - blurred_background_layer_ = - std::make_unique<ui::LayerOwner>(std::make_unique<ui::Layer>()); - blurred_layer = blurred_background_layer_->layer(); - drag_image->AddLayerToRegion(blurred_layer, views::LayerRegion::kBelow); - blurred_layer->SetBounds(shadow_->GetContentBounds()); - corner_radius = shadow_->GetContentBounds().width() / 2.0f; - } else { - // For the clipped drag icon, the `drag_image` layer can be used for - // blurring as the whole clipped area needs to be blurred. - blurred_layer = drag_image->layer(); - corner_radius = size.width() / 2.0f; - } + // The blur should be only added on the background circle, where none of + // any existing layer is bounded to that area. + // Therefore, the `blurred_background_layer_` is needed here to explicitly + // blur the background of the icon. + blurred_background_layer_ = + std::make_unique<ui::LayerOwner>(std::make_unique<ui::Layer>()); + ui::Layer* const blurred_layer = blurred_background_layer_->layer(); + drag_image->AddLayerToRegion(blurred_layer, views::LayerRegion::kBelow); + blurred_layer->SetBounds(shadow_->GetContentBounds()); + const float corner_radius = shadow_->GetContentBounds().width() / 2.0f; blurred_layer->SetRoundedCornerRadius( {corner_radius, corner_radius, corner_radius, corner_radius}); @@ -192,9 +182,7 @@ } ui::Layer* AppDragIconProxy::GetBlurredLayerForTesting() { - return features::IsAppCollectionFolderRefreshEnabled() - ? blurred_background_layer_->layer() - : GetImageLayerForTesting(); // IN-TEST + return blurred_background_layer_->layer(); } void AppDragIconProxy::OnProxyAnimationCompleted() {
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index 6ec747a..14d4e30 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -265,7 +265,6 @@ jelly_style_(chromeos::features::IsJellyEnabled()), config_(config), icon_scale_(icon_scale) { - DCHECK(features::IsAppCollectionFolderRefreshEnabled()); folder_item_->item_list()->AddObserver(this); } FolderIconView(const FolderIconView&) = delete; @@ -491,8 +490,7 @@ item_weak_(item), grid_delegate_(grid_delegate), view_delegate_(view_delegate), - use_item_icon_(!is_folder_ || - !features::IsAppCollectionFolderRefreshEnabled()), + use_item_icon_(!is_folder_), context_(context) { DCHECK(app_list_config_); DCHECK(grid_delegate_); @@ -505,6 +503,11 @@ item_weak_->GetMetadata()->app_status == AppStatus::kPending || item_weak_->GetMetadata()->app_status == AppStatus::kInstalling; + // Draw the promise ring for the first time before waiting for updates. + if (is_promise_app_) { + ItemProgressUpdated(); + } + const bool is_jelly_enabled = chromeos::features::IsJellyEnabled(); StyleUtil::SetUpInkDropForButton( this, gfx::Insets(), @@ -579,16 +582,9 @@ } if (is_folder_) { - if (features::IsAppCollectionFolderRefreshEnabled()) { - // Draw the background as part of the icon view. - EnsureIconBackgroundLayer(); - } else { - views::View* icon_view = GetIconView(); - icon_view->SetPaintToLayer(); - icon_view->layer()->SetFillsBoundsOpaquely(false); - icon_view->SetBackground(views::CreateThemedSolidBackground( - kColorAshControlBackgroundColorInactive)); - } + // Draw the background as part of the icon view. + EnsureIconBackgroundLayer(); + // Set background blur for folder icon and use mask layer to clip it into // circle. Note that blur is only enabled in tablet mode to improve dragging // smoothness. @@ -752,8 +748,7 @@ void AppListItemView::UpdateBackgroundLayerBounds() { auto* background_layer = GetIconBackgroundLayer(); - if (!background_layer || !features::IsAppCollectionFolderRefreshEnabled() || - GetIconView()->bounds().IsEmpty()) { + if (!background_layer || GetIconView()->bounds().IsEmpty()) { return; } @@ -1042,8 +1037,7 @@ // The list of descriptions to be announced. std::vector<std::u16string> descriptions; - if (item_weak_->is_folder() && - features::IsAppCollectionFolderRefreshEnabled()) { + if (item_weak_->is_folder()) { // For folder items, announce the number of apps in the folder. std::u16string app_count_announcement = l10n_util::GetPluralStringFUTF16( IDS_APP_LIST_FOLDER_NUMBER_OF_APPS_ACCESSIBILE_DESCRIPTION, @@ -1706,14 +1700,7 @@ } gfx::Rect AppListItemView::GetIconBounds() const { - gfx::Rect folder_icon_bounds = GetIconView()->bounds(); - if (is_folder_ && !features::IsAppCollectionFolderRefreshEnabled()) { - // The folder icon is in unclipped size, so clip it before return. - folder_icon_bounds.ClampToCenteredSize( - app_list_config_->icon_visible_size()); - return folder_icon_bounds; - } - return folder_icon_bounds; + return GetIconView()->bounds(); } gfx::Rect AppListItemView::GetIconBoundsInScreen() const { @@ -1867,7 +1854,7 @@ return view->GetColorProvider()->GetColor(color_id); }, base::Unretained(this)))); - progress_indicator_->SetColorId(cros_tokens::kCrosRefPrimary90); + progress_indicator_->SetColorId(cros_tokens::kCrosSysOnPrimaryContainer); } UpdateProgressRingBounds(); @@ -1920,77 +1907,34 @@ weak_ptr_factory_.GetWeakPtr(), extend_icon)) .Once(); - if (features::IsAppCollectionFolderRefreshEnabled()) { - UpdateBackgroundLayerBounds(); - const int width = extend_icon ? app_list_config_->unclipped_icon_dimension() - : app_list_config_->icon_visible_dimension(); - gfx::Rect clip_rect(background_layer->size()); - clip_rect.ClampToCenteredSize( - ScaleToRoundedSize(gfx::Size(width, width), icon_scale_)); + UpdateBackgroundLayerBounds(); + const int width = extend_icon ? app_list_config_->unclipped_icon_dimension() + : app_list_config_->icon_visible_dimension(); + gfx::Rect clip_rect(background_layer->size()); + clip_rect.ClampToCenteredSize( + ScaleToRoundedSize(gfx::Size(width, width), icon_scale_)); - const int corner_radius = - extend_icon ? app_list_config_->icon_extended_background_radius() - : width / 2; - const base::TimeDelta duration = - animate ? base::Milliseconds(125) : base::TimeDelta(); - builder.GetCurrentSequence() - .SetDuration(duration) - .SetClipRect(background_layer, clip_rect, animation_tween_type) - .SetRoundedCorners(background_layer, - gfx::RoundedCornersF(corner_radius * icon_scale_), - animation_tween_type); - if (chromeos::features::IsJellyEnabled() && GetWidget()) { - builder.GetCurrentSequence().SetColor( - background_layer, - GetColorProvider()->GetColor(GetBackgroundLayerColorId()), - animation_tween_type); - } - return; - } - - // Handle folder icons - if (is_folder_) { - const int corner_radius = - extend_icon ? app_list_config_->unclipped_icon_dimension() / 2 - : app_list_config_->icon_visible_dimension() / 2; - - gfx::Rect clip_rect = GetIconView()->GetLocalBounds(); - if (!extend_icon) { - clip_rect.Inset(gfx::Insets(app_list_config_->folder_icon_insets())); - } - builder.GetCurrentSequence() - .SetDuration(base::Milliseconds(animate ? 125 : 0)) - .SetClipRect(background_layer, clip_rect, animation_tween_type) - .SetRoundedCorners(background_layer, - gfx::RoundedCornersF(corner_radius), - animation_tween_type); - return; - } - - // Handle app icons - gfx::Rect background_target_bounds( - GetIconView()->layer()->bounds().CenterPoint(), gfx::Size()); - if (extend_icon) { - background_layer->SetBounds(background_target_bounds); - background_layer->SetColor( - GetColorProvider()->GetColor(GetBackgroundLayerColorId())); - background_target_bounds.Outset( - app_list_config_->folder_dropping_circle_radius() * icon_scale_); - } + const int corner_radius = + extend_icon ? app_list_config_->icon_extended_background_radius() + : width / 2; + const base::TimeDelta duration = + animate ? base::Milliseconds(125) : base::TimeDelta(); builder.GetCurrentSequence() - .SetDuration(base::Milliseconds(animate ? 250 : 0)) - .SetBounds(background_layer, background_target_bounds, - animation_tween_type) - .SetRoundedCorners( - background_layer, - gfx::RoundedCornersF(background_target_bounds.width() / 2), - animation_tween_type); + .SetDuration(duration) + .SetClipRect(background_layer, clip_rect, animation_tween_type) + .SetRoundedCorners(background_layer, + gfx::RoundedCornersF(corner_radius * icon_scale_), + animation_tween_type); + if (chromeos::features::IsJellyEnabled() && GetWidget()) { + builder.GetCurrentSequence().SetColor( + background_layer, + GetColorProvider()->GetColor(GetBackgroundLayerColorId()), + animation_tween_type); + } } void AppListItemView::EnsureIconBackgroundLayer() { - const bool clip_inner_icons = - is_folder_ && !features::IsAppCollectionFolderRefreshEnabled(); - if (clip_inner_icons || icon_background_layer_) { + if (icon_background_layer_) { return; } @@ -2024,10 +1968,6 @@ } ui::Layer* AppListItemView::GetIconBackgroundLayer() { - if (is_folder_ && !features::IsAppCollectionFolderRefreshEnabled()) { - return GetIconView()->layer(); - } - if (!icon_background_layer_) { return nullptr; }
diff --git a/ash/app_list/views/app_list_item_view_pixeltest.cc b/ash/app_list/views/app_list_item_view_pixeltest.cc index 865c426..141f003 100644 --- a/ash/app_list/views/app_list_item_view_pixeltest.cc +++ b/ash/app_list/views/app_list_item_view_pixeltest.cc
@@ -57,7 +57,6 @@ void SetUp() override { scoped_feature_list_.InitWithFeatureStates( {{app_list_features::kDragAndDropRefactor, use_drag_drop_refactor()}, - {features::kAppCollectionFolderRefresh, use_folder_icon_refresh()}, {chromeos::features::kJelly, jelly_enabled()}}); AshTestBase::SetUp(); @@ -153,10 +152,8 @@ return 5; } - size_t base_revision_number = 7; - if (use_folder_icon_refresh()) { - ++base_revision_number; - } + size_t base_revision_number = 8; + if (use_drag_drop_refactor()) { ++base_revision_number; } @@ -191,10 +188,6 @@ /*jelly_enabled=*/testing::Bool())); TEST_P(AppListItemViewPixelTest, AppListItemView) { - // Folder icon refresh doesn't change the app list item view. - if (use_folder_icon_refresh()) { - return; - } CreateAppListItem("App"); CreateAppListItem("App with a loooooooong name"); @@ -208,7 +201,7 @@ TEST_P(AppListItemViewPixelTest, AppListFolderItemsLayoutInIcon) { // Skip the case where the apps are newly installed as it doesn't change the // folder icons. - if (is_new_install()) { + if (!use_folder_icon_refresh() || is_new_install()) { return; } @@ -218,31 +211,21 @@ AppListConfigProvider::Get().ResetForTesting(); // To test the item counter on folder icons, set the maximum number of the - // items in a folder to 5. For legacy folder icons, set the max items to 4 to - // reduce the revisions. - const int max_items_in_folder = use_folder_icon_refresh() ? 5 : 4; + // items in a folder to 5. + const int max_items_in_folder = 5; CreateFoldersContainingDifferentNumOfItems(max_items_in_folder); ShowAppList(); if (jelly_enabled()) { - if (use_folder_icon_refresh()) { - // In production, use_folder_icon_refresh() is always enabled when jelly - // is enabled. - EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( - GenerateScreenshotName(), /*revision_number=*/4, GetItemViewAt(0), - GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3), - GetItemViewAt(4))); - } - // jelly_enabled && !use_folder_icon_refresh is deliberately skipped. - } else if (use_folder_icon_refresh()) { EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( - GenerateScreenshotName(), /*revision_number=*/5, GetItemViewAt(0), + GenerateScreenshotName(), /*revision_number=*/4, GetItemViewAt(0), GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3), GetItemViewAt(4))); } else { EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( - GenerateScreenshotName(), /*revision_number=*/4, GetItemViewAt(0), - GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3))); + GenerateScreenshotName(), /*revision_number=*/5, GetItemViewAt(0), + GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3), + GetItemViewAt(4))); } } @@ -250,7 +233,7 @@ TEST_P(AppListItemViewPixelTest, AppListFolderIconExtendedState) { // Skip the case where the apps are newly installed as it doesn't change the // folder icons. - if (is_new_install()) { + if (!use_folder_icon_refresh() || is_new_install()) { return; } @@ -260,9 +243,8 @@ AppListConfigProvider::Get().ResetForTesting(); // To test the item counter on folder icons, set the maximum number of the - // items in a folder to 5. For legacy folder icons, set the max items to 4 to - // reduce the revisions. - const int max_items_in_folder = use_folder_icon_refresh() ? 5 : 4; + // items in a folder to 5. + const int max_items_in_folder = 5; CreateFoldersContainingDifferentNumOfItems(max_items_in_folder); CreateAppListItem("App"); ShowAppList(); @@ -280,23 +262,15 @@ } if (jelly_enabled()) { - if (use_folder_icon_refresh()) { - EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( - GenerateScreenshotName(), /*revision_number=*/4, GetItemViewAt(0), - GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3), - GetItemViewAt(4))); - } - // Skip the !use_folder_icon_refresh && jelly_enabled state as it doesn't - // occur in production. - } else if (use_folder_icon_refresh()) { EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( - GenerateScreenshotName(), /*revision_number=*/5, GetItemViewAt(0), + GenerateScreenshotName(), /*revision_number=*/4, GetItemViewAt(0), GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3), GetItemViewAt(4))); } else { EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( - GenerateScreenshotName(), /*revision_number=*/4, GetItemViewAt(0), - GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3))); + GenerateScreenshotName(), /*revision_number=*/5, GetItemViewAt(0), + GetItemViewAt(1), GetItemViewAt(2), GetItemViewAt(3), + GetItemViewAt(4))); } // Reset the states. @@ -312,7 +286,7 @@ TEST_P(AppListItemViewPixelTest, DraggedAppListFolderIcon) { // Skip the case where the apps are newly installed or have notifications as // they don't change the folder icons. - if (is_new_install() || has_notification()) { + if (!use_folder_icon_refresh() || is_new_install() || has_notification()) { return; } @@ -341,48 +315,49 @@ const size_t revision_number = GetRevisionNumber(); auto verify_folder_widget = - base::BindLambdaForTesting([&](int number_of_items) { + [&](int number_of_items) { std::string filename = base::NumberToString(number_of_items) + "_items_folder"; EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( base::JoinString({GenerateScreenshotName(), filename}, "."), revision_number, GetDraggedWidget())); - // Release the drag. - if (use_tablet_mode()) { - event_generator->ReleaseTouch(); - } else { - event_generator->ReleaseLeftButton(); - } - }); + }; for (size_t i = 0; i < max_items_in_folder; ++i) { gfx::Point folder_icon_center = folder_list[i]->GetIconBoundsInScreen().CenterPoint(); - if (use_drag_drop_refactor()) { - ShellTestApi().drag_drop_controller()->SetLoopClosureForTesting( - base::BindRepeating(verify_folder_widget, /*number_of_items=*/i + 1), - /*quit_closure=*/base::DoNothing()); - } + std::list<base::OnceClosure> tasks; + tasks.push_back(base::BindLambdaForTesting([&]() { + if (use_tablet_mode()) { + event_generator->PressTouch(folder_icon_center); + folder_list[i]->FireTouchDragTimerForTest(); + } else { + event_generator->MoveMouseTo(folder_icon_center); + event_generator->PressLeftButton(); + folder_list[i]->FireMouseDragTimerForTest(); + } + })); + tasks.push_back(base::BindLambdaForTesting([&]() { + if (use_tablet_mode()) { + event_generator->MoveTouch(grid_center); + } else { + event_generator->MoveMouseTo(grid_center); + } + test::AppsGridViewTestApi(apps_grid_view).WaitForItemMoveAnimationDone(); + })); + tasks.push_back(base::BindLambdaForTesting( + [&]() { verify_folder_widget(/*number_of_items=*/i + 1); })); + tasks.push_back(base::BindLambdaForTesting([&]() { + if (use_tablet_mode()) { + event_generator->ReleaseTouch(); + } else { + event_generator->ReleaseLeftButton(); + } + })); - // Start dragging the folder icon. - if (use_tablet_mode()) { - event_generator->PressTouch(folder_icon_center); - folder_list[i]->FireTouchDragTimerForTest(); - event_generator->MoveTouch(grid_center); - std::unique_ptr<test::AppsGridViewTestApi> test_api = - std::make_unique<test::AppsGridViewTestApi>(apps_grid_view); - test_api->WaitForItemMoveAnimationDone(); - } else { - event_generator->MoveMouseTo(folder_icon_center); - event_generator->PressLeftButton(); - folder_list[i]->FireMouseDragTimerForTest(); - event_generator->MoveMouseTo(grid_center); - } - - if (!use_drag_drop_refactor()) { - verify_folder_widget.Run(/*number_of_items=*/i + 1); - } + MaybeRunDragAndDropSequenceForAppList(&tasks, + /*is_touch=*/use_tablet_mode()); } }
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index d180798..f1d21f30 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -615,30 +615,10 @@ view_->GetWidget()->OnKeyEvent(&key_event); } - // Add search results for test on focus movement. + // Adds test search results. void SetUpSearchResults(int list_results_num) { SearchModel::SearchResults* results = GetSearchModel()->results(); results->DeleteAll(); - - for (int i = 0; i < list_results_num; ++i) { - std::unique_ptr<TestSearchResult> result = - std::make_unique<TestSearchResult>(); - result->set_display_type(SearchResultDisplayType::kList); - result->set_display_score(1); - result->SetTitle(u"Test"); - result->set_best_match(true); - results->Add(std::move(result)); - } - - // Adding results will schedule Update(). - base::RunLoop().RunUntilIdle(); - } - - // Add search results for test on embedded Assistant UI. - void SetUpSearchResultsForAssistantUI(int list_results_num, - int index_open_assistant_ui) { - SearchModel::SearchResults* results = GetSearchModel()->results(); - results->DeleteAll(); double display_score = list_results_num; for (int i = 0; i < list_results_num; ++i) { // Set the display score of the results in decreasing order @@ -652,9 +632,6 @@ result->SetTitle(u"Test" + base::NumberToString16(i)); result->set_result_id("Test" + base::NumberToString(i)); result->set_best_match(true); - if (i == index_open_assistant_ui) - result->set_is_omnibox_search(true); - results->Add(std::move(result)); } @@ -688,10 +665,6 @@ return delegate_->open_search_result_count(); } - int GetTotalOpenAssistantUICount() { - return delegate_->open_assistant_ui_count(); - } - // Test focus traversal across all the views in |view_list|. The initial focus // is expected to be on the first view in |view_list|. The final focus is // expected to be on the last view in |view_list| after |view_list.size()-1| @@ -1046,7 +1019,7 @@ TEST_F(AppListViewFocusTest, CtrlASelectsAllTextInSearchbox) { Show(); search_box_view()->search_box()->InsertText( - u"test", + u"test0", ui::TextInputClient::InsertTextCursorBehavior::kMoveCursorAfterText); constexpr int kListResults = 2; SetUpSearchResults(kListResults); @@ -1058,21 +1031,21 @@ // Focus left the searchbox, so the selected range should be at the end of the // search text. EXPECT_FALSE(search_box_view()->search_box()->HasSelection()); - EXPECT_EQ(gfx::Range(4, 4), + EXPECT_EQ(gfx::Range(5, 5), search_box_view()->search_box()->GetSelectedRange()); // Press Ctrl-A, everything should be selected and the selected range should // include the whole text. SimulateKeyPress(ui::VKEY_A, false, true); EXPECT_TRUE(search_box_view()->search_box()->HasSelection()); - EXPECT_EQ(gfx::Range(0, 4), + EXPECT_EQ(gfx::Range(0, 5), search_box_view()->search_box()->GetSelectedRange()); // Advance focus, Focus should leave the searchbox, and the selected range // should be at the end of the search text. SimulateKeyPress(ui::VKEY_TAB, false); EXPECT_FALSE(search_box_view()->search_box()->HasSelection()); - EXPECT_EQ(gfx::Range(4, 4), + EXPECT_EQ(gfx::Range(5, 5), search_box_view()->search_box()->GetSelectedRange()); } @@ -1676,25 +1649,22 @@ u"test", ui::TextInputClient::InsertTextCursorBehavior::kMoveCursorAfterText); const int kListResults = 2; - const int kIndexOpenAssistantUi = 1; - SetUpSearchResultsForAssistantUI(kListResults, kIndexOpenAssistantUi); + SetUpSearchResults(kListResults); SimulateKeyPress(ui::VKEY_RETURN, false); EXPECT_EQ(1, GetOpenFirstSearchResultCount()); EXPECT_EQ(1, GetTotalOpenSearchResultCount()); - EXPECT_EQ(0, GetTotalOpenAssistantUICount()); // Type something in search box to transition to re-open search state and // populate fake list results. Then hit Enter key. search_box_view()->search_box()->InsertText( u"test", ui::TextInputClient::InsertTextCursorBehavior::kMoveCursorAfterText); - SetUpSearchResultsForAssistantUI(kListResults, kIndexOpenAssistantUi); + SetUpSearchResults(kListResults); SimulateKeyPress(ui::VKEY_DOWN, false); SimulateKeyPress(ui::VKEY_RETURN, false); EXPECT_EQ(1, GetOpenFirstSearchResultCount()); EXPECT_EQ(2, GetTotalOpenSearchResultCount()); - EXPECT_EQ(1, GetTotalOpenAssistantUICount()); } // Tests that pressing escape in embedded Assistant UI returns to fullscreen
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 6468442..58d993f 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -1763,7 +1763,7 @@ (point - GetExpectedTileBounds(nearest_tile_index).CenterPoint()) .Length(); if (distance_to_tile_center > - (app_list_config_->folder_dropping_circle_radius() * + (app_list_config_->folder_bubble_radius() * (cardified_state_ ? GetAppsGridCardifiedScale() : 1.0f))) { return false; } @@ -1912,7 +1912,7 @@ // between apps. int x_offset = x_offset_direction * (total_tile_size.width() / 2 - - app_list_config_->folder_dropping_circle_radius() * + app_list_config_->folder_bubble_radius() * (cardified_state_ ? GetAppsGridCardifiedScale() : 1.0f)); const int selected_page = GetSelectedPage(); int col = (point.x() - bounds.x() + x_offset - @@ -1960,7 +1960,7 @@ (app_list_config_->grid_tile_width() + horizontal_tile_padding_ * 2) * 0.4 * (cardified_state_ ? GetAppsGridCardifiedScale() : 1.0f); const int double_icon_radius = - app_list_config_->folder_dropping_circle_radius() * 2 * + app_list_config_->folder_bubble_radius() * 2 * (cardified_state_ ? GetAppsGridCardifiedScale() : 1.0f); const int minimum_drag_distance_for_reorder = std::min(forty_percent_icon_spacing, double_icon_radius); @@ -2631,10 +2631,9 @@ const bool is_folder = drag_view_->item()->is_folder(); // Set the refreshed folder shadow size equal to the folder icon background // circle. - const gfx::Size shadow_size = - is_folder && features::IsAppCollectionFolderRefreshEnabled() - ? app_list_config_->icon_visible_size() - : drag_view_->GetIconImage().size(); + const gfx::Size shadow_size = is_folder + ? app_list_config_->icon_visible_size() + : drag_view_->GetIconImage().size(); drag_icon_proxy_ = std::make_unique<AppDragIconProxy>( GetWidget()->GetNativeWindow()->GetRootWindow(), drag_view_->GetIconImage(), location_in_screen,
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index 129809b..3391c70 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -297,9 +297,8 @@ if (is_rtl_) base::i18n::SetICUDefaultLocale("he"); - scoped_feature_list_.InitWithFeatureStates( - {{app_list_features::kDragAndDropRefactor, use_drag_drop_refactor_}, - {features::kAppCollectionFolderRefresh, folder_icon_refresh_}}); + scoped_feature_list_.InitWithFeatureState( + app_list_features::kDragAndDropRefactor, use_drag_drop_refactor_); AshTestBase::SetUp(); // Make the display big enough to hold the app list. @@ -455,8 +454,6 @@ bool use_drag_drop_refactor() const { return use_drag_drop_refactor_; } - bool folder_icon_refresh() const { return folder_icon_refresh_; } - AppsGridView* folder_apps_grid_view() const { return app_list_folder_view_->items_grid_view(); } @@ -744,8 +741,6 @@ bool create_as_tablet_mode_ = false; // True to test with the drag and drop refactor feature enabled. bool use_drag_drop_refactor_ = false; - // True if the folder icon refresh feature is enabled. - bool folder_icon_refresh_ = false; std::unique_ptr<PageFlipWaiter> page_flip_waiter_; @@ -837,17 +832,14 @@ class AppsGridViewFolderIconRefreshTest : public AppsGridViewDragTestBase, - public testing::WithParamInterface<std::tuple<bool, bool>> { + public testing::WithParamInterface<bool> { public: - AppsGridViewFolderIconRefreshTest() { - is_rtl_ = std::get<0>(GetParam()); - folder_icon_refresh_ = std::get<1>(GetParam()); - } + AppsGridViewFolderIconRefreshTest() { is_rtl_ = GetParam(); } }; -INSTANTIATE_TEST_SUITE_P(All, +INSTANTIATE_TEST_SUITE_P(Rtl, AppsGridViewFolderIconRefreshTest, - testing::Combine(testing::Bool(), testing::Bool())); + testing::Bool()); // Tests for legacy behaviour using the old drag and drop code. class AppsGridViewDragLegacyTest : public AppsGridViewDragTestBase, @@ -1854,14 +1846,7 @@ auto* background_layer = folder_view->icon_background_layer_for_test(); // The icon_background_layer is only created if the icon refresh is enabled. - if (folder_icon_refresh()) { - EXPECT_TRUE(background_layer); - } else { - EXPECT_FALSE(background_layer); - // Return early as the test below verifies the background layer that isn't - // available with legacy folder icons. - return; - } + EXPECT_TRUE(background_layer); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); @@ -1891,10 +1876,6 @@ } TEST_P(AppsGridViewFolderIconRefreshTest, FolderIconItemCounter) { - if (!folder_icon_refresh()) { - return; - } - GetTestModel()->CreateAndPopulateFolderWithApps(2); GetTestModel()->CreateAndPopulateFolderWithApps(4); GetTestModel()->CreateAndPopulateFolderWithApps(10); @@ -2615,8 +2596,7 @@ GetItemRectOnCurrentPageAt(0, 0).x()) / 2; gfx::Vector2d drag_vector( - -2 * half_tile_width - - GetAppListConfig()->folder_dropping_circle_radius() - 4, + -2 * half_tile_width - GetAppListConfig()->folder_bubble_radius() - 4, 0); // Flip drag vector in rtl. if (is_rtl_) {
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index d274438..fc405d1 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -1486,30 +1486,19 @@ return; } - if (features::IsAutocompleteExtendedSuggestionsEnabled()) { - ClearAutocompleteText(); + ClearAutocompleteText(); - const std::u16string& details = selected_result->details(); - const std::u16string& search_text = selected_result->title(); + const std::u16string& details = selected_result->details(); + const std::u16string& search_text = selected_result->title(); - // Don't set autocomplete text if it's the same as user typed text. - if (current_query_ == details || current_query_ == search_text) - return; + // Don't set autocomplete text if it's the same as user typed text. + if (current_query_ == details || current_query_ == search_text) { + return; + } - if (!ProcessPrefixMatchAutocomplete(selected_result, current_query_)) { - MaybeSetAutocompleteGhostText(selected_result->title(), - GetCategoryName(selected_result)); - } - } else { - if (selected_result->result_type() == AppListSearchResultType::kOmnibox && - !selected_result->is_omnibox_search() && - !selected_result->details().empty()) { - // For url (non-search) results, use details to ensure that the url is - // displayed. - search_box()->SetText(selected_result->details()); - } else { - search_box()->SetText(selected_result->title()); - } + if (!ProcessPrefixMatchAutocomplete(selected_result, current_query_)) { + MaybeSetAutocompleteGhostText(selected_result->title(), + GetCategoryName(selected_result)); } }
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index cf128fc..0794a6a 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -708,21 +708,11 @@ EXPECT_TRUE(view()->filter_button()->GetVisible()); } -class SearchBoxViewAutocompleteTest : public SearchBoxViewTest, - public testing::WithParamInterface<bool> { +class SearchBoxViewAutocompleteTest : public SearchBoxViewTest { public: SearchBoxViewAutocompleteTest() { scoped_feature_list_.Reset(); - scoped_feature_list_.InitWithFeatureStates({ - { - features::kAutocompleteExtendedSuggestions, - IsExtendedAutocompleteEnabled(), - }, - { - chromeos::features::kJelly, - true, - }, - }); + scoped_feature_list_.InitAndEnableFeature(chromeos::features::kJelly); } SearchBoxViewAutocompleteTest(const SearchBoxViewAutocompleteTest&) = delete; SearchBoxViewAutocompleteTest& operator=( @@ -733,8 +723,6 @@ view()->ProcessAutocomplete(GetFirstResultView()); } - bool IsExtendedAutocompleteEnabled() { return GetParam(); } - // Sets up the test by creating a SearchResult and displaying an autocomplete // suggestion. void SetupAutocompleteBehaviorTest() { @@ -750,15 +738,9 @@ } }; -// Instantiate the values in the parameterized tests. The boolean -// determines whether to run the test in tablet mode. -INSTANTIATE_TEST_SUITE_P(ExtendedAutocomplete, - SearchBoxViewAutocompleteTest, - testing::Bool()); - // Tests that autocomplete suggestions are consistent with top SearchResult list // titles. -TEST_P(SearchBoxViewAutocompleteTest, +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesTopListResultTitle) { SimulateQuery(u"he"); @@ -774,16 +756,14 @@ EXPECT_EQ(view()->search_box()->GetText(), u"hello list"); EXPECT_EQ(view()->search_box()->GetSelectedText(), u"llo list"); - if (IsExtendedAutocompleteEnabled()) { - EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); - KeyPress(ui::VKEY_DOWN); - EXPECT_EQ("Apps", view()->GetSearchBoxGhostTextForTest()); - } + EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); + KeyPress(ui::VKEY_DOWN); + EXPECT_EQ("Apps", view()->GetSearchBoxGhostTextForTest()); } // Tests that autocomplete suggestions are consistent with top SearchResult list // details. -TEST_P(SearchBoxViewAutocompleteTest, +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesTopListResultDetails) { SimulateQuery(u"he"); @@ -799,16 +779,14 @@ EXPECT_EQ(view()->search_box()->GetText(), u"hello list"); EXPECT_EQ(view()->search_box()->GetSelectedText(), u"llo list"); - if (IsExtendedAutocompleteEnabled()) { - EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); - KeyPress(ui::VKEY_DOWN); - EXPECT_EQ("Apps", view()->GetSearchBoxGhostTextForTest()); - } + EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); + KeyPress(ui::VKEY_DOWN); + EXPECT_EQ("Apps", view()->GetSearchBoxGhostTextForTest()); } // Tests that SearchBoxView's textfield text does not autocomplete if the top // result title or details do not have a matching prefix. -TEST_P(SearchBoxViewAutocompleteTest, +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxDoesNotAutocompleteWrongCharacter) { // Send ABC to the SearchBoxView textfield, then trigger an autocomplete. KeyPress(ui::VKEY_A); @@ -822,14 +800,12 @@ // The text should not be autocompleted. EXPECT_EQ(view()->search_box()->GetText(), u"abc"); - if (IsExtendedAutocompleteEnabled()) { - EXPECT_EQ("title - Websites", view()->GetSearchBoxGhostTextForTest()); - } + EXPECT_EQ("title - Websites", view()->GetSearchBoxGhostTextForTest()); } // Tests that autocomplete suggestion will remain if next key in the suggestion // is typed. -TEST_P(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesAcceptsNextChar) { +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesAcceptsNextChar) { SimulateQuery(u"he"); // Add a search result with a non-empty title field. CreateSearchResult(ash::SearchResultDisplayType::kList, 1.0, u"hello world!", @@ -849,13 +825,12 @@ EXPECT_EQ(view()->search_box()->GetText(), u"hello world!"); EXPECT_EQ(u"lo world!", selected_text); - if (IsExtendedAutocompleteEnabled()) - EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); + EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); } // Tests that autocomplete suggestion is accepted and displayed in SearchModel // after clicking or tapping on the search box. -TEST_P(SearchBoxViewAutocompleteTest, SearchBoxAcceptsAutocompleteForClick) { +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAcceptsAutocompleteForClick) { SetupAutocompleteBehaviorTest(); ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), @@ -872,11 +847,10 @@ EXPECT_EQ(u"hello world!", view()->search_box()->GetText()); EXPECT_EQ(u"he", view()->current_query()); - if (IsExtendedAutocompleteEnabled()) - EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); + EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); } -TEST_P(SearchBoxViewAutocompleteTest, SearchBoxAcceptsAutocompleteForTap) { +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAcceptsAutocompleteForTap) { SetupAutocompleteBehaviorTest(); ui::GestureEvent gesture_event(0, 0, 0, ui::EventTimeForNow(), @@ -893,12 +867,11 @@ // trigger another query, thus it is not reflected in Search Model. EXPECT_EQ(u"hello world!", view()->search_box()->GetText()); EXPECT_EQ(u"he", view()->current_query()); - if (IsExtendedAutocompleteEnabled()) - EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); + EXPECT_EQ("Websites", view()->GetSearchBoxGhostTextForTest()); } // Tests that autocomplete is not handled if IME is using composition text. -TEST_P(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesNotHandledForIME) { +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesNotHandledForIME) { // Simulate uncomposited text. The autocomplete should be handled. KeyPress(ui::VKEY_H); KeyPress(ui::VKEY_E); @@ -926,8 +899,7 @@ EXPECT_EQ(view()->search_box()->GetText(), u"he"); EXPECT_EQ(u"", selected_text); - if (IsExtendedAutocompleteEnabled()) - EXPECT_EQ("", view()->GetSearchBoxGhostTextForTest()); + EXPECT_EQ("", view()->GetSearchBoxGhostTextForTest()); } // TODO(crbug.com/1216082): Refactor the above tests to use AshTestBase.
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index 3926dd9..223029e8 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -1080,8 +1080,7 @@ keyboard_shortcut_container_->RemoveAllChildViews(); keyboard_shortcut_container_tags_.clear(); - if (!app_list_features::IsSearchResultInlineIconEnabled() || !result() || - result()->keyboard_shortcut_text_vector().empty()) { + if (!result() || result()->keyboard_shortcut_text_vector().empty()) { keyboard_shortcut_container_->SetVisible(false); has_keyboard_shortcut_contents_ = false; // Reset `title_and_details_container_` orientation. @@ -1448,9 +1447,7 @@ UpdateBigTitleContainer(); UpdateBigTitleSuperscriptContainer(); } - if (app_list_features::IsSearchResultInlineIconEnabled()) { - UpdateKeyboardShortcutContainer(); - } + UpdateKeyboardShortcutContainer(); UpdateTitleContainer(); UpdateProgressBarContainer(); UpdateDetailsContainer();
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 35b175c7..5c83846d 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -7083,8 +7083,11 @@ <message name="IDS_ASH_GAME_DASHBOARD_HELP_TOOLTIP" translateable="false" desc="Tooltip for the Game Dashboard help icon button."> Help center </message> - <message name="IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE" desc="The title of the main Game Dashboard button."> - Game Dashboard + <message name="IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_RECORDING" desc="The title of the Game Dashboard button when the window is being recorded, and also shows the recording duration."> + <ph name="DURATION">$1<ex>00:00</ex></ph>  Recording + </message> + <message name="IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE" desc="The default title of the Game Dashboard button."> + Game dashboard </message> <message name="IDS_ASH_GAME_DASHBOARD_HIDDEN_STATUS" translateable="false" desc="The hidden state for compact Game Dashboard tile sub-labels."> Hidden
diff --git a/ash/ash_strings_grd/IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_RECORDING.png.sha1 b/ash/ash_strings_grd/IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_RECORDING.png.sha1 new file mode 100644 index 0000000..b8b0b8f --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_RECORDING.png.sha1
@@ -0,0 +1 @@ +f2c0634c74b7ba723ca89c982215138c0f531eaa \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE.png.sha1 index 5f77646..89045aef 100644 --- a/ash/ash_strings_grd/IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE.png.sha1 +++ b/ash/ash_strings_grd/IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE.png.sha1
@@ -1 +1 @@ -a3687baed80e7c5db6fb27eced97143e808d182b \ No newline at end of file +91a7c8d80714026aafacb5089da88a08df4fb248 \ No newline at end of file
diff --git a/ash/bubble/bubble_event_filter.cc b/ash/bubble/bubble_event_filter.cc new file mode 100644 index 0000000..8fbd4a0 --- /dev/null +++ b/ash/bubble/bubble_event_filter.cc
@@ -0,0 +1,90 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/bubble/bubble_event_filter.h" + +#include "ash/bubble/bubble_utils.h" +#include "ash/shelf/shelf.h" +#include "ash/shell.h" +#include "ash/wm/container_finder.h" +#include "base/functional/callback.h" +#include "ui/events/event.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/views/widget/widget.h" + +namespace ash { + +BubbleEventFilter::BubbleEventFilter(views::Widget* bubble_widget, + views::View* button, + base::RepeatingClosure on_click_outside) + : bubble_widget_(bubble_widget), + button_(button), + on_click_outside_(on_click_outside) { + Shell::Get()->AddPreTargetHandler(this); +} + +BubbleEventFilter::~BubbleEventFilter() { + Shell::Get()->RemovePreTargetHandler(this); +} + +void BubbleEventFilter::SetButton(views::View* button) { + button_ = button; +} + +void BubbleEventFilter::OnMouseEvent(ui::MouseEvent* event) { + if (event->type() == ui::ET_MOUSE_PRESSED) { + ProcessPressedEvent(*event); + } +} + +void BubbleEventFilter::OnTouchEvent(ui::TouchEvent* event) { + if (event->type() == ui::ET_TOUCH_PRESSED) { + ProcessPressedEvent(*event); + } +} + +bool BubbleEventFilter::ShouldRunOnClickOutsideCallback( + const ui::LocatedEvent& event) { + if (!bubble_widget_) { + return false; + } + + // Check the general rules for closing bubbles. + if (!bubble_utils::ShouldCloseBubbleForEvent(event)) { + return false; + } + + gfx::Point event_location = event.target() + ? event.target()->GetScreenLocation(event) + : event.root_location(); + // Ignore clicks inside the bubble widget. + if (bubble_widget_->GetWindowBoundsInScreen().Contains(event_location)) { + return false; + } + + // Ignore clicks that hit the button (which usually spawned the widget). + // Note that we need to use `HitTestPoint()` because certain button (i.e. the + // shelf home button) have a custom view targeter that extends its hit test + // bounds beyond the button bounds, so when deciding whether or not to close + // the bubble we need to do a real hit test against the button, not just check + // if the click point is inside its bounds. + if (button_) { + gfx::Point point_in_button = event_location; + views::View::ConvertPointFromScreen(button_, &point_in_button); + if (button_->HitTestPoint(point_in_button)) { + return false; + } + } + + return true; +} + +void BubbleEventFilter::ProcessPressedEvent(const ui::LocatedEvent& event) { + if (ShouldRunOnClickOutsideCallback(event)) { + on_click_outside_.Run(); + } +} + +} // namespace ash
diff --git a/ash/bubble/bubble_event_filter.h b/ash/bubble/bubble_event_filter.h new file mode 100644 index 0000000..23663f9 --- /dev/null +++ b/ash/bubble/bubble_event_filter.h
@@ -0,0 +1,62 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_BUBBLE_BUBBLE_EVENT_FILTER_H_ +#define ASH_BUBBLE_BUBBLE_EVENT_FILTER_H_ + +#include "ash/ash_export.h" +#include "base/functional/callback.h" +#include "base/memory/raw_ptr.h" +#include "ui/events/event_handler.h" + +namespace ui { +class LocatedEvent; +} // namespace ui + +namespace views { +class View; +class Widget; +} // namespace views + +namespace ash { + +// Observes mouse and touch events and invokes a callback when +// `ShouldRunOnClickOutsideCallback()` is satisfied. For example, this class +// can be used to close the bubble according to an appropriate event. +class ASH_EXPORT BubbleEventFilter : public ui::EventHandler { + public: + // See class comment. Runs `on_click_outside` when a click or tap occurs + // outside the bounds of `bubble_widget` and `button`. + BubbleEventFilter(views::Widget* bubble_widget, + views::View* button, + base::RepeatingClosure on_click_outside); + BubbleEventFilter(const BubbleEventFilter&) = delete; + BubbleEventFilter& operator=(const BubbleEventFilter&) = delete; + ~BubbleEventFilter() override; + + // Changes the button to be checked in `ShouldRunOnClickOutsideCallback()`. + // This will be used for the app list bubble where the app list has changed + // displays, so a different home button needs to be checked. + void SetButton(views::View* button); + + // ui::EventHandler: + void OnMouseEvent(ui::MouseEvent* event) override; + void OnTouchEvent(ui::TouchEvent* event) override; + + protected: + // Checks whether we should run `on_click_outside_` or not. + virtual bool ShouldRunOnClickOutsideCallback(const ui::LocatedEvent& event); + + void ProcessPressedEvent(const ui::LocatedEvent& event); + + private: + const raw_ptr<views::Widget> bubble_widget_; + raw_ptr<views::View, DanglingUntriaged | ExperimentalAsh> + button_; // May be null. + base::RepeatingClosure on_click_outside_; +}; + +} // namespace ash + +#endif // ASH_BUBBLE_BUBBLE_EVENT_FILTER_H_
diff --git a/ash/bubble/bubble_event_filter_unittest.cc b/ash/bubble/bubble_event_filter_unittest.cc new file mode 100644 index 0000000..775bf58 --- /dev/null +++ b/ash/bubble/bubble_event_filter_unittest.cc
@@ -0,0 +1,98 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/bubble/bubble_event_filter.h" + +#include <memory> + +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/test/test_widget_builder.h" +#include "base/memory/raw_ptr.h" +#include "base/test/bind.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash { + +// Parameterized by mouse events vs. touch events. +class BubbleEventFilterTest : public AshTestBase, + public testing::WithParamInterface<bool> { + public: + BubbleEventFilterTest() = default; + BubbleEventFilterTest(const BubbleEventFilterTest&) = delete; + BubbleEventFilterTest& operator=(const BubbleEventFilterTest&) = delete; + ~BubbleEventFilterTest() override = default; + + // testing::Test: + void SetUp() override { + AshTestBase::SetUp(); + widget_ = TestWidgetBuilder() + .SetBounds({10, 10, 100, 100}) + .SetShow(true) + .BuildOwnsNativeWidget(); + // Create a separate Widget to host the View. A View must live in a Widget + // to have valid screen coordinates. + view_holder_widget_ = TestWidgetBuilder() + .SetBounds({500, 500, 100, 100}) + .SetShow(true) + .BuildOwnsNativeWidget(); + view_ = view_holder_widget_->client_view()->AddChildView( + std::make_unique<views::View>()); + view_->SetBoundsRect({0, 0, 32, 32}); + } + + // Generates a click or a tap based on test parameterization. + void ClickOrTapAt(gfx::Point point_in_screen) { + auto* generator = GetEventGenerator(); + if (GetParam()) { + generator->MoveMouseTo(point_in_screen); + generator->ClickLeftButton(); + } else { + generator->GestureTapAt(point_in_screen); + } + } + + std::unique_ptr<views::Widget> widget_; + std::unique_ptr<views::Widget> view_holder_widget_; + raw_ptr<views::View, ExperimentalAsh> view_ = nullptr; +}; + +INSTANTIATE_TEST_SUITE_P(MouseOrTouch, BubbleEventFilterTest, testing::Bool()); + +TEST_P(BubbleEventFilterTest, ClickOutsideWidgetRunsCallback) { + int callback_count = 0; + auto callback = base::BindLambdaForTesting([&]() { ++callback_count; }); + BubbleEventFilter filter(widget_.get(), view_, callback); + + // Click outside the widget. + gfx::Point point_outside_widget = widget_->GetWindowBoundsInScreen().origin(); + point_outside_widget.Offset(-1, -1); + ClickOrTapAt(point_outside_widget); + + EXPECT_EQ(callback_count, 1); +} + +TEST_P(BubbleEventFilterTest, ClickInsideWidgetDoesNotRunCallback) { + bool callback_ran = false; + auto callback = base::BindLambdaForTesting([&]() { callback_ran = true; }); + BubbleEventFilter filter(widget_.get(), view_, callback); + + // Click inside the widget. + ClickOrTapAt(widget_->GetWindowBoundsInScreen().CenterPoint()); + + EXPECT_FALSE(callback_ran); +} + +TEST_P(BubbleEventFilterTest, ClickInsideViewDoesNotRunCallback) { + bool callback_ran = false; + auto callback = base::BindLambdaForTesting([&]() { callback_ran = true; }); + BubbleEventFilter filter(widget_.get(), view_, callback); + + // Click inside the view. + ClickOrTapAt(view_->GetBoundsInScreen().CenterPoint()); + + EXPECT_FALSE(callback_ran); +} + +} // namespace ash
diff --git a/ash/capture_mode/capture_mode_game_dashboard_unittests.cc b/ash/capture_mode/capture_mode_game_dashboard_unittests.cc index 13394d45..92aff58 100644 --- a/ash/capture_mode/capture_mode_game_dashboard_unittests.cc +++ b/ash/capture_mode/capture_mode_game_dashboard_unittests.cc
@@ -19,6 +19,7 @@ #include "ash/display/window_tree_host_manager.h" #include "ash/game_dashboard/game_dashboard_context_test_api.h" #include "ash/game_dashboard/game_dashboard_controller.h" +#include "ash/game_dashboard/game_dashboard_widget.h" #include "ash/public/cpp/capture_mode/capture_mode_test_api.h" #include "ash/public/cpp/window_properties.h" #include "ash/screen_util.h"
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index c33a004d..70e9ee7 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -139,10 +139,6 @@ BASE_FEATURE(kApnRevamp, "ApnRevamp", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kAppCollectionFolderRefresh, - "AppCollectionFolderRefresh", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kAppLaunchAutomation, "AppLaunchAutomation", base::FEATURE_DISABLED_BY_DEFAULT); @@ -243,11 +239,6 @@ "AutoScreenBrightness", base::FEATURE_ENABLED_BY_DEFAULT); -// Enables or disables extended autocomplete results. -BASE_FEATURE(kAutocompleteExtendedSuggestions, - "AutocompleteExtendedSuggestions", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enables params tuning experiment for autocorrect on ChromeOS. BASE_FEATURE(kAutocorrectParamsTuning, "AutocorrectParamsTuning", @@ -2935,10 +2926,6 @@ return base::FeatureList::IsEnabled(kAudioHFPMicSRToggle); } -bool IsAutocompleteExtendedSuggestionsEnabled() { - return base::FeatureList::IsEnabled(kAutocompleteExtendedSuggestions); -} - bool IsAutoEnrollmentKioskInOobeEnabled() { return base::FeatureList::IsEnabled(kAutoEnrollmentKioskInOobe); } @@ -3011,10 +2998,6 @@ return base::FeatureList::IsEnabled(kOsSettingsAppNotificationsPage); } -bool IsAppCollectionFolderRefreshEnabled() { - return base::FeatureList::IsEnabled(kAppCollectionFolderRefresh); -} - bool IsArcFuseBoxFileSharingEnabled() { return base::FeatureList::IsEnabled(kArcFuseBoxFileSharing); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index ca1a13fe..f20d84c 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -43,8 +43,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAmbientModeManagedScreensaver); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kApnRevamp); -COMPONENT_EXPORT(ASH_CONSTANTS) -BASE_DECLARE_FEATURE(kAppCollectionFolderRefresh); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAppLaunchAutomation); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kArcAdbSideloadingFeature); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kArcFuseBoxFileSharing); @@ -69,8 +67,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAudioUrl); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutoNightLight); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutoScreenBrightness); -COMPONENT_EXPORT(ASH_CONSTANTS) -BASE_DECLARE_FEATURE(kAutocompleteExtendedSuggestions); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutocorrectParamsTuning); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutocorrectToggle); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutocorrectByDefault); @@ -835,7 +831,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool ArePromiseIconsForWebAppsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool AreSideAlignedToastsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool AreSystemSoundsEnabled(); -COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAutocompleteExtendedSuggestionsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAutoEnrollmentKioskInOobeEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool AreImprovedScreenCaptureSettingsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool Is16DesksEnabled(); @@ -855,7 +850,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAmbientModePhotoPreviewEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAmbientModeThrottleAnimationEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsApnRevampEnabled(); -COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAppCollectionFolderRefreshEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAppNotificationsPageEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsArcFuseBoxFileSharingEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsArcInputOverlayAlphaV2Enabled();
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index 2052c5b0..39f8858 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -402,6 +402,9 @@ const char kDisableHIDDetectionOnOOBEForTesting[] = "disable-hid-detection-on-oobe"; +// Skip multidevice setup screen during tast tests. +const char kSkipMultideviceScreenForTesting[] = "skip-multidevice-screen"; + // Disables the Lacros keep alive for testing. const char kDisableLacrosKeepAliveForTesting[] = "disable-lacros-keep-alive"; @@ -1133,6 +1136,11 @@ kEnableTabletFormFactor); } +bool ShouldMultideviceScreenBeSkippedForTesting() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + kSkipMultideviceScreenForTesting); +} + bool IsGaiaServicesDisabled() { return base::CommandLine::ForCurrentProcess()->HasSwitch( kDisableGaiaServices);
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index af299b6..95e8518 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -132,6 +132,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDisableHIDDetectionOnOOBEForTesting[]; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const char kSkipMultideviceScreenForTesting[]; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDisableLacrosKeepAliveForTesting[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDisableLoginAnimations[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDisableLoginLacrosOpening[]; @@ -397,6 +399,10 @@ // Returns true if GAIA services has been disabled. COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGaiaServicesDisabled(); +// Returns true if we should skip MultideviceSetup screen. +COMPONENT_EXPORT(ASH_CONSTANTS) +bool ShouldMultideviceScreenBeSkippedForTesting(); + // Returns true if |kDisableArcCpuRestriction| is true. COMPONENT_EXPORT(ASH_CONSTANTS) bool IsArcCpuRestrictionDisabled();
diff --git a/ash/game_dashboard/game_dashboard_button.cc b/ash/game_dashboard/game_dashboard_button.cc new file mode 100644 index 0000000..7d445fc --- /dev/null +++ b/ash/game_dashboard/game_dashboard_button.cc
@@ -0,0 +1,151 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/game_dashboard/game_dashboard_button.h" + +#include <memory> +#include <string> + +#include "ash/bubble/bubble_utils.h" +#include "ash/game_dashboard/game_dashboard_context.h" +#include "ash/resources/vector_icons/vector_icons.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/style/rounded_container.h" +#include "ash/style/typography.h" +#include "base/check.h" +#include "chromeos/strings/grit/chromeos_strings.h" +#include "chromeos/ui/frame/frame_header.h" +#include "chromeos/ui/vector_icons/vector_icons.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/compositor/layer.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/gfx/geometry/rounded_corners_f.h" +#include "ui/gfx/vector_icon_types.h" +#include "ui/views/background.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/box_layout_view.h" +#include "ui/views/view.h" +#include "ui/views/view_class_properties.h" +#include "ui/views/widget/widget.h" + +namespace ash { + +namespace { + +constexpr int kIconHeight = 20; +constexpr gfx::RoundedCornersF kRoundedCornerRadius = + gfx::RoundedCornersF(12.0f); +constexpr gfx::Insets kButtonBorderInsets = gfx::Insets::TLBR(0, 12, 0, 8); +constexpr gfx::Insets kGamepadIconMargins = gfx::Insets::TLBR(0, 0, 0, 8); +constexpr gfx::Insets kDropdownArrowMargins = gfx::Insets::TLBR(0, 6, 0, 0); + +} // namespace + +GameDashboardButton::GameDashboardButton(PressedCallback callback) + : views::Button(callback) { + auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>()); + layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); + layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); + + SetBorder(views::CreateEmptyBorder(kButtonBorderInsets)); + SetPaintToLayer(); + layer()->SetRoundedCornerRadius(kRoundedCornerRadius); + layer()->SetFillsBoundsOpaquely(false); + + // Add the gamepad icon view. + gamepad_icon_view_ = AddChildView(std::make_unique<views::ImageView>()); + gamepad_icon_view_->SetProperty(views::kMarginsKey, kGamepadIconMargins); + + // Add the title view. + title_view_ = AddChildView( + bubble_utils::CreateLabel(ash::TypographyToken::kCrosButton2)); + + // Add the dropdown icon view. + dropdown_icon_view_ = AddChildView(std::make_unique<views::ImageView>()); + dropdown_icon_view_->SetProperty(views::kMarginsKey, kDropdownArrowMargins); + + UpdateViews(); +} + +GameDashboardButton::~GameDashboardButton() = default; + +void GameDashboardButton::SetToggled(bool toggled) { + if (toggled == toggled_) { + return; + } + toggled_ = toggled; + UpdateDropDownArrow(); +} + +void GameDashboardButton::OnRecordingStarted() { + CHECK(!is_recording_); + is_recording_ = true; + UpdateViews(); +} + +void GameDashboardButton::OnRecordingEnded() { + if (!is_recording_) { + return; + } + is_recording_ = false; + UpdateViews(); +} + +void GameDashboardButton::UpdateRecordingDuration( + const std::u16string& duration) { + DCHECK(title_view_); + SetTitle(l10n_util::GetStringFUTF16( + IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_RECORDING, duration)); +} + +void GameDashboardButton::ChildPreferredSizeChanged(views::View* child) { + PreferredSizeChanged(); +} + +void GameDashboardButton::UpdateDropDownArrow() { + DCHECK(dropdown_icon_view_); + const gfx::VectorIcon& dropdown_icon = + toggled_ ? kGdDropUpArrowIcon : kGdDropDownArrowIcon; + const auto icon_color = is_recording_ + ? cros_tokens::kCrosSysSystemOnNegativeContainer + : cros_tokens::kCrosSysOnPrimaryContainer; + dropdown_icon_view_->SetImage( + ui::ImageModel::FromVectorIcon(dropdown_icon, icon_color, kIconHeight)); +} + +void GameDashboardButton::UpdateViews() { + ui::ColorId container_color; + ui::ColorId icon_and_label_color; + if (is_recording_) { + container_color = cros_tokens::kCrosSysSystemNegativeContainer; + icon_and_label_color = cros_tokens::kCrosSysSystemOnNegativeContainer; + // Don't update `title_view_` because it will be updated by + // `UpdateRecordingDuration()`. + } else { + container_color = cros_tokens::kCrosSysHighlightShape; + icon_and_label_color = cros_tokens::kCrosSysOnPrimaryContainer; + SetTitle(l10n_util::GetStringUTF16( + IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE)); + } + + SetBackground(views::CreateThemedSolidBackground(container_color)); + gamepad_icon_view_->SetImage(ui::ImageModel::FromVectorIcon( + chromeos::kGameDashboardGamepadIcon, icon_and_label_color, kIconHeight)); + title_view_->SetEnabledColorId(icon_and_label_color); + UpdateDropDownArrow(); +} + +void GameDashboardButton::SetTitle(const std::u16string& title_text) { + SetTooltipText(title_text); + title_view_->SetText(title_text); +} + +BEGIN_METADATA(GameDashboardButton, views::Button) +END_METADATA + +} // namespace ash
diff --git a/ash/game_dashboard/game_dashboard_button.h b/ash/game_dashboard/game_dashboard_button.h new file mode 100644 index 0000000..e037dac6 --- /dev/null +++ b/ash/game_dashboard/game_dashboard_button.h
@@ -0,0 +1,106 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_H_ +#define ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_H_ + +#include "base/memory/raw_ptr.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/controls/button/button.h" + +namespace views { +class ImageView; +class Label; +class View; +} // namespace views + +namespace ash { + +// The main button for the Game Dashboard, which acts as an entry point for +// features in GameDashboardMainMenuView. +// +// The button looks like: +// +-----------+-------+-----------+ +// | icon_view | label | icon_view | +// +-----------+-------+-----------+ +// +// There are 2 states: Default and Recording +// +// The 'Default' button indicates an idle Game Dashboard menu. Clicking on +// the button will toggle the `GameDashboardMainMenuView`, where the Recording +// Game tile is in the default state. +// +// The 'Recording' button state indicates that the game window is being +// recorded, which is shown after a user has initiated a game window recording. +// The label view is updated to show a count up timer, representing the +// duration, and "Recording" as its status. Clicking on the button will toggle +// the `GameDashboardMainMenuView`, where the Recording Game tile allows the +// user to stop the recording. +// +// The first "icon_view" always shows the gamepad icon. +// The second "icon_view" shows a dropdown arrow. Calling `SetToggled()` with +// true will replace the second "icon_view" with an the up arrow. Called with +// false, it will show the down arrow. +class GameDashboardButton : public views::Button { + public: + METADATA_HEADER(GameDashboardButton); + + explicit GameDashboardButton(PressedCallback callback); + GameDashboardButton(const GameDashboardButton&) = delete; + GameDashboardButton& operator=(const GameDashboardButton&) = delete; + ~GameDashboardButton() override; + + bool is_recording() const { return is_recording_; } + + bool toggled() const { return toggled_; } + + // Updates the `toggled_` state of the button. + void SetToggled(bool toggled); + + // Called when the game window recording has started. + void OnRecordingStarted(); + + // Called when the game window recording has ended. + void OnRecordingEnded(); + + // Updates `title_view_`'s text with `duration`. + void UpdateRecordingDuration(const std::u16string& duration); + + // views::View: + void ChildPreferredSizeChanged(views::View* child) override; + + private: + friend class GameDashboardContextTestApi; + + // Updates the `dropdown_icon_view_` icon. If `toggled_` is true, it'll show + // the up arrow, otherwise the down arrow. + void UpdateDropDownArrow(); + + // Updates `is_recording_` with `is_recording`, then updates all the views. + void UpdateRecordingState(bool is_recording); + + // Updates all the views in the button. If `is_recording_` is true, the + // UI is updated to show the 'Recording' button, indicating that there's an + // active video recording session. Otherwise, it will show the 'Default' + // button. + void UpdateViews(); + + // Sets the `title_view` and the tooltip text to `title_text`. + void SetTitle(const std::u16string& title_text); + + // Owned by views hierarchy. + raw_ptr<views::ImageView, ExperimentalAsh> gamepad_icon_view_; + raw_ptr<views::Label, ExperimentalAsh> title_view_; + raw_ptr<views::ImageView, ExperimentalAsh> dropdown_icon_view_; + + // If true, the game window is being recorded, otherwise false. + bool is_recording_ = false; + + // The button toggle state. + bool toggled_ = false; +}; + +} // namespace ash + +#endif // ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_H_
diff --git a/ash/game_dashboard/game_dashboard_context.cc b/ash/game_dashboard/game_dashboard_context.cc index 3143b93c..697742b 100644 --- a/ash/game_dashboard/game_dashboard_context.cc +++ b/ash/game_dashboard/game_dashboard_context.cc
@@ -7,15 +7,14 @@ #include <memory> #include <string> +#include "ash/game_dashboard/game_dashboard_button.h" #include "ash/game_dashboard/game_dashboard_main_menu_view.h" #include "ash/game_dashboard/game_dashboard_toolbar_view.h" -#include "ash/strings/grit/ash_strings.h" -#include "ash/style/pill_button.h" +#include "ash/game_dashboard/game_dashboard_widget.h" #include "base/i18n/time_formatting.h" -#include "base/timer/timer.h" #include "chromeos/ui/frame/frame_header.h" #include "ui/aura/window.h" -#include "ui/base/l10n/l10n_util.h" +#include "ui/base/l10n/time_format.h" #include "ui/compositor/layer.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/transform.h" @@ -74,6 +73,7 @@ } GameDashboardContext::~GameDashboardContext() { + game_dashboard_button_->RemoveObserver(this); if (main_menu_widget_) { main_menu_widget_->CloseNow(); } @@ -91,10 +91,7 @@ } void GameDashboardContext::SetGameDashboardButtonEnabled(bool enable) { - DCHECK(game_dashboard_button_widget_); - auto* contents_view = game_dashboard_button_widget_->GetContentsView(); - DCHECK(contents_view); - contents_view->SetEnabled(enable); + game_dashboard_button_->SetEnabled(enable); } void GameDashboardContext::ToggleMainMenu() { @@ -106,6 +103,7 @@ base::WrapUnique(views::BubbleDialogDelegateView::CreateBubble( std::move(widget_delegate))); main_menu_widget_->Show(); + game_dashboard_button_->SetToggled(true); } else { CloseMainMenu(); } @@ -116,6 +114,7 @@ DCHECK(main_menu_widget_.get()); main_menu_view_ = nullptr; main_menu_widget_.reset(); + game_dashboard_button_->SetToggled(false); } bool GameDashboardContext::ToggleToolbar() { @@ -155,11 +154,10 @@ void GameDashboardContext::OnRecordingStarted(bool is_recording_game_window) { if (is_recording_game_window) { - // TODO(b/273641154): Update the the Game Dashboard button to the recording - // state. CHECK(!recording_timer_.IsRunning()); DCHECK(recording_start_time_.is_null()); DCHECK(recording_duration_.empty()); + game_dashboard_button_->OnRecordingStarted(); recording_start_time_ = base::Time::Now(); OnUpdateRecordingTimer(); recording_timer_.Start(FROM_HERE, kCountUpTimerRefreshInterval, this, @@ -178,8 +176,7 @@ recording_timer_.Stop(); recording_start_time_ = base::Time(); recording_duration_.clear(); - // TODO(b/273641154): Update the the Game Dashboard button to the default - // state. + game_dashboard_button_->OnRecordingEnded(); if (main_menu_view_) { main_menu_view_->OnRecordingEnded(); } @@ -188,15 +185,21 @@ } } +void GameDashboardContext::OnViewPreferredSizeChanged( + views::View* observed_view) { + CHECK_EQ(game_dashboard_button_, observed_view); + UpdateGameDashboardButtonWidgetBounds(); +} + void GameDashboardContext::CreateAndAddGameDashboardButtonWidget() { + auto game_dashboard_button = std::make_unique<GameDashboardButton>( + base::BindRepeating(&GameDashboardContext::OnGameDashboardButtonPressed, + weak_ptr_factory_.GetWeakPtr())); + game_dashboard_button->AddObserver(this); + DCHECK(!game_dashboard_button_); + game_dashboard_button_ = game_dashboard_button.get(); game_dashboard_button_widget_ = CreateTransientChildWidget( - game_window_, "GameDashboardButton", - std::make_unique<PillButton>( - base::BindRepeating( - &GameDashboardContext::OnGameDashboardButtonPressed, - weak_ptr_factory_.GetWeakPtr()), - l10n_util::GetStringUTF16( - IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE))); + game_window_, "GameDashboardButton", std::move(game_dashboard_button)); DCHECK_EQ( game_window_, wm::GetTransientParent(game_dashboard_button_widget_->GetNativeWindow())); @@ -304,11 +307,8 @@ if (delta < base::Hours(1)) { base::ReplaceFirstSubstringAfterOffset(&duration, 0, u"0:", u""); } - recording_duration_ = duration; - - // TODO(b/273641154): Update the the Game Dashboard button with the recording - // duration. + game_dashboard_button_->UpdateRecordingDuration(duration); if (main_menu_view_) { main_menu_view_->UpdateRecordingDuration(duration); }
diff --git a/ash/game_dashboard/game_dashboard_context.h b/ash/game_dashboard/game_dashboard_context.h index 012bc41..8216e3b 100644 --- a/ash/game_dashboard/game_dashboard_context.h +++ b/ash/game_dashboard/game_dashboard_context.h
@@ -7,12 +7,12 @@ #include <memory> -#include "ash/game_dashboard/game_dashboard_widget.h" +#include "ash/ash_export.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" +#include "ui/views/view_observer.h" #include "ui/views/widget/unique_widget_ptr.h" -#include "ui/views/widget/widget.h" namespace aura { class Window; @@ -20,12 +20,14 @@ namespace ash { +class GameDashboardButton; class GameDashboardMainMenuView; class GameDashboardToolbarView; +class GameDashboardWidget; // This class manages Game Dashboard related UI for a given `aura::Window`, and // its instance is managed by the `GameDashboardController`. -class ASH_EXPORT GameDashboardContext { +class ASH_EXPORT GameDashboardContext : public views::ViewObserver { public: // Indicator for the 4 quadrants that the toolbar is able to be placed. enum class ToolbarSnapLocation { @@ -38,7 +40,7 @@ explicit GameDashboardContext(aura::Window* game_window); GameDashboardContext(const GameDashboardContext&) = delete; GameDashboardContext& operator=(const GameDashboardContext&) = delete; - ~GameDashboardContext(); + ~GameDashboardContext() override; aura::Window* game_window() { return game_window_.get(); } @@ -90,6 +92,9 @@ // if the recording session was aborted. void OnRecordingEnded(); + // views::ViewObserver: + void OnViewPreferredSizeChanged(views::View* observed_view) override; + private: friend class GameDashboardContextTestApi; @@ -101,8 +106,7 @@ // the `game_window_`. void UpdateGameDashboardButtonWidgetBounds(); - // Called when the button in the `game_dashboard_button_widget_` is pressed, - // and toggles the main menu. + // Called when `GameDashboardButton` is pressed, and toggles the main menu. void OnGameDashboardButtonPressed(); // Determines the toolbar's physical location on screen based on the @@ -131,8 +135,14 @@ // The indicator of the current corner that the toolbar is placed. ToolbarSnapLocation toolbar_snap_location_; + // The `GameDashboardButton` view in the `game_dashboard_button_widget_`. + // Owned by the views hierarchy. + raw_ptr<GameDashboardButton, ExperimentalAsh> game_dashboard_button_ = + nullptr; + // The `GameDashboardMainMenuView` when the user presses the Game Dashboard - // button. Owned by the views hierarchy. + // button. + // Owned by the views hierarchy. raw_ptr<GameDashboardMainMenuView, DanglingUntriaged | ExperimentalAsh> main_menu_view_ = nullptr;
diff --git a/ash/game_dashboard/game_dashboard_context_test_api.cc b/ash/game_dashboard/game_dashboard_context_test_api.cc index 7e8d28a8..57d95f4 100644 --- a/ash/game_dashboard/game_dashboard_context_test_api.cc +++ b/ash/game_dashboard/game_dashboard_context_test_api.cc
@@ -7,6 +7,7 @@ #include <string> #include "ash/capture_mode/capture_mode_test_util.h" +#include "ash/game_dashboard/game_dashboard_button.h" #include "ash/game_dashboard/game_dashboard_context.h" #include "ash/game_dashboard/game_dashboard_main_menu_view.h" #include "ash/game_dashboard/game_dashboard_toolbar_view.h" @@ -45,11 +46,15 @@ return context_->game_dashboard_button_widget(); } -PillButton* GameDashboardContextTestApi::GetGameDashboardButton() const { - auto* game_dashboard_button_widget = GetGameDashboardButtonWidget(); - CHECK(game_dashboard_button_widget); - return views::AsViewClass<PillButton>( - game_dashboard_button_widget->GetContentsView()); +GameDashboardButton* GameDashboardContextTestApi::GetGameDashboardButton() + const { + return context_->game_dashboard_button_; +} + +views::Label* GameDashboardContextTestApi::GetGameDashboardButtonTitle() const { + auto* game_dashboard_button = GetGameDashboardButton(); + CHECK(game_dashboard_button); + return game_dashboard_button->title_view_; } views::Widget* GameDashboardContextTestApi::GetMainMenuWidget() {
diff --git a/ash/game_dashboard/game_dashboard_context_test_api.h b/ash/game_dashboard/game_dashboard_context_test_api.h index bb5371c..6c22ea8 100644 --- a/ash/game_dashboard/game_dashboard_context_test_api.h +++ b/ash/game_dashboard/game_dashboard_context_test_api.h
@@ -20,6 +20,7 @@ namespace views { class Button; +class Label; class LabelButton; class View; class Widget; @@ -28,6 +29,7 @@ namespace ash { class FeatureTile; +class GameDashboardButton; class GameDashboardMainMenuView; class GameDashboardToolbarView; class GameDashboardWidget; @@ -49,9 +51,10 @@ const base::RepeatingTimer& GetRecordingTimer() const; const std::u16string& GetRecordingDuration() const; - // Returns the Game Dashboard button widget and button. + // Returns the Game Dashboard button widget, button, and title view. GameDashboardWidget* GetGameDashboardButtonWidget() const; - PillButton* GetGameDashboardButton() const; + GameDashboardButton* GetGameDashboardButton() const; + views::Label* GetGameDashboardButtonTitle() const; // Returns the main menu widget and all its views. views::Widget* GetMainMenuWidget();
diff --git a/ash/game_dashboard/game_dashboard_context_unittest.cc b/ash/game_dashboard/game_dashboard_context_unittest.cc index 13eb9b13..b1f6210 100644 --- a/ash/game_dashboard/game_dashboard_context_unittest.cc +++ b/ash/game_dashboard/game_dashboard_context_unittest.cc
@@ -5,11 +5,13 @@ #include "ash/game_dashboard/game_dashboard_context.h" #include <memory> +#include <string> #include "ash/capture_mode/capture_mode_controller.h" #include "ash/capture_mode/capture_mode_test_util.h" #include "ash/capture_mode/capture_mode_types.h" #include "ash/constants/ash_features.h" +#include "ash/game_dashboard/game_dashboard_button.h" #include "ash/game_dashboard/game_dashboard_context_test_api.h" #include "ash/game_dashboard/game_dashboard_controller.h" #include "ash/game_dashboard/game_dashboard_main_menu_view.h" @@ -22,6 +24,7 @@ #include "ash/public/cpp/style/dark_light_mode_controller.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" #include "ash/style/color_palette_controller.h" #include "ash/style/icon_button.h" #include "ash/style/mojom/color_scheme.mojom-shared.h" @@ -39,6 +42,7 @@ #include "extensions/common/constants.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/aura/window.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/events/keycodes/keyboard_codes_posix.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/views/controls/button/button.h" @@ -211,6 +215,31 @@ ToolbarSnapLocation::kTopLeft); } + // Verifies the Game Dashboard button is in the respective state for the given + // `test_api`. If `is_recording` is true, then the Game Dashboard button must + // be in the recording state, and the recording timer is running. Otherwise, + // it should be in the default state and the timer should not be running. + void VerifyGameDashboardButtonState(GameDashboardContextTestApi* test_api, + bool is_recording) { + EXPECT_EQ(is_recording, test_api->GetGameDashboardButton()->is_recording()); + + std::u16string expected_title; + if (is_recording) { + expected_title = l10n_util::GetStringFUTF16( + IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_RECORDING, + test_api->GetRecordingDuration()); + } else { + expected_title = l10n_util::GetStringUTF16( + IDS_ASH_GAME_DASHBOARD_GAME_DASHBOARD_BUTTON_TITLE); + } + EXPECT_EQ(expected_title, + test_api->GetGameDashboardButtonTitle()->GetText()); + } + + void VerifyGameDashboardButtonState(bool is_recording) { + VerifyGameDashboardButtonState(test_api_.get(), is_recording); + } + // Starts recording `recording_window_test_api`'s window, and verifies its // record game buttons are enabled and toggled on, while the record game // buttons in `other_window_test_api` are disabled and toggled off. @@ -242,6 +271,12 @@ EXPECT_FALSE(recording_window_timer.IsRunning()); EXPECT_FALSE(other_window_timer.IsRunning()); + // Verify the game dashboard buttons are not in the recording state. + VerifyGameDashboardButtonState(recording_window_test_api, + /*is_recording=*/false); + VerifyGameDashboardButtonState(other_window_test_api, + /*is_recording=*/false); + // Activate the recording_window. auto* recording_window = recording_window_test_api->context()->game_window(); @@ -260,6 +295,12 @@ EXPECT_TRUE(recording_window_timer.IsRunning()); EXPECT_FALSE(other_window_timer.IsRunning()); + // Verify the game dashboard button state. + VerifyGameDashboardButtonState(recording_window_test_api, + /*is_recording=*/true); + VerifyGameDashboardButtonState(other_window_test_api, + /*is_recording=*/false); + // Retrieve the record game buttons from both windows. auto* recording_window_record_game_tile = recording_window_test_api->GetMainMenuRecordGameTile(); @@ -310,6 +351,12 @@ EXPECT_FALSE(recording_window_timer.IsRunning()); EXPECT_FALSE(other_window_timer.IsRunning()); + // Verify the game dashboard buttons are no longer in the recording state. + VerifyGameDashboardButtonState(recording_window_test_api, + /*is_recording=*/false); + VerifyGameDashboardButtonState(other_window_test_api, + /*is_recording=*/false); + // Close the toolbar and main menu in both windows. for (auto* test_api : {recording_window_test_api, other_window_test_api}) { wm::ActivateWindow(test_api->context()->game_window()); @@ -750,6 +797,9 @@ test_api_->OpenTheMainMenu(); + // Verify the game dashboard button is initially not in the recording state. + VerifyGameDashboardButtonState(/*is_recording=*/false); + // Retrieve the record game tile from the main menu, and verify it's // enabled and toggled off. auto* main_menu_record_game_button = test_api_->GetMainMenuRecordGameTile(); @@ -777,6 +827,9 @@ EXPECT_FALSE(toolbar_record_game_button->GetEnabled()); EXPECT_FALSE(toolbar_record_game_button->toggled()); + // Verify the game dashboard button is not in the recording state. + VerifyGameDashboardButtonState(/*is_recording=*/false); + // Stop video recording. CaptureModeTestApi().StopVideoRecording(); EXPECT_FALSE(capture_mode_controller->is_recording_in_progress()); @@ -786,6 +839,9 @@ EXPECT_FALSE(main_menu_record_game_button->IsToggled()); EXPECT_TRUE(toolbar_record_game_button->GetEnabled()); EXPECT_FALSE(toolbar_record_game_button->toggled()); + + // Verify the game dashboard button is still in not in the recording state. + VerifyGameDashboardButtonState(/*is_recording=*/false); } // Verifies the toolbar opens and closes when the toolbar button in the main @@ -1206,6 +1262,7 @@ test_api_->OpenTheMainMenu(); EXPECT_FALSE(capture_mode_controller->is_recording_in_progress()); EXPECT_FALSE(timer.IsRunning()); + VerifyGameDashboardButtonState(/*is_recording=*/false); if (should_start_from_main_menu_) { // Retrieve the record game tile from the main menu. @@ -1229,6 +1286,7 @@ EXPECT_TRUE(capture_mode_controller->is_recording_in_progress()); EXPECT_TRUE(timer.IsRunning()); + VerifyGameDashboardButtonState(/*is_recording=*/true); if (should_stop_from_main_menu_) { // Stop the video recording from the main menu. @@ -1248,6 +1306,7 @@ } EXPECT_FALSE(capture_mode_controller->is_recording_in_progress()); EXPECT_FALSE(timer.IsRunning()); + VerifyGameDashboardButtonState(/*is_recording=*/false); WaitForCaptureFileToBeSaved(); }
diff --git a/ash/game_dashboard/game_dashboard_controller.cc b/ash/game_dashboard/game_dashboard_controller.cc index e7b8c57..87c369b 100644 --- a/ash/game_dashboard/game_dashboard_controller.cc +++ b/ash/game_dashboard/game_dashboard_controller.cc
@@ -11,6 +11,7 @@ #include "ash/capture_mode/capture_mode_controller.h" #include "ash/game_dashboard/game_dashboard_context.h" #include "ash/game_dashboard/game_dashboard_utils.h" +#include "ash/game_dashboard/game_dashboard_widget.h" #include "ash/public/cpp/app_types_util.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h"
diff --git a/ash/game_dashboard/game_dashboard_main_menu_view.cc b/ash/game_dashboard/game_dashboard_main_menu_view.cc index fd13555..abec768 100644 --- a/ash/game_dashboard/game_dashboard_main_menu_view.cc +++ b/ash/game_dashboard/game_dashboard_main_menu_view.cc
@@ -12,6 +12,7 @@ #include "ash/game_dashboard/game_dashboard_context.h" #include "ash/game_dashboard/game_dashboard_controller.h" #include "ash/game_dashboard/game_dashboard_utils.h" +#include "ash/game_dashboard/game_dashboard_widget.h" #include "ash/public/cpp/app_types_util.h" #include "ash/public/cpp/ash_view_ids.h" #include "ash/public/cpp/window_properties.h"
diff --git a/ash/login/ui/access_code_input.cc b/ash/login/ui/access_code_input.cc index dc0d5cc8..64bd7e66 100644 --- a/ash/login/ui/access_code_input.cc +++ b/ash/login/ui/access_code_input.cc
@@ -10,6 +10,7 @@ #include "ash/style/ash_color_id.h" #include "ash/style/system_textfield.h" #include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" #include "chromeos/constants/chromeos_features.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" @@ -421,6 +422,11 @@ if (key_code == ui::VKEY_TAB || key_code == ui::VKEY_BACKTAB) { // Allow using tab for keyboard navigation. return false; + } else if (key_code == ui::VKEY_PROCESSKEY) { + // Default handling for keyboard events that are not generated by physical + // key press. This can happen, for example, when virtual keyboard button + // is pressed. + return false; } else if (key_code >= ui::VKEY_0 && key_code <= ui::VKEY_9) { InsertDigit(key_code - ui::VKEY_0); } else if (key_code >= ui::VKEY_NUMPAD0 && key_code <= ui::VKEY_NUMPAD9) { @@ -447,6 +453,30 @@ return true; } +void FixedLengthCodeInput::ContentsChanged(views::Textfield* sender, + const std::u16string& new_contents) { + if (new_contents.empty()) { + return; + } + // Called when a character or text is inserted from the virtual keyboard. + if (new_contents.size() > 1) { + sender->SetText(std::u16string()); + return; + } + unsigned new_digit = 0; + // If a non-numeric character is inserted from the virtual keyboard, clear it. + if (!base::StringToUint(new_contents, &new_digit) || + !base::IsValueInRangeForNumericType<uint8_t>(new_digit)) { + sender->SetText(std::u16string()); + return; + } + bool was_last_field = IsLastFieldActive(); + ResetTextValueForA11y(); + FocusNextField(); + NotifyAccessibilityEvent(ax::mojom::Event::kTextSelectionChanged, true); + on_input_change_.Run(was_last_field, GetCode().has_value()); +} + bool FixedLengthCodeInput::HandleMouseEvent(views::Textfield* sender, const ui::MouseEvent& mouse_event) { if (!(mouse_event.IsOnlyLeftMouseButton() ||
diff --git a/ash/login/ui/access_code_input.h b/ash/login/ui/access_code_input.h index 28c81b2..90841d9 100644 --- a/ash/login/ui/access_code_input.h +++ b/ash/login/ui/access_code_input.h
@@ -219,6 +219,9 @@ bool HandleGestureEvent(views::Textfield* sender, const ui::GestureEvent& gesture_event) override; + void ContentsChanged(views::Textfield* sender, + const std::u16string& new_contents) override; + // Enables/disables entering a PIN. Currently, there is no use-case that uses // this with fixed length PINs. void SetInputEnabled(bool input_enabled) override;
diff --git a/ash/public/cpp/accelerators.cc b/ash/public/cpp/accelerators.cc index 8db1d46a..4c64020 100644 --- a/ash/public/cpp/accelerators.cc +++ b/ash/public/cpp/accelerators.cc
@@ -50,6 +50,8 @@ AcceleratorAction::kPrivacyScreenToggle}, {true, ui::VKEY_MICROPHONE_MUTE_TOGGLE, ui::EF_NONE, AcceleratorAction::kMicrophoneMuteToggle}, + {true, ui::VKEY_M, ui::EF_COMMAND_DOWN, + AcceleratorAction::kMicrophoneMuteToggle}, {true, ui::VKEY_KBD_BACKLIGHT_TOGGLE, ui::EF_NONE, AcceleratorAction::kKeyboardBacklightToggle}, {true, ui::VKEY_KBD_BRIGHTNESS_DOWN, ui::EF_NONE,
diff --git a/ash/public/cpp/ambient/common/ambient_settings.h b/ash/public/cpp/ambient/common/ambient_settings.h index a65b8b0d..ae9fdbc 100644 --- a/ash/public/cpp/ambient/common/ambient_settings.h +++ b/ash/public/cpp/ambient/common/ambient_settings.h
@@ -9,6 +9,7 @@ #include <vector> #include "ash/public/cpp/ash_public_export.h" +#include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h" namespace ash { @@ -21,20 +22,6 @@ ASH_PUBLIC_EXPORT extern const char kAmbientModeStreetArtAlbumId[]; ASH_PUBLIC_EXPORT extern const char kAmbientModeCapturedOnPixelAlbumId[]; -// Enumeration of the topic source, i.e. where the photos come from. -// Values need to stay in sync with the |TopicSource| in -// personalization_app.mojom. Art gallery is a super set of art related topic -// sources in Backdrop service. -// TODO(b/276349995): Deprecate this and use -// ash::personalization_app::mojom::TopicSource directly. -enum class AmbientModeTopicSource { - kMinValue = 0, - kGooglePhotos = kMinValue, - kArtGallery = 1, - kVideo = 2, - kMaxValue = kVideo -}; - // Subsettings of Art gallery. struct ASH_PUBLIC_EXPORT ArtSetting { ArtSetting(); @@ -80,7 +67,8 @@ AmbientSettings& operator=(AmbientSettings&&); ~AmbientSettings(); - AmbientModeTopicSource topic_source = AmbientModeTopicSource::kArtGallery; + personalization_app::mojom::TopicSource topic_source = + personalization_app::mojom::TopicSource::kArtGallery; // Only a subset Settings of Art gallery. std::vector<ArtSetting> art_settings;
diff --git a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc index 896c6b7b..47bfefd 100644 --- a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc +++ b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/ambient/ambient_backend_controller.h" #include "ash/public/cpp/ambient/common/ambient_settings.h" +#include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h" #include "base/check.h" #include "base/functional/bind.h" #include "base/functional/callback.h" @@ -22,8 +23,8 @@ namespace { -constexpr AmbientModeTopicSource kTopicSource = - AmbientModeTopicSource::kGooglePhotos; +constexpr personalization_app::mojom::TopicSource kTopicSource = + personalization_app::mojom::TopicSource::kGooglePhotos; constexpr AmbientModeTemperatureUnit kTemperatureUnit = AmbientModeTemperatureUnit::kCelsius;
diff --git a/ash/public/cpp/app_list/app_list_config.cc b/ash/public/cpp/app_list/app_list_config.cc index b86e54b..196cdc6 100644 --- a/ash/public/cpp/app_list/app_list_config.cc +++ b/ash/public/cpp/app_list/app_list_config.cc
@@ -154,7 +154,7 @@ } int ItemIconInFolderIconMargin() { - return features::IsAppCollectionFolderRefreshEnabled() ? 2 : 4; + return 2; } } // namespace @@ -208,8 +208,7 @@ icon_extended_background_radius_(IconExtendedBackgroundRadius(type)), item_icon_in_folder_icon_dimension_( ItemIconInFolderIconDimensionForType(type)), - item_icon_in_folder_icon_margin_(ItemIconInFolderIconMargin()), - folder_dropping_circle_radius_(folder_bubble_radius_) {} + item_icon_in_folder_icon_margin_(ItemIconInFolderIconMargin()) {} AppListConfig::AppListConfig(const AppListConfig& base_config, float scale_x) : type_(base_config.type_), @@ -241,9 +240,7 @@ item_icon_in_folder_icon_dimension_( Scale(base_config.item_icon_in_folder_icon_dimension_, scale_x)), item_icon_in_folder_icon_margin_( - Scale(base_config.item_icon_in_folder_icon_margin_, scale_x)), - folder_dropping_circle_radius_( - Scale(base_config.folder_dropping_circle_radius_, scale_x)) {} + Scale(base_config.item_icon_in_folder_icon_margin_, scale_x)) {} AppListConfig::~AppListConfig() = default;
diff --git a/ash/public/cpp/app_list/app_list_config.h b/ash/public/cpp/app_list/app_list_config.h index 4474bb2..7942415 100644 --- a/ash/public/cpp/app_list/app_list_config.h +++ b/ash/public/cpp/app_list/app_list_config.h
@@ -205,7 +205,6 @@ int unclipped_icon_dimension() const { return unclipped_icon_dimension_; } int folder_icon_radius() const { return folder_icon_radius_; } int icon_extended_background_radius() const { - DCHECK(features::IsAppCollectionFolderRefreshEnabled()); return icon_extended_background_radius_; } int item_icon_in_folder_icon_dimension() const { @@ -214,9 +213,6 @@ int item_icon_in_folder_icon_margin() const { return item_icon_in_folder_icon_margin_; } - int folder_dropping_circle_radius() const { - return folder_dropping_circle_radius_; - } gfx::Size grid_icon_size() const { return gfx::Size(grid_icon_dimension_, grid_icon_dimension_); @@ -230,15 +226,6 @@ return gfx::Size(unclipped_icon_dimension_, unclipped_icon_dimension_); } - gfx::Insets folder_icon_insets() const { - int folder_icon_dimension_diff = - unclipped_icon_dimension_ - icon_visible_dimension_; - return gfx::Insets::TLBR(folder_icon_dimension_diff / 2, - folder_icon_dimension_diff / 2, - (folder_icon_dimension_diff + 1) / 2, - (folder_icon_dimension_diff + 1) / 2); - } - gfx::Size item_icon_in_folder_icon_size() const { return gfx::Size(item_icon_in_folder_icon_dimension_, item_icon_in_folder_icon_dimension_); @@ -306,7 +293,6 @@ const int folder_icon_radius_; // The background corner radius of an item icon in extended state. - // Only used if app collection folder icon refresh is enabled. const int icon_extended_background_radius_; // The dimension of the item icon in folder icon. @@ -314,10 +300,6 @@ // The margin between item icons inside a folder icon. const int item_icon_in_folder_icon_margin_; - - // Radius of the circle, in which if entered, show folder dropping preview - // UI. - const int folder_dropping_circle_radius_; }; } // namespace ash
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc index 8a5149d..050d3de 100644 --- a/ash/public/cpp/app_list/app_list_features.cc +++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -23,9 +23,6 @@ BASE_FEATURE(kForceShowContinueSection, "ForceShowContinueSection", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kSearchResultInlineIcon, - "SearchResultInlineIcon", - base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kDynamicSearchUpdateAnimation, "DynamicSearchUpdateAnimation", base::FEATURE_ENABLED_BY_DEFAULT); @@ -48,11 +45,6 @@ return base::FeatureList::IsEnabled(kEnableAppListLaunchRecording); } -bool IsSearchResultInlineIconEnabled() { - // Inline Icons are only supported for categorical search. - return base::FeatureList::IsEnabled(kSearchResultInlineIcon); -} - bool IsDynamicSearchUpdateAnimationEnabled() { // Search update animations are only supported for categorical search. return base::FeatureList::IsEnabled(kDynamicSearchUpdateAnimation);
diff --git a/ash/public/cpp/app_list/app_list_features.h b/ash/public/cpp/app_list/app_list_features.h index 365e4be0..b486f74 100644 --- a/ash/public/cpp/app_list/app_list_features.h +++ b/ash/public/cpp/app_list/app_list_features.h
@@ -28,9 +28,6 @@ // suggestions. ASH_PUBLIC_EXPORT BASE_DECLARE_FEATURE(kForceShowContinueSection); -// Enables iconified text and inline icons in launcher search. -ASH_PUBLIC_EXPORT BASE_DECLARE_FEATURE(kSearchResultInlineIcon); - // Enable shortened search result update animations when in progress animations // are interrupted by search model updates. ASH_PUBLIC_EXPORT BASE_DECLARE_FEATURE(kDynamicSearchUpdateAnimation); @@ -47,7 +44,6 @@ ASH_PUBLIC_EXPORT bool IsForceShowContinueSectionEnabled(); ASH_PUBLIC_EXPORT bool IsAggregatedMlSearchRankingEnabled(); ASH_PUBLIC_EXPORT bool IsLauncherSearchNormalizationEnabled(); -ASH_PUBLIC_EXPORT bool IsSearchResultInlineIconEnabled(); ASH_PUBLIC_EXPORT bool IsDynamicSearchUpdateAnimationEnabled(); ASH_PUBLIC_EXPORT base::TimeDelta DynamicSearchUpdateAnimationDuration(); ASH_PUBLIC_EXPORT bool IsLauncherPlayStoreSearchEnabled();
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index 716fbf1..fe266cc 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -806,9 +806,6 @@ // A score to determine the result display order. double display_score = 0; - // Whether this is searched from Omnibox. - bool is_omnibox_search = false; - // Whether this result is a recommendation. bool is_recommendation = false;
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index e486ac4..ead47fa 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -116,6 +116,8 @@ "focus_mode_lamp.icon", "folder.icon", "four_files.icon", + "gd_drop_down_arrow.icon", + "gd_drop_up_arrow.icon", "gd_game_controls.icon", "gd_help.icon", "gd_record_game.icon",
diff --git a/ash/resources/vector_icons/gd_drop_down_arrow.icon b/ash/resources/vector_icons/gd_drop_down_arrow.icon new file mode 100644 index 0000000..e958810d --- /dev/null +++ b/ash/resources/vector_icons/gd_drop_down_arrow.icon
@@ -0,0 +1,10 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 6, 8, +LINE_TO, 10, 12, +LINE_TO, 14, 8, +H_LINE_TO, 6, +CLOSE
diff --git a/ash/resources/vector_icons/gd_drop_up_arrow.icon b/ash/resources/vector_icons/gd_drop_up_arrow.icon new file mode 100644 index 0000000..32395ee5 --- /dev/null +++ b/ash/resources/vector_icons/gd_drop_up_arrow.icon
@@ -0,0 +1,10 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 6, 12, +LINE_TO, 10, 8, +LINE_TO, 14, 12, +H_LINE_TO, 6, +CLOSE
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index 72ecb11..1405fb3 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -541,9 +541,6 @@ void SearchBoxViewBase::MaybeSetAutocompleteGhostText( const std::u16string& title, const std::u16string& category) { - if (!features::IsAutocompleteExtendedSuggestionsEnabled()) - return; - if (title.empty() && category.empty()) { ghost_text_container_->SetVisible(false); autocomplete_ghost_text_->SetText(std::u16string()); @@ -637,10 +634,8 @@ void SearchBoxViewBase::OnThemeChanged() { views::View::OnThemeChanged(); - if (features::IsAutocompleteExtendedSuggestionsEnabled()) { - search_box_->SetSelectionBackgroundColor( - GetWidget()->GetColorProvider()->GetColor(kColorAshFocusAuraColor)); - } + search_box_->SetSelectionBackgroundColor( + GetWidget()->GetColorProvider()->GetColor(kColorAshFocusAuraColor)); UpdatePlaceholderTextStyle(); }
diff --git a/ash/shelf/login_shelf_view_pixeltest.cc b/ash/shelf/login_shelf_view_pixeltest.cc index 89cb681d..842861cb 100644 --- a/ash/shelf/login_shelf_view_pixeltest.cc +++ b/ash/shelf/login_shelf_view_pixeltest.cc
@@ -150,7 +150,9 @@ // Verifies that focusing on the login shelf widget with a policy wallpaper // works as expected (see https://crbug.com/1197052). -TEST_P(LoginShelfWithPolicyWallpaperPixelTestWithRTL, FocusOnShutdownButton) { +// Test disabled due to flakiness b/293680827 +TEST_P(LoginShelfWithPolicyWallpaperPixelTestWithRTL, + DISABLED_FocusOnShutdownButton) { FocusOnShutdownButton(); EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( "focus_on_shutdown_button",
diff --git a/ash/system/holding_space/holding_space_view_delegate.cc b/ash/system/holding_space/holding_space_view_delegate.cc index d0d09708..f4bb7f84 100644 --- a/ash/system/holding_space/holding_space_view_delegate.cc +++ b/ash/system/holding_space/holding_space_view_delegate.cc
@@ -22,6 +22,7 @@ #include "base/containers/contains.h" #include "base/containers/cxx20_erase_vector.h" #include "base/functional/callback_helpers.h" +#include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" #include "net/base/mime_util.h" @@ -621,7 +622,7 @@ struct MenuItemModel { const HoldingSpaceCommandId command_id; const int label_id; - const gfx::VectorIcon& icon; + const raw_ref<const gfx::VectorIcon> icon; }; using MenuSectionModel = std::vector<MenuItemModel>; @@ -634,7 +635,7 @@ menu_sections.back().emplace_back( MenuItemModel{.command_id = in_progress_command.command_id, .label_id = in_progress_command.label_id, - .icon = *in_progress_command.icon}); + .icon = raw_ref(*in_progress_command.icon)}); } } @@ -648,7 +649,7 @@ menu_sections.back().emplace_back(MenuItemModel{ .command_id = HoldingSpaceCommandId::kShowInFolder, .label_id = IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_SHOW_IN_FOLDER, - .icon = kFolderIcon}); + .icon = raw_ref(kFolderIcon)}); std::string mime_type; const bool is_image = @@ -663,7 +664,7 @@ .command_id = HoldingSpaceCommandId::kCopyImageToClipboard, .label_id = IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_COPY_IMAGE_TO_CLIPBOARD, - .icon = kCopyIcon}); + .icon = raw_ref(kCopyIcon)}); } } @@ -672,12 +673,12 @@ menu_sections.back().emplace_back( MenuItemModel{.command_id = HoldingSpaceCommandId::kPinItem, .label_id = IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_PIN, - .icon = views::kPinIcon}); + .icon = raw_ref(views::kPinIcon)}); } else { menu_sections.back().emplace_back( MenuItemModel{.command_id = HoldingSpaceCommandId::kUnpinItem, .label_id = IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_UNPIN, - .icon = views::kUnpinIcon}); + .icon = raw_ref(views::kUnpinIcon)}); } } @@ -685,7 +686,7 @@ menu_sections.back().emplace_back( MenuItemModel{.command_id = HoldingSpaceCommandId::kRemoveItem, .label_id = IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_REMOVE, - .icon = kCancelCircleOutlineIcon}); + .icon = raw_ref(kCancelCircleOutlineIcon)}); } // Add modeled `menu_sections` to the `context_menu_model_`. @@ -704,7 +705,7 @@ context_menu_model_->AddItemWithIcon( static_cast<int>(menu_item.command_id), l10n_util::GetStringUTF16(menu_item.label_id), - ui::ImageModel::FromVectorIcon(menu_item.icon, + ui::ImageModel::FromVectorIcon(*menu_item.icon, ui::kColorAshSystemUIMenuIcon, kHoldingSpaceIconSize)); }
diff --git a/ash/system/tray/tray_event_filter.cc b/ash/system/tray/tray_event_filter.cc index 0db05f8..ca68c20 100644 --- a/ash/system/tray/tray_event_filter.cc +++ b/ash/system/tray/tray_event_filter.cc
@@ -4,7 +4,9 @@ #include "ash/system/tray/tray_event_filter.h" +#include "ash/bubble/bubble_event_filter.h" #include "ash/bubble/bubble_utils.h" +#include "ash/capture_mode/capture_mode_util.h" #include "ash/constants/ash_features.h" #include "ash/constants/tray_background_view_catalog.h" #include "ash/root_window_controller.h" @@ -19,6 +21,7 @@ #include "ash/system/unified/unified_system_tray.h" #include "ash/system/unified/unified_system_tray_bubble.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" +#include "base/functional/bind.h" #include "ui/aura/window.h" #include "ui/display/screen.h" #include "ui/views/widget/widget.h" @@ -28,27 +31,18 @@ TrayEventFilter::TrayEventFilter(views::Widget* bubble_widget, TrayBubbleView* bubble_view, TrayBackgroundView* tray_button) - : bubble_widget_(bubble_widget), + : BubbleEventFilter(bubble_widget, + tray_button, + base::BindRepeating( + [](TrayBackgroundView* tray_button) { + tray_button->ClickedOutsideBubble(); + }, + tray_button)), + bubble_widget_(bubble_widget), bubble_view_(bubble_view), - tray_button_(tray_button) { - Shell::Get()->AddPreTargetHandler(this); -} + tray_button_(tray_button) {} -TrayEventFilter::~TrayEventFilter() { - Shell::Get()->RemovePreTargetHandler(this); -} - -void TrayEventFilter::OnMouseEvent(ui::MouseEvent* event) { - if (event->type() == ui::ET_MOUSE_PRESSED) { - ProcessPressedEvent(*event); - } -} - -void TrayEventFilter::OnTouchEvent(ui::TouchEvent* event) { - if (event->type() == ui::ET_TOUCH_PRESSED) { - ProcessPressedEvent(*event); - } -} +TrayEventFilter::~TrayEventFilter() = default; void TrayEventFilter::OnGestureEvent(ui::GestureEvent* event) { if (event->type() != ui::ET_GESTURE_SCROLL_BEGIN) { @@ -59,103 +53,44 @@ event->target() ? event->target()->GetScreenLocation(*event) : event->root_location(); // If user is dragging on the tray button or - // `ShouldTriggerClickedOutsideBubble()` is satisfied, we should close the + // `ShouldRunOnClickOutsideCallback()` is satisfied, we should close the // bubble. if ((tray_button_->GetVisible() && tray_button_->GetBoundsInScreen().Contains(event_location)) || - ShouldTriggerClickedOutsideBubble(*event)) { + ShouldRunOnClickOutsideCallback(*event)) { tray_button_->ClickedOutsideBubble(); } } -bool TrayEventFilter::ShouldTriggerClickedOutsideBubble( +bool TrayEventFilter::ShouldRunOnClickOutsideCallback( const ui::LocatedEvent& event) { - if (!bubble_widget_ || !bubble_view_ || !tray_button_) { + if (!bubble_view_ || !tray_button_) { return false; } - if (!bubble_utils::ShouldCloseBubbleForEvent(event)) { + if (!BubbleEventFilter::ShouldRunOnClickOutsideCallback(event)) { return false; } - // Check the boundary for all bubbles, and do not handle the event if it - // happens inside of any of those bubbles. - const gfx::Point screen_location = + const gfx::Point event_location = event.target() ? event.target()->GetScreenLocation(event) : event.root_location(); - - gfx::Rect bounds = bubble_widget_->GetWindowBoundsInScreen(); - bounds.Inset(bubble_view_->GetBorderInsets()); - - int64_t display_id = display::Screen::GetScreen() - ->GetDisplayNearestPoint(screen_location) - .id(); + int64_t display_id = + display::Screen::GetScreen()->GetDisplayNearestPoint(event_location).id(); StatusAreaWidget* status_area = Shell::GetRootWindowControllerWithDisplayId(display_id) ->shelf() ->GetStatusAreaWidget(); - // When Quick Settings bubble is opened and the date tray is - // clicked, the bubble should not be closed since it will transition - // to show calendar. + // When Quick Settings bubble is opened and the date tray is clicked, the + // bubble should not be closed since it will transition to show calendar. if (tray_button_->catalog_name() == TrayBackgroundViewCatalogName::kUnifiedSystem && - status_area->date_tray()->GetBoundsInScreen().Contains(screen_location)) { - return false; - } - - UnifiedSystemTray* unified_system_tray = status_area->unified_system_tray(); - - // The system tray and message center are separate bubbles but they need to - // stay open together. We need to make sure to check if a click falls with in - // both their bounds and not close them both in this case. - if (!features::IsQsRevampEnabled() && - tray_button_->catalog_name() == - TrayBackgroundViewCatalogName::kUnifiedSystem) { - auto* system_tray_bubble = unified_system_tray->bubble(); - TrayBubbleBase* message_center_bubble = - unified_system_tray->message_center_bubble(); - CHECK(message_center_bubble); - if (bubble_widget_ == system_tray_bubble->GetBubbleWidget()) { - bounds.Union( - message_center_bubble->GetBubbleWidget()->GetWindowBoundsInScreen()); - } else { - CHECK_EQ(bubble_widget_, message_center_bubble->GetBubbleWidget()); - bounds.Union(system_tray_bubble->GetBoundsInScreen()); - } - } - - // If the bubble is anchored to the shelf corner, the notification - // popup will be shown on top of that bubble. In that case, we - // should not filter out the events happening on the popup - // notification. - if (features::IsNotifierCollisionEnabled() && - bubble_view_->IsAnchoredToShelfCorner() && - unified_system_tray->GetMessagePopupCollection() - ->popup_collection_bounds() - .Contains(screen_location)) { - return false; - } - - if (bounds.Contains(screen_location)) { - return false; - } - - // Maybe close the parent tray if the user drags on it. Otherwise, let the - // tray logic handle the event and determine show/hide behavior if the - // user clicks on the parent tray. - bounds = tray_button_->GetBoundsInScreen(); - if (tray_button_->GetVisible() && bounds.Contains(screen_location)) { + status_area->date_tray()->GetBoundsInScreen().Contains(event_location)) { return false; } return true; } -void TrayEventFilter::ProcessPressedEvent(const ui::LocatedEvent& event) { - if (ShouldTriggerClickedOutsideBubble(event)) { - tray_button_->ClickedOutsideBubble(); - } -} - } // namespace ash
diff --git a/ash/system/tray/tray_event_filter.h b/ash/system/tray/tray_event_filter.h index 1820ee2..e3decd6 100644 --- a/ash/system/tray/tray_event_filter.h +++ b/ash/system/tray/tray_event_filter.h
@@ -6,8 +6,9 @@ #define ASH_SYSTEM_TRAY_TRAY_EVENT_FILTER_H_ #include "ash/ash_export.h" +#include "ash/bubble/bubble_event_filter.h" #include "base/memory/raw_ptr.h" -#include "ui/events/event_handler.h" +#include "base/memory/weak_ptr.h" namespace ui { class LocatedEvent; @@ -22,9 +23,9 @@ class TrayBackgroundView; class TrayBubbleView; -// Handles events for a tray bubble, e.g. to close the system tray bubble when -// the user clicks outside it. -class ASH_EXPORT TrayEventFilter : public ui::EventHandler { +// Handles events for tray bubbles, closing the system tray bubble when the user +// clicks outside of it. +class ASH_EXPORT TrayEventFilter : public BubbleEventFilter { public: TrayEventFilter(views::Widget* bubble_widget, TrayBubbleView* bubble_view, @@ -35,21 +36,16 @@ ~TrayEventFilter() override; - // ui::EventHandler: - void OnMouseEvent(ui::MouseEvent* event) override; - void OnTouchEvent(ui::TouchEvent* event) override; + // BubbleEventFilter: void OnGestureEvent(ui::GestureEvent* event) override; + bool ShouldRunOnClickOutsideCallback(const ui::LocatedEvent& event) override; private: - // Evaluates whether the given `event` should cause the tray button to trigger - // `ClickedOutsideBubble()`. - bool ShouldTriggerClickedOutsideBubble(const ui::LocatedEvent& event); - - void ProcessPressedEvent(const ui::LocatedEvent& event); - const raw_ptr<views::Widget> bubble_widget_; const raw_ptr<TrayBubbleView> bubble_view_; const raw_ptr<TrayBackgroundView> tray_button_; + + base::WeakPtrFactory<TrayEventFilter> weak_factory_{this}; }; } // namespace ash
diff --git a/ash/system/tray/tray_event_filter_unittest.cc b/ash/system/tray/tray_event_filter_unittest.cc index 8e9efb4..eaffcaa3 100644 --- a/ash/system/tray/tray_event_filter_unittest.cc +++ b/ash/system/tray/tray_event_filter_unittest.cc
@@ -4,7 +4,6 @@ #include "ash/system/tray/tray_event_filter.h" -#include "ash/capture_mode/capture_mode_controller.h" #include "ash/constants/ash_features.h" #include "ash/ime/ime_controller_impl.h" #include "ash/root_window_controller.h" @@ -187,18 +186,10 @@ return GetPrimaryUnifiedSystemTray()->IsMessageCenterBubbleShown(); } - gfx::Rect GetQuickSettingsBubbleBounds() { - return GetPrimaryUnifiedSystemTray()->GetBubbleBoundsInScreen(); - } - UnifiedSystemTray* GetPrimaryUnifiedSystemTray() { return GetPrimaryShelf()->GetStatusAreaWidget()->unified_system_tray(); } - UnifiedMessageCenterBubble* GetMessageCenterBubble() { - return GetPrimaryUnifiedSystemTray()->message_center_bubble(); - } - void AnimatePopupAnimationUntilIdle() { AshMessagePopupCollection* popup_collection = GetPrimaryUnifiedSystemTray()->GetMessagePopupCollection(); @@ -223,72 +214,10 @@ TrayEventFilterTest, testing::Bool()); -TEST_P(TrayEventFilterTest, ClickOutsideBubble) { - ShowTestBubble(); - auto* bubble_widget = GetTestBubbleWidget(); - EXPECT_TRUE(bubble_widget); - - // Clicking outside the bubble should trigger `ClickedOutsideBubble()`. - ClickOutsideWidget(bubble_widget); - - EXPECT_TRUE(test_tray_background_view()->clicked_outside_bubble_called()); -} - -TEST_P(TrayEventFilterTest, ClickInsideBubble) { - ShowTestBubble(); - auto* bubble_widget = GetTestBubbleWidget(); - EXPECT_TRUE(bubble_widget); - - // Clicking inside the bubble should not trigger `ClickedOutsideBubble()`. - ClickInsideWidget(bubble_widget); - - EXPECT_FALSE(test_tray_background_view()->clicked_outside_bubble_called()); -} - -TEST_P(TrayEventFilterTest, ClickOnTray) { - auto* test_tray = test_tray_background_view(); - LeftClickOn(test_tray); - EXPECT_TRUE(test_tray->bubble()); - - // Clicking on the tray when bubble is open will not trigger - // `ClickedOutsideBubble()`, since this will be handled in the tray level. - LeftClickOn(test_tray); - EXPECT_FALSE(test_tray->clicked_outside_bubble_called()); -} - -TEST_P(TrayEventFilterTest, CaptureMode) { - ShowTestBubble(); - auto* bubble_widget = GetTestBubbleWidget(); - EXPECT_TRUE(bubble_widget); - - CaptureModeController::Get()->Start(CaptureModeEntryType::kQuickSettings); - - // Clicking outside of the bubble during capture mode should not trigger - // `ClickedOutsideBubble()`. - ClickOutsideWidget(bubble_widget); - EXPECT_FALSE(test_tray_background_view()->clicked_outside_bubble_called()); -} - -TEST_P(TrayEventFilterTest, ClickOnMenuContainer) { - // Create a menu window and place it in the menu container window. - std::unique_ptr<aura::Window> menu_window = CreateTestWindow(); - menu_window->set_owned_by_parent(false); - Shell::GetPrimaryRootWindowController() - ->GetContainer(kShellWindowId_MenuContainer) - ->AddChild(menu_window.get()); - - ShowTestBubble(); - EXPECT_TRUE(GetTestBubbleWidget()); - - // Clicking on the menu container should not trigger - // `ClickedOutsideBubble()`. - auto* event_generator = GetEventGenerator(); - event_generator->MoveMouseTo(menu_window->GetBoundsInScreen().CenterPoint()); - event_generator->ClickLeftButton(); - - EXPECT_FALSE(test_tray_background_view()->clicked_outside_bubble_called()); -} - +// Tests that clicking on notification popup when bubble is open will not result +// in the bubble closes. The logic for this is handled in +// `bubble_utils::ShouldCloseBubbleForEvent()` where we ignore events happen +// inside a `kShellWindowId_SettingBubbleContainer`. TEST_P(TrayEventFilterTest, ClickOnPopupWhenBubbleOpen) { // Update display so that the screen is height enough and expand/collapse // notification is allowed on top of the tray bubble. @@ -331,29 +260,6 @@ EXPECT_TRUE(IsQuickSettingsBubbleShown()); } -TEST_P(TrayEventFilterTest, ClickOnKeyboardContainer) { - // Simulate the virtual keyboard being open. In production the virtual - // keyboard container only exists while the keyboard is open. - std::unique_ptr<aura::Window> keyboard_container = - CreateTestWindow(gfx::Rect(), aura::client::WINDOW_TYPE_NORMAL, - kShellWindowId_VirtualKeyboardContainer); - std::unique_ptr<aura::Window> keyboard_window = CreateTestWindow(); - keyboard_window->set_owned_by_parent(false); - keyboard_container->AddChild(keyboard_window.get()); - - ShowTestBubble(); - EXPECT_TRUE(GetTestBubbleWidget()); - - // Clicking on the keyboard container should not trigger - // `ClickedOutsideBubble()`. - auto* event_generator = GetEventGenerator(); - event_generator->MoveMouseTo( - keyboard_window->GetBoundsInScreen().CenterPoint()); - event_generator->ClickLeftButton(); - - EXPECT_FALSE(test_tray_background_view()->clicked_outside_bubble_called()); -} - TEST_P(TrayEventFilterTest, DraggingInsideDoesNotCloseBubble) { ShowTestBubble(); auto* bubble_widget = GetTestBubbleWidget(); @@ -477,7 +383,7 @@ auto border_insets = GetPrimaryUnifiedSystemTray()->GetBubbleView()->GetBorderInsets(); event_generator->MoveMouseTo( - GetQuickSettingsBubbleBounds().origin() + + GetPrimaryUnifiedSystemTray()->GetBubbleBoundsInScreen().origin() + gfx::Vector2d(border_insets.left(), border_insets.top())); event_generator->ClickLeftButton(); @@ -485,7 +391,9 @@ EXPECT_TRUE(IsQuickSettingsBubbleShown()); // Clicking inside the message center bubble should not close either bubble. - ClickInsideWidget(GetMessageCenterBubble()->GetBubbleWidget()); + ClickInsideWidget(GetPrimaryUnifiedSystemTray() + ->message_center_bubble() + ->GetBubbleWidget()); EXPECT_TRUE(IsMessageCenterBubbleShown()); EXPECT_TRUE(IsQuickSettingsBubbleShown());
diff --git a/ash/webui/personalization_app/mojom/BUILD.gn b/ash/webui/personalization_app/mojom/BUILD.gn index 95229b6..3f9d3cd 100644 --- a/ash/webui/personalization_app/mojom/BUILD.gn +++ b/ash/webui/personalization_app/mojom/BUILD.gn
@@ -63,10 +63,6 @@ move_only = true }, { - mojom = "ash.personalization_app.mojom.TopicSource" - cpp = "::ash::AmbientModeTopicSource" - }, - { mojom = "ash.personalization_app.mojom.TemperatureUnit" cpp = "::ash::AmbientModeTemperatureUnit" },
diff --git a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc index fe0784d..61ee8b4 100644 --- a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc +++ b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.cc
@@ -30,7 +30,6 @@ using MojomWallpaperLayout = ash::personalization_app::mojom::WallpaperLayout; using MojomWallpaperType = ash::personalization_app::mojom::WallpaperType; using MojomOnlineImageType = ash::personalization_app::mojom::OnlineImageType; -using MojomTopicSource = ash::personalization_app::mojom::TopicSource; using MojomTemperatureUnit = ash::personalization_app::mojom::TemperatureUnit; using MojomAmbientUiVisibility = ash::personalization_app::mojom::AmbientUiVisibility; @@ -369,39 +368,6 @@ data.ReadSourceInfo(&out->source_info); } -// TODO (b/220933864): remove ash::AmbientModeTopicSource and -// ash::AmbientModeTemperatureUnit enums. -MojomTopicSource -EnumTraits<MojomTopicSource, ash::AmbientModeTopicSource>::ToMojom( - ash::AmbientModeTopicSource input) { - switch (input) { - case ash::AmbientModeTopicSource::kGooglePhotos: - return MojomTopicSource::kGooglePhotos; - case ash::AmbientModeTopicSource::kArtGallery: - return MojomTopicSource::kArtGallery; - case ash::AmbientModeTopicSource::kVideo: - return MojomTopicSource::kVideo; - } -} - -bool EnumTraits<MojomTopicSource, ash::AmbientModeTopicSource>::FromMojom( - MojomTopicSource input, - ash::AmbientModeTopicSource* output) { - switch (input) { - case MojomTopicSource::kGooglePhotos: - *output = ash::AmbientModeTopicSource::kGooglePhotos; - return true; - case MojomTopicSource::kArtGallery: - *output = ash::AmbientModeTopicSource::kArtGallery; - return true; - case MojomTopicSource::kVideo: - *output = ash::AmbientModeTopicSource::kVideo; - return true; - } - NOTREACHED(); - return false; -} - MojomTemperatureUnit EnumTraits<MojomTemperatureUnit, ash::AmbientModeTemperatureUnit>::ToMojom( ash::AmbientModeTemperatureUnit input) {
diff --git a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h index ff6c5ec..00449b2a3 100644 --- a/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h +++ b/ash/webui/personalization_app/mojom/personalization_app_mojom_traits.h
@@ -127,15 +127,6 @@ }; template <> -struct EnumTraits<ash::personalization_app::mojom::TopicSource, - ash::AmbientModeTopicSource> { - using MojomTopicSource = ::ash::personalization_app::mojom::TopicSource; - static MojomTopicSource ToMojom(ash::AmbientModeTopicSource input); - static bool FromMojom(MojomTopicSource input, - ash::AmbientModeTopicSource* output); -}; - -template <> struct EnumTraits<ash::personalization_app::mojom::TemperatureUnit, ash::AmbientModeTemperatureUnit> { using MojomTemperatureUnit =
diff --git a/ash/webui/personalization_app/resources/BUILD.gn b/ash/webui/personalization_app/resources/BUILD.gn index ff1312f..38afc236 100644 --- a/ash/webui/personalization_app/resources/BUILD.gn +++ b/ash/webui/personalization_app/resources/BUILD.gn
@@ -8,6 +8,12 @@ assert(is_chromeos_ash) +declare_args() { + # Whether or not the target board supports the time of day feature. Set in + # the chromeos-chrome ebuild file. + is_time_of_day_supported = true +} + build_webui("build") { grd_prefix = "ash_personalization_app" @@ -183,9 +189,7 @@ # Time of day assets cannot be made public until after the feature is # released. Thus, they are currently hosted in CIPD and downloaded to # this directory only if an internal chrome-branded checkout is being used. - # TODO(b/275379819): Create a custom GN arg like "tod_screensaver_enabled" and set it based - # on "feature_management" use flag in chromeos-chrome.ebuild. - if (is_chrome_branded) { + if (is_chrome_branded && is_time_of_day_supported) { static_files += [ "time_of_day/thumbnails/clouds.jpg", "time_of_day/thumbnails/new_mexico.jpg",
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_ambient_provider.h b/ash/webui/personalization_app/test/fake_personalization_app_ambient_provider.h index 8bf81c3..84741c77 100644 --- a/ash/webui/personalization_app/test/fake_personalization_app_ambient_provider.h +++ b/ash/webui/personalization_app/test/fake_personalization_app_ambient_provider.h
@@ -45,11 +45,11 @@ void SetAmbientModeEnabled(bool enabled) override {} void SetAmbientTheme(mojom::AmbientTheme ambient_theme) override {} void SetScreenSaverDuration(int) override {} - void SetTopicSource(ash::AmbientModeTopicSource topic_source) override {} + void SetTopicSource(mojom::TopicSource topic_source) override {} void SetTemperatureUnit( ash::AmbientModeTemperatureUnit temperature_unit) override {} void SetAlbumSelected(const std::string& id, - ash::AmbientModeTopicSource topic_source, + mojom::TopicSource topic_source, bool selected) override {} void SetPageViewed() override {} void StartScreenSaverPreview() override {}
diff --git a/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc b/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc index f2a98ff..7e15967 100644 --- a/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc +++ b/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc
@@ -47,7 +47,7 @@ MOCK_METHOD(void, SetScreenSaverDuration, (int minutes), (override)); MOCK_METHOD(void, SetTopicSource, - (ash::AmbientModeTopicSource topic_source), + (mojom::TopicSource topic_source), (override)); MOCK_METHOD(void, SetTemperatureUnit, @@ -56,7 +56,7 @@ MOCK_METHOD(void, SetAlbumSelected, (const std::string& id, - ash::AmbientModeTopicSource topic_source, + mojom::TopicSource topic_source, bool selected), (override)); MOCK_METHOD(void, SetPageViewed, (), (override));
diff --git a/ash/webui/scanning/resources/BUILD.gn b/ash/webui/scanning/resources/BUILD.gn index e8a909e..d0cba3a 100644 --- a/ash/webui/scanning/resources/BUILD.gn +++ b/ash/webui/scanning/resources/BUILD.gn
@@ -31,13 +31,13 @@ ] web_component_files = [ - "action_toolbar.js", + "action_toolbar.ts", "color_mode_select.js", "file_type_select.js", - "loading_page.js", + "loading_page.ts", "multi_page_checkbox.js", "multi_page_scan.js", - "page_size_select.js", + "page_size_select.ts", "resolution_select.js", "scan_done_section.js", "scanner_select.js", @@ -51,7 +51,7 @@ ] non_web_component_files = [ - "mojo_interface_provider.js", + "mojo_interface_provider.ts", "scanning_app_types.js", "scanning_app_util.js", "scanning_browser_proxy.js",
diff --git a/ash/webui/scanning/resources/action_toolbar.html b/ash/webui/scanning/resources/action_toolbar.html index 5308ff8..76e69e54 100644 --- a/ash/webui/scanning/resources/action_toolbar.html +++ b/ash/webui/scanning/resources/action_toolbar.html
@@ -55,13 +55,13 @@ } </style> <div id="actionToolbar"> - <div id="pageNumbers" aria-hidden="true">[[pageNumberText_]]</div> + <div id="pageNumbers" aria-hidden="true">[[pageNumberText]]</div> <div class="separator"></div> <div> - <cr-icon-button id="removePageIcon" on-click="onRemovePageIconClick_" + <cr-icon-button id="removePageIcon" on-click="onRemovePageIconClick" title="[[i18n('removePageButtonLabel')]]"> </cr-icon-button> - <cr-icon-button id="rescanPageIcon" on-click="onRescanPageIconClick_" + <cr-icon-button id="rescanPageIcon" on-click="onRescanPageIconClick" title="[[i18n('rescanPageButtonLabel')]]"> </cr-icon-button> </div>
diff --git a/ash/webui/scanning/resources/action_toolbar.js b/ash/webui/scanning/resources/action_toolbar.js deleted file mode 100644 index a2b752f..0000000 --- a/ash/webui/scanning/resources/action_toolbar.js +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import './scanning_shared_css.js'; -import './strings.m.js'; -import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; - -import {assert} from 'chrome://resources/ash/common/assert.js'; -import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/ash/common/i18n_behavior.js'; -import {mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {getTemplate} from './action_toolbar.html.js'; - -/** - * @fileoverview - * 'action-toolbar' is a floating toolbar that contains post-scan page options. - */ - -/** - * @constructor - * @extends {PolymerElement} - * @implements {I18nBehaviorInterface} - */ -const ActionToolbarElementBase = mixinBehaviors([I18nBehavior], PolymerElement); - -/** @polymer */ -class ActionToolbarElement extends ActionToolbarElementBase { - static get is() { - return 'action-toolbar'; - } - - static get template() { - return getTemplate(); - } - - static get properties() { - return { - /** @type {number} */ - pageIndex: Number, - - /** @type {number} */ - numTotalPages: Number, - - /** @private {string} */ - pageNumberText_: { - type: String, - computed: 'computePageNumberText_(pageIndex, numTotalPages)', - }, - }; - } - - /** - * @return {string} - * @private - */ - computePageNumberText_() { - if (!this.numTotalPages || this.pageIndex >= this.numTotalPages) { - return ''; - } - - assert(this.numTotalPages > 0); - // Add 1 to |pageIndex| to get the corresponding page number. - return this.i18n( - 'actionToolbarPageCountText', this.pageIndex + 1, this.numTotalPages); - } - - /** @private */ - onRemovePageIconClick_() { - this.dispatchEvent( - new CustomEvent('show-remove-page-dialog', {detail: this.pageIndex})); - } - - /** @private */ - onRescanPageIconClick_() { - this.dispatchEvent( - new CustomEvent('show-rescan-page-dialog', {detail: this.pageIndex})); - } -} - -customElements.define(ActionToolbarElement.is, ActionToolbarElement);
diff --git a/ash/webui/scanning/resources/action_toolbar.ts b/ash/webui/scanning/resources/action_toolbar.ts new file mode 100644 index 0000000..9c005cc --- /dev/null +++ b/ash/webui/scanning/resources/action_toolbar.ts
@@ -0,0 +1,81 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './scanning_shared_css.js'; +import './strings.m.js'; +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; + +import {assert} from 'chrome://resources/ash/common/assert.js'; +import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {getTemplate} from './action_toolbar.html.js'; + +/** + * @fileoverview + * 'action-toolbar' is a floating toolbar that contains post-scan page options. + */ + +const ActionToolbarElementBase = I18nMixin(PolymerElement); + +class ActionToolbarElement extends ActionToolbarElementBase { + static get is() { + return 'action-toolbar' as const; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + pageIndex: Number, + + numTotalPages: Number, + + pageNumberText: { + type: String, + computed: 'computePageNumberText(pageIndex, numTotalPages)', + }, + }; + } + + pageIndex: number = 0; + numTotalPages: number = 0; + private pageNumberText: string = ''; + + private computePageNumberText(): string { + if (!this.numTotalPages || this.pageIndex >= this.numTotalPages) { + return ''; + } + + assert(this.numTotalPages > 0); + // Add 1 to |pageIndex| to get the corresponding page number. + return this.i18n( + 'actionToolbarPageCountText', this.pageIndex + 1, this.numTotalPages); + } + + private onRemovePageIconClick(): void { + this.dispatchEvent(new CustomEvent<number>( + 'show-remove-page-dialog', {detail: this.pageIndex})); + } + + private onRescanPageIconClick(): void { + this.dispatchEvent(new CustomEvent<number>( + 'show-rescan-page-dialog', {detail: this.pageIndex})); + } +} + +declare global { + interface HTMLElementEventMap { + 'show-remove-page-dialog': CustomEvent<number>; + 'show-rescan-page-dialog': CustomEvent<number>; + } + + interface HTMLElementTagNameMap { + [ActionToolbarElement.is]: ActionToolbarElement; + } +} + +customElements.define(ActionToolbarElement.is, ActionToolbarElement);
diff --git a/ash/webui/scanning/resources/loading_page.html b/ash/webui/scanning/resources/loading_page.html index 8d5d9a7..5d4803a 100644 --- a/ash/webui/scanning/resources/loading_page.html +++ b/ash/webui/scanning/resources/loading_page.html
@@ -57,17 +57,17 @@ } </style> <iron-media-query query="(prefers-color-scheme: dark)" - query-matches="{{isDarkModeEnabled_}}"> + query-matches="{{isDarkModeEnabled}}"> </iron-media-query> <div id="loadingContainer"> - <div id="loadingDiv" hidden="[[noScannersAvailable_]]"> + <div id="loadingDiv" hidden="[[noScannersAvailable]]"> <!-- TODO(b/276493795): After the Jelly experiment is launched, remove used image elements and SVGs. --> - <template is="dom-if" if="[[!isJellyEnabled_]]"> - <img src$="[[getScannersLoadingSvgSrc_(isDarkModeEnabled_)]]" + <template is="dom-if" if="[[!isJellyEnabled]]"> + <img src$="[[getScannersLoadingSvgSrc(isDarkModeEnabled)]]" alt="[[i18n('scannersLoadingText')]]"> </template> - <template is="dom-if" if="[[isJellyEnabled_]]"> + <template is="dom-if" if="[[isJellyEnabled]]"> <svg preserveAspectRatio="xMidYMid meet" role="img" viewBox="0 0 257 256"> <title>[[i18n('scannersLoadingText')]]</title> <use href="svg/illo_loading_scanner.svg#illo_loading_scanner"></use> @@ -76,14 +76,14 @@ <h1>[[i18n('scannersLoadingText')]]</h1> <paper-progress indeterminate></paper-progress> </div> - <div id="noScannersDiv" hidden="[[!noScannersAvailable_]]"> + <div id="noScannersDiv" hidden="[[!noScannersAvailable]]"> <!-- TODO(b/276493795): After the Jelly experiment is launched, remove used image elements and SVGs. --> - <template is="dom-if" if="[[!isJellyEnabled_]]"> - <img src$="[[getNoScannersSvgSrc_(isDarkModeEnabled_)]]" + <template is="dom-if" if="[[!isJellyEnabled]]"> + <img src$="[[getNoScannersSvgSrc(isDarkModeEnabled)]]" alt="[[i18n('noScannersText')]]"> </template> - <template is="dom-if" if="[[isJellyEnabled_]]"> + <template is="dom-if" if="[[isJellyEnabled]]"> <svg preserveAspectRatio="xMidYMid meet" role="img" viewBox="0 0 257 256"> <title>[[i18n('noScannersSubtext')]]</title> <use href="svg/illo_no_scanner.svg#illo_no_scanner"></use> @@ -93,11 +93,11 @@ <span id="noScannersSubtext">[[i18n('noScannersSubtext')]]</span> <div id="buttonDiv"> <cr-button id="learnMoreButton" class="cancel-button" - on-click="onLearnMoreClick_"> + on-click="onLearnMoreClick"> [[i18n('learnMoreButtonLabel')]] </cr-button> <cr-button id="retryButton" class="action-button" - on-click="onRetryClick_"> + on-click="onRetryClick"> [[i18n('retryButtonLabel')]] </cr-button> </div>
diff --git a/ash/webui/scanning/resources/loading_page.js b/ash/webui/scanning/resources/loading_page.js deleted file mode 100644 index b7f61bb0..0000000 --- a/ash/webui/scanning/resources/loading_page.js +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://resources/cr_elements/cr_button/cr_button.js'; -import 'chrome://resources/polymer/v3_0/iron-media-query/iron-media-query.js'; -import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js'; -import './strings.m.js'; - -import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/ash/common/i18n_behavior.js'; -import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; -import {mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {getTemplate} from './loading_page.html.js'; -import {AppState} from './scanning_app_types.js'; - -/** - * @fileoverview - * 'loading-page' is shown while searching for available scanners. - */ - -/** - * @constructor - * @extends {PolymerElement} - * @implements {I18nBehaviorInterface} - */ -const LoadingPageElementBase = mixinBehaviors([I18nBehavior], PolymerElement); - -/** @polymer */ -class LoadingPageElement extends LoadingPageElementBase { - static get is() { - return 'loading-page'; - } - - static get template() { - return getTemplate(); - } - - static get properties() { - return { - /** @type {!AppState} */ - appState: { - type: Number, - observer: 'onAppStateChange_', - }, - - /** @protected {boolean} */ - isDarkModeEnabled_: { - type: Boolean, - }, - - /** @protected {boolean} */ - isJellyEnabled_: { - type: Boolean, - value: () => { - return loadTimeData.getBoolean('isJellyEnabledForScanningApp'); - }, - }, - - /** @private {boolean} */ - noScannersAvailable_: { - type: Boolean, - value: false, - }, - }; - } - - - - /** - * Determines correct SVG for "no scanners" based on dark mode. - * @protected - * @return {string} - */ - getNoScannersSvgSrc_() { - return this.isDarkModeEnabled_ ? 'svg/no_scanners_dark.svg' : - 'svg/no_scanners.svg'; - } - - /** - * Determines correct SVG for "scanners loading" based on dark mode. - * @protected - * @return {string} - */ - getScannersLoadingSvgSrc_() { - return this.isDarkModeEnabled_ ? 'svg/scanners_loading_dark.svg' : - 'svg/scanners_loading.svg'; - } - - /** @private */ - onAppStateChange_() { - this.noScannersAvailable_ = this.appState === AppState.NO_SCANNERS; - } - - /** @private */ - onRetryClick_() { - this.dispatchEvent( - new CustomEvent('retry-click', {bubbles: true, composed: true})); - } - - /** @private */ - onLearnMoreClick_() { - this.dispatchEvent( - new CustomEvent('learn-more-click', {bubbles: true, composed: true})); - } - - /** @param {boolean} enabled */ - setIsJellyEnabledForTesting(enabled) { - this.isJellyEnabled_ = enabled; - } -} - -customElements.define(LoadingPageElement.is, LoadingPageElement);
diff --git a/ash/webui/scanning/resources/loading_page.ts b/ash/webui/scanning/resources/loading_page.ts new file mode 100644 index 0000000..167973e --- /dev/null +++ b/ash/webui/scanning/resources/loading_page.ts
@@ -0,0 +1,110 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_button/cr_button.js'; +import 'chrome://resources/polymer/v3_0/iron-media-query/iron-media-query.js'; +import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js'; +import './strings.m.js'; + +import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; +import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {getTemplate} from './loading_page.html.js'; +import {AppState} from './scanning_app_types.js'; + +/** + * @fileoverview + * 'loading-page' is shown while searching for available scanners. + */ + +const LoadingPageElementBase = I18nMixin(PolymerElement); + +class LoadingPageElement extends LoadingPageElementBase { + static get is() { + return 'loading-page' as const; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + appState: { + type: Number, + observer: 'appStateChanged', + }, + + isDarkModeEnabled: { + type: Boolean, + }, + + isJellyEnabled: { + type: Boolean, + value: () => { + return loadTimeData.getBoolean('isJellyEnabledForScanningApp'); + }, + }, + + noScannersAvailable: { + type: Boolean, + value: false, + }, + }; + } + + appState: AppState; + private isDarkModeEnabled: boolean; + private isJellyEnabled: boolean; + private noScannersAvailable: boolean; + + /** + * Determines correct SVG for "no scanners" based on dark mode. + */ + private getNoScannersSvgSrc(): string { + return this.isDarkModeEnabled ? 'svg/no_scanners_dark.svg' : + 'svg/no_scanners.svg'; + } + + /** + * Determines correct SVG for "scanners loading" based on dark mode. + */ + private getScannersLoadingSvgSrc(): string { + return this.isDarkModeEnabled ? 'svg/scanners_loading_dark.svg' : + 'svg/scanners_loading.svg'; + } + + private appStateChanged(): void { + this.noScannersAvailable = this.appState === AppState.NO_SCANNERS; + } + + private onRetryClick(): void { + this.dispatchEvent( + new CustomEvent('retry-click', {bubbles: true, composed: true})); + } + + private onLearnMoreClick(): void { + this.dispatchEvent( + new CustomEvent('learn-more-click', {bubbles: true, composed: true})); + } + + setIsJellyEnabledForTesting(enabled: boolean): void { + this.isJellyEnabled = enabled; + } +} + +declare global { + interface HTMLElementEventMap { + 'learn-more-click': CustomEvent<void>; + 'retry-click': CustomEvent<void>; + } + + interface HTMLElementTagNameMap { + [LoadingPageElement.is]: LoadingPageElement; + } +} + + +customElements.define(LoadingPageElement.is, LoadingPageElement);
diff --git a/ash/webui/scanning/resources/mojo_interface_provider.js b/ash/webui/scanning/resources/mojo_interface_provider.js deleted file mode 100644 index 5e923ffa..0000000 --- a/ash/webui/scanning/resources/mojo_interface_provider.js +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {AccessibilityFeatures, AccessibilityFeaturesInterface} from './accessibility_features.mojom-webui.js'; -import {ScanService, ScanServiceInterface} from './scanning.mojom-webui.js'; - -/** @type {?ScanServiceInterface} */ -let scanService = null; - -/** @type {?AccessibilityFeaturesInterface} */ -let accessibilityFeatures = null; - -/** @param {!ScanServiceInterface} testScanService */ -export function setScanServiceForTesting(testScanService) { - scanService = testScanService; -} - -/** @return {!ScanServiceInterface} */ -export function getScanService() { - if (scanService) { - return scanService; - } - - scanService = ScanService.getRemote(); - return scanService; -} - -/** - * @param {!AccessibilityFeaturesInterface} - * testAccessibilityInterface - */ -export function setAccessibilityFeaturesForTesting(testAccessibilityInterface) { - accessibilityFeatures = testAccessibilityInterface; -} - -/** @return {!AccessibilityFeaturesInterface} */ -export function getAccessibilityFeaturesInterface() { - if (accessibilityFeatures) { - return accessibilityFeatures; - } - - accessibilityFeatures = AccessibilityFeatures.getRemote(); - return accessibilityFeatures; -}
diff --git a/ash/webui/scanning/resources/mojo_interface_provider.ts b/ash/webui/scanning/resources/mojo_interface_provider.ts new file mode 100644 index 0000000..6142148 --- /dev/null +++ b/ash/webui/scanning/resources/mojo_interface_provider.ts
@@ -0,0 +1,39 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {AccessibilityFeatures, AccessibilityFeaturesInterface} from './accessibility_features.mojom-webui.js'; +import {ScanService, ScanServiceInterface} from './scanning.mojom-webui.js'; + +let scanService: ScanServiceInterface|null = null; + +let accessibilityFeatures: AccessibilityFeaturesInterface|null = null; + +export function setScanServiceForTesting( + testScanService: ScanServiceInterface) { + scanService = testScanService; +} + +export function getScanService(): ScanServiceInterface { + if (scanService) { + return scanService; + } + + scanService = ScanService.getRemote(); + return scanService; +} + +export function setAccessibilityFeaturesForTesting( + testAccessibilityInterface: AccessibilityFeaturesInterface) { + accessibilityFeatures = testAccessibilityInterface; +} + +export function getAccessibilityFeaturesInterface(): + AccessibilityFeaturesInterface { + if (accessibilityFeatures) { + return accessibilityFeatures; + } + + accessibilityFeatures = AccessibilityFeatures.getRemote(); + return accessibilityFeatures; +}
diff --git a/ash/webui/scanning/resources/page_size_select.html b/ash/webui/scanning/resources/page_size_select.html index 006566a..33f24e9d 100644 --- a/ash/webui/scanning/resources/page_size_select.html +++ b/ash/webui/scanning/resources/page_size_select.html
@@ -9,7 +9,7 @@ aria-labelledby="pageSizeLabel"> <template is="dom-repeat" items="[[options]]" as="pageSize"> <option value="[[pageSize]]" selected$="[[isDefaultOption(pageSize)]]"> - [[getPageSizeString_(pageSize)]] + [[getPageSizeAsString(pageSize)]] </option> </template> </select>
diff --git a/ash/webui/scanning/resources/page_size_select.js b/ash/webui/scanning/resources/page_size_select.js deleted file mode 100644 index d49e0a78..0000000 --- a/ash/webui/scanning/resources/page_size_select.js +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import './scan_settings_section.js'; -import './strings.m.js'; - -import {assert} from 'chrome://resources/ash/common/assert.js'; -import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/ash/common/i18n_behavior.js'; -import {mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {getTemplate} from './page_size_select.html.js'; -import {PageSize} from './scanning.mojom-webui.js'; -import {alphabeticalCompare, getPageSizeString} from './scanning_app_util.js'; -import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js'; - -/** @type {PageSize} */ -const DEFAULT_PAGE_SIZE = PageSize.kNaLetter; - -/** - * @fileoverview - * 'page-size-select' displays the available page sizes in a dropdown. - */ - -/** - * @constructor - * @extends {PolymerElement} - * @implements {I18nBehaviorInterface} - * @implements {SelectBehaviorInterface} - */ -const PageSizeSelectElementBase = - mixinBehaviors([I18nBehavior, SelectBehavior], PolymerElement); - -/** @polymer */ -class PageSizeSelectElement extends PageSizeSelectElementBase { - static get is() { - return 'page-size-select'; - } - - static get template() { - return getTemplate(); - } - - /** - * @param {number} index - * @return {string} - */ - getOptionAtIndex(index) { - assert(index < this.options.length); - - return this.options[index].toString(); - } - - /** - * @param {!PageSize} pageSize - * @return {string} - * @private - */ - getPageSizeString_(pageSize) { - return getPageSizeString(pageSize); - } - - sortOptions() { - this.options.sort((a, b) => { - return alphabeticalCompare(getPageSizeString(a), getPageSizeString(b)); - }); - - // If the fit to scan area option exists, move it to the end of the page - // sizes array. - const fitToScanAreaIndex = this.options.findIndex((pageSize) => { - return pageSize === PageSize.kMax; - }); - - - if (fitToScanAreaIndex !== -1) { - this.options.push(this.options.splice(fitToScanAreaIndex, 1)[0]); - } - } - - /** - * @param {!PageSize} option - * @return {boolean} - */ - isDefaultOption(option) { - return option === DEFAULT_PAGE_SIZE; - } -} - -customElements.define(PageSizeSelectElement.is, PageSizeSelectElement);
diff --git a/ash/webui/scanning/resources/page_size_select.ts b/ash/webui/scanning/resources/page_size_select.ts new file mode 100644 index 0000000..4ff61a5d --- /dev/null +++ b/ash/webui/scanning/resources/page_size_select.ts
@@ -0,0 +1,79 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import './scan_settings_section.js'; +import './strings.m.js'; + +import {assert} from 'chrome://resources/ash/common/assert.js'; +import {I18nBehavior} from 'chrome://resources/ash/common/i18n_behavior.js'; +import {mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {getTemplate} from './page_size_select.html.js'; +import {PageSize} from './scanning.mojom-webui.js'; +import {alphabeticalCompare, getPageSizeString} from './scanning_app_util.js'; +import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js'; + +/** @type {PageSize} */ +const DEFAULT_PAGE_SIZE = PageSize.kNaLetter; + +/** + * @fileoverview + * 'page-size-select' displays the available page sizes in a dropdown. + */ + +// TODO(b/300484132): Replace mixinBehavior with mixin implementation once a +// Mixin version of SelectBehavior is available. +const PageSizeSelectElementBase = + mixinBehaviors([I18nBehavior, SelectBehavior], PolymerElement) as + {new (): PolymerElement & I18nBehavior & SelectBehaviorInterface}; + +class PageSizeSelectElement extends PageSizeSelectElementBase { + static get is() { + return 'page-size-select' as const; + } + + static get template() { + return getTemplate(); + } + + getOptionAtIndex(index: number): string { + assert(index < this.options.length); + + return this.options[index].toString(); + } + + getPageSizeAsString(pageSize: PageSize): string { + return getPageSizeString(pageSize); + } + + sortOptions(): void { + this.options.sort((a: PageSize, b: PageSize) => { + return alphabeticalCompare(getPageSizeString(a), getPageSizeString(b)); + }); + + // If the fit to scan area option exists, move it to the end of the page + // sizes array. + const fitToScanAreaIndex = + this.options.findIndex((pageSize: PageSize): boolean => { + return pageSize === PageSize.kMax; + }); + + + if (fitToScanAreaIndex !== -1) { + this.options.push(this.options.splice(fitToScanAreaIndex, 1)[0]); + } + } + + isDefaultOption(option: PageSize): boolean { + return option === DEFAULT_PAGE_SIZE; + } +} + +declare global { + interface HTMLElementTagNameMap { + [PageSizeSelectElement.is]: PageSizeSelectElement; + } +} + +customElements.define(PageSizeSelectElement.is, PageSizeSelectElement);
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table_unittest.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table_unittest.cc index 67a25b4..823f606 100644 --- a/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table_unittest.cc +++ b/ash/webui/shortcut_customization_ui/backend/accelerator_layout_table_unittest.cc
@@ -22,9 +22,9 @@ namespace { // The total number of Ash accelerators. -constexpr int kAshAcceleratorsTotalNum = 147; +constexpr int kAshAcceleratorsTotalNum = 148; // The hash of Ash accelerators. -constexpr char kAshAcceleratorsHash[] = "6b946ad3ceb8263615f2c47dc7e240a8"; +constexpr char kAshAcceleratorsHash[] = "6c4f544746a603c9075b45cc093a64bf"; std::string ToActionName(ash::AcceleratorAction action) { return base::StrCat(
diff --git a/ash/wm/base_state.cc b/ash/wm/base_state.cc index cbe1961..3245d68 100644 --- a/ash/wm/base_state.cc +++ b/ash/wm/base_state.cc
@@ -105,33 +105,6 @@ } // static -void BaseState::CenterWindow(WindowState* window_state) { - if (!window_state->IsNormalOrSnapped()) - return; - aura::Window* window = window_state->window(); - if (window_state->IsSnapped()) { - gfx::Rect center_in_screen = display::Screen::GetScreen() - ->GetDisplayNearestWindow(window) - .work_area(); - gfx::Size size = window_state->HasRestoreBounds() - ? window_state->GetRestoreBoundsInScreen().size() - : window->bounds().size(); - center_in_screen.ClampToCenteredSize(size); - window_state->SetRestoreBoundsInScreen(center_in_screen); - window_state->Restore(); - } else { - gfx::Rect center_in_parent = - screen_util::GetDisplayWorkAreaBoundsInParent(window); - center_in_parent.ClampToCenteredSize(window->bounds().size()); - const SetBoundsWMEvent event(center_in_parent, - /*animate=*/true); - window_state->OnWMEvent(&event); - } - // Centering window is treated as if a user moved and resized the window. - window_state->set_bounds_changed_by_user(true); -} - -// static void BaseState::CycleSnap(WindowState* window_state, WMEventType event) { auto* shell = Shell::Get(); // For tablet mode, use |TabletModeWindowState::CycleTabletSnap|.
diff --git a/ash/wm/base_state.h b/ash/wm/base_state.h index 6880933..b23a3e0 100644 --- a/ash/wm/base_state.h +++ b/ash/wm/base_state.h
@@ -34,7 +34,6 @@ WindowState* window_state, const WMEvent* event); - static void CenterWindow(WindowState* window_state); static void CycleSnap(WindowState* window_state, WMEventType event); // Handles workspace related events, such as DISPLAY_BOUNDS_CHANGED.
diff --git a/ash/wm/client_controlled_state.cc b/ash/wm/client_controlled_state.cc index 5a2a686e..57d818a 100644 --- a/ash/wm/client_controlled_state.cc +++ b/ash/wm/client_controlled_state.cc
@@ -267,9 +267,6 @@ } break; } - case WM_EVENT_CENTER: - CenterWindow(window_state); - break; default: NOTREACHED() << "Unknown event:" << event->type(); }
diff --git a/ash/wm/client_controlled_state_unittest.cc b/ash/wm/client_controlled_state_unittest.cc index cc5d3eb..0e972a1 100644 --- a/ash/wm/client_controlled_state_unittest.cc +++ b/ash/wm/client_controlled_state_unittest.cc
@@ -416,10 +416,11 @@ TEST_F(ClientControlledStateTest, CenterWindow) { display::Screen* screen = display::Screen::GetScreen(); - gfx::Rect bounds = screen->GetPrimaryDisplay().work_area(); + const gfx::Rect bounds = screen->GetPrimaryDisplay().work_area(); - const WMEvent center_event(WM_EVENT_CENTER); - window_state()->OnWMEvent(¢er_event); + gfx::Rect center_bounds = bounds; + center_bounds.ClampToCenteredSize(window()->bounds().size()); + window()->SetBoundsInScreen(center_bounds, screen->GetPrimaryDisplay()); EXPECT_NEAR(bounds.CenterPoint().x(), delegate()->requested_bounds().CenterPoint().x(), 1); EXPECT_NEAR(bounds.CenterPoint().y(),
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc index aca49d0..35fc8c4 100644 --- a/ash/wm/default_state.cc +++ b/ash/wm/default_state.cc
@@ -376,9 +376,6 @@ static_cast<const SetBoundsWMEvent*>(event); SetBounds(window_state, set_bounds_event); } break; - case WM_EVENT_CENTER: - CenterWindow(window_state); - break; default: NOTREACHED() << "Unknown event:" << event->type(); break;
diff --git a/ash/wm/lock_window_state.cc b/ash/wm/lock_window_state.cc index c975479..e1d61bc 100644 --- a/ash/wm/lock_window_state.cc +++ b/ash/wm/lock_window_state.cc
@@ -53,7 +53,6 @@ case WM_EVENT_TOGGLE_MAXIMIZE: case WM_EVENT_CYCLE_SNAP_PRIMARY: case WM_EVENT_CYCLE_SNAP_SECONDARY: - case WM_EVENT_CENTER: case WM_EVENT_SNAP_PRIMARY: case WM_EVENT_SNAP_SECONDARY: case WM_EVENT_NORMAL:
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.cc b/ash/wm/tablet_mode/tablet_mode_window_state.cc index 349a59a..3902c02 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_state.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_state.cc
@@ -311,7 +311,6 @@ case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE: case WM_EVENT_TOGGLE_MAXIMIZE: - case WM_EVENT_CENTER: case WM_EVENT_MAXIMIZE: UpdateWindow(window_state, window_state->GetWindowTypeOnMaximizable(), /*animate=*/true);
diff --git a/ash/wm/window_positioning_utils.cc b/ash/wm/window_positioning_utils.cc index 54835d6..3fb8e76 100644 --- a/ash/wm/window_positioning_utils.cc +++ b/ash/wm/window_positioning_utils.cc
@@ -224,11 +224,6 @@ rotation); } -void CenterWindow(aura::Window* window) { - WMEvent event(WM_EVENT_CENTER); - WindowState::Get(window)->OnWMEvent(&event); -} - void SetBoundsInScreen(aura::Window* window, const gfx::Rect& bounds_in_screen, const display::Display& display) {
diff --git a/ash/wm/window_positioning_utils.h b/ash/wm/window_positioning_utils.h index 8a3e341..3a298904 100644 --- a/ash/wm/window_positioning_utils.h +++ b/ash/wm/window_positioning_utils.h
@@ -81,9 +81,6 @@ chromeos::OrientationType GetSnapDisplayOrientation( const display::Display& display); -// Moves the window to the center of the display. -ASH_EXPORT void CenterWindow(aura::Window* window); - // Sets the bounds of |window| to |bounds_in_screen|. This may move |window| // to |display| if necessary. ASH_EXPORT void SetBoundsInScreen(aura::Window* window,
diff --git a/ash/wm/window_util_unittest.cc b/ash/wm/window_util_unittest.cc index 6ad2503..7b31279c 100644 --- a/ash/wm/window_util_unittest.cc +++ b/ash/wm/window_util_unittest.cc
@@ -35,25 +35,6 @@ using WindowUtilTest = AshTestBase; -TEST_F(WindowUtilTest, CenterWindow) { - UpdateDisplay("500x400, 600x400"); - std::unique_ptr<aura::Window> window( - CreateTestWindowInShellWithBounds(gfx::Rect(12, 20, 100, 100))); - - WindowState* window_state = WindowState::Get(window.get()); - EXPECT_FALSE(window_state->bounds_changed_by_user()); - - CenterWindow(window.get()); - // Centring window is considered as a user's action. - EXPECT_TRUE(window_state->bounds_changed_by_user()); - EXPECT_EQ("200,126 100x100", window->bounds().ToString()); - EXPECT_EQ("200,126 100x100", window->GetBoundsInScreen().ToString()); - window->SetBoundsInScreen(gfx::Rect(600, 0, 100, 100), GetSecondaryDisplay()); - CenterWindow(window.get()); - EXPECT_EQ("250,126 100x100", window->bounds().ToString()); - EXPECT_EQ("750,126 100x100", window->GetBoundsInScreen().ToString()); -} - TEST_F(WindowUtilTest, AdjustBoundsToEnsureMinimumVisibility) { const gfx::Rect visible_bounds(0, 0, 100, 100);
diff --git a/ash/wm/wm_event.cc b/ash/wm/wm_event.cc index 795885c..96d025f 100644 --- a/ash/wm/wm_event.cc +++ b/ash/wm/wm_event.cc
@@ -56,14 +56,7 @@ } bool WMEvent::IsBoundsEvent() const { - switch (type_) { - case WM_EVENT_SET_BOUNDS: - case WM_EVENT_CENTER: - return true; - default: - break; - } - return false; + return type_ == WM_EVENT_SET_BOUNDS; } bool WMEvent::IsTransitionEvent() const {
diff --git a/ash/wm/wm_event.h b/ash/wm/wm_event.h index 31d850bd..b03893b 100644 --- a/ash/wm/wm_event.h +++ b/ash/wm/wm_event.h
@@ -80,9 +80,6 @@ // See description of WM_EVENT_CYCLE_SNAP_PRIMARY. WM_EVENT_CYCLE_SNAP_SECONDARY, - // A user requested to center a window. - WM_EVENT_CENTER, - // TODO(oshima): Investigate if this can be removed from ash. // Widget requested to show in inactive state. WM_EVENT_SHOW_INACTIVE,
diff --git a/base/BUILD.gn b/base/BUILD.gn index cf62fd2..ca1f9c6 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2027,7 +2027,6 @@ "mac/scoped_mach_msg_destroy.h", "mac/scoped_sending_event.h", "mac/scoped_sending_event.mm", - "mac/wrap_cg_display.h", "message_loop/message_pump_kqueue.cc", "message_loop/message_pump_kqueue.h", "native_library_mac.mm",
diff --git a/base/android/library_loader/library_loader_hooks.h b/base/android/library_loader/library_loader_hooks.h index 6fe749b..c81f7a4 100644 --- a/base/android/library_loader/library_loader_hooks.h +++ b/base/android/library_loader/library_loader_hooks.h
@@ -29,12 +29,8 @@ PROCESS_WEBVIEW = 3, // Shared library is running in child process as part of webview. PROCESS_WEBVIEW_CHILD = 4, - // Shared library is running in the app that uses weblayer. - PROCESS_WEBLAYER = 5, - // Shared library is running in child process as part of weblayer. - PROCESS_WEBLAYER_CHILD = 6, // Shared library is running in a non-embedded WebView process. - PROCESS_WEBVIEW_NONEMBEDDED = 7, + PROCESS_WEBVIEW_NONEMBEDDED = 5, }; // Returns the library process type this library was loaded for.
diff --git a/base/mac/wrap_cg_display.h b/base/mac/wrap_cg_display.h deleted file mode 100644 index a579ef1..0000000 --- a/base/mac/wrap_cg_display.h +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_MAC_WRAP_CG_DISPLAY_H_ -#define BASE_MAC_WRAP_CG_DISPLAY_H_ - -// All these symbols have incorrect availability annotations in the 13.3 SDK. -// These have the correct annotation. See https://crbug.com/1431897. -// TODO(thakis): Remove this once FB12109479 is fixed and we updated to an SDK -// with the fix. - -#include <CoreGraphics/CoreGraphics.h> - -inline CGDisplayStreamRef __nullable wrapCGDisplayStreamCreate( - CGDirectDisplayID display, - size_t outputWidth, - size_t outputHeight, - int32_t pixelFormat, - CFDictionaryRef __nullable properties, - CGDisplayStreamFrameAvailableHandler __nullable handler) - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's " - "initWithFilter:configuration:delegate: instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return CGDisplayStreamCreate(display, outputWidth, outputHeight, pixelFormat, - properties, handler); -#pragma clang diagnostic pop -} - -inline CFRunLoopSourceRef __nullable wrapCGDisplayStreamGetRunLoopSource( - CGDisplayStreamRef cg_nullable displayStream) - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "There is no direct replacement for this function. Please use " - "ScreenCaptureKit API's SCStream to replace CGDisplayStream") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return CGDisplayStreamGetRunLoopSource(displayStream); -#pragma clang diagnostic pop -} - -inline CGError wrapCGDisplayStreamStart( - CGDisplayStreamRef cg_nullable displayStream) - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's " - "startCaptureWithCompletionHandler: to start a stream instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return CGDisplayStreamStart(displayStream); -#pragma clang diagnostic pop -} - -inline CGError wrapCGDisplayStreamStop( - CGDisplayStreamRef cg_nullable displayStream) - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's " - "stopCaptureWithCompletionHandler: to stop a stream instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return CGDisplayStreamStop(displayStream); -#pragma clang diagnostic pop -} - -inline _Null_unspecified CFStringRef wrapkCGDisplayStreamColorSpace() - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's SCStreamConfiguration " - "colorSpaceName property instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return kCGDisplayStreamColorSpace; -#pragma clang diagnostic pop -} - -inline _Null_unspecified CFStringRef wrapkCGDisplayStreamDestinationRect() - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's SCStreamConfiguration " - "destinationRect property instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return kCGDisplayStreamDestinationRect; -#pragma clang diagnostic pop -} - -inline _Null_unspecified CFStringRef wrapkCGDisplayStreamMinimumFrameTime() - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's SCStreamConfiguration " - "minimumFrameInterval property instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return kCGDisplayStreamMinimumFrameTime; -#pragma clang diagnostic pop -} - -inline _Null_unspecified CFStringRef wrapkCGDisplayStreamPreserveAspectRatio() - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's SCStreamConfiguration " - "preserveAspectRatio property instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return kCGDisplayStreamPreserveAspectRatio; -#pragma clang diagnostic pop -} - -inline _Null_unspecified CFStringRef wrapkCGDisplayStreamShowCursor() - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's SCStreamConfiguration showsCursor " - "property instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return kCGDisplayStreamShowCursor; -#pragma clang diagnostic pop -} - -inline const CGRect* __nullable -wrapCGDisplayStreamUpdateGetRects(CGDisplayStreamUpdateRef __nullable updateRef, - CGDisplayStreamUpdateRectType rectType, - size_t* _Null_unspecified rectCount) - CG_AVAILABLE_BUT_DEPRECATED( - 10.8, - 14.0, - "Please use ScreenCaptureKit API's SCStreamFrameInfo with " - "SCStreamFrameInfoContentRect instead") { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - return CGDisplayStreamUpdateGetRects(updateRef, rectType, rectCount); -#pragma clang diagnostic pop -} - -#endif // BASE_MAC_WRAP_CG_DISPLAY_H_
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc index de3f8f80..df1e6557 100644 --- a/base/metrics/statistics_recorder.cc +++ b/base/metrics/statistics_recorder.cc
@@ -27,7 +27,7 @@ namespace { // Whether a 50/50 trial for using a R/W lock should be run. -constexpr bool kRunRwLockTrial = false; +constexpr bool kRunRwLockTrial = true; bool EnableBenchmarking() { // TODO(asvitkine): If this code ends up not being temporary, refactor it to @@ -316,7 +316,7 @@ if (kRunRwLockTrial && !EnableBenchmarking()) { return RandInt(0, 1) == 1; } - return false; + return true; } // static
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index b6cd3b3..de96337 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -30,6 +30,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" +#include "base/metrics/statistics_recorder.h" #include "base/no_destructor.h" #include "base/path_service.h" #include "base/process/launch.h" @@ -117,7 +118,14 @@ class ResetCommandLineBetweenTests : public testing::EmptyTestEventListener { public: - ResetCommandLineBetweenTests() : old_command_line_(CommandLine::NO_PROGRAM) {} + ResetCommandLineBetweenTests() : old_command_line_(CommandLine::NO_PROGRAM) { + // TODO(crbug.com/1123627): Remove this after A/B test is done. + // Workaround a test-specific race conditon with StatisticsRecorder lock + // initialization checking CommandLine by ensuring it's created here (when + // we start the test process), rather than in some arbitrary test. This + // prevents a race with OnTestEnd(). + StatisticsRecorder::FindHistogram("Dummy"); + } ResetCommandLineBetweenTests(const ResetCommandLineBetweenTests&) = delete; ResetCommandLineBetweenTests& operator=(const ResetCommandLineBetweenTests&) =
diff --git a/base/tracing/stdlib/chrome/README b/base/tracing/stdlib/chrome/README new file mode 100644 index 0000000..1d70202 --- /dev/null +++ b/base/tracing/stdlib/chrome/README
@@ -0,0 +1,5 @@ +# PerfettoSQL Chrome Standard Library + +The [PerfettoSQL Standard Library](https://perfetto.dev/docs/analysis/stdlib-docs) contains commonly used SQL tables, views, functions and macros to make it easier for users to query traces. The Chrome Standard Library contains those metrics that are specific to Chrome. + +The source of truth of the Perfetto SQL Chrome stdlib has been moved from Perfetto to the Chromium repository to make it easier to develop new metrics and add tests for them in a single Chromium CL. \ No newline at end of file
diff --git a/base/tracing/test/README b/base/tracing/test/README new file mode 100644 index 0000000..b5cd7f5 --- /dev/null +++ b/base/tracing/test/README
@@ -0,0 +1,15 @@ +# PerfettoSQL Chrome Standard Library tests + +This directory contains the [Perfetto Diff Tests](https://perfetto.dev/docs/analysis/trace-processor#diff-tests) to test changes to the Chrome standard library. + +The diff tests themselves are in `./trace_processor/diff_tests/chrome`. The `./data` directory contains the Perfetto traces that are used by the diff tests. + +## Running Diff Tests + +Currently, the diff tests only run on Linux. You can build and run the diff tests with the following. + +``` +$ gn gen --args='' out/Linux +$ autoninja -C out/Linux perfetto_diff_tests +$ out/Linux/bin/run_perfetto_diff_tests +``` \ No newline at end of file
diff --git a/build/OWNERS.setnoparent b/build/OWNERS.setnoparent index 876d9ee75..b93cd202 100644 --- a/build/OWNERS.setnoparent +++ b/build/OWNERS.setnoparent
@@ -57,10 +57,6 @@ # deprecation and versioning steps must be taken when doing so. file://chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/NOTIFICATION_CHANNEL_OWNERS -# The Weblayer API is supposed to be stable and will be used outside of the -# chromium repository. -file://weblayer/API_OWNERS - # New features for lock/login UI on Chrome OS need to work stably in all corner # cases. file://ash/login/LOGIN_LOCK_OWNERS
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index a08a8c8..03b0f68 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision vars in //DEPS. - libcxx_revision = "7cee6b00d34adc4da2ff2a4d373e44fc27a9a223" + libcxx_revision = "3e8a3b3c5d497eb7250566a63432046baf95481a" }
diff --git a/cc/input/scrollbar_animation_controller.cc b/cc/input/scrollbar_animation_controller.cc index d434f80..a9d7f02 100644 --- a/cc/input/scrollbar_animation_controller.cc +++ b/cc/input/scrollbar_animation_controller.cc
@@ -299,23 +299,13 @@ return; } - if (client_->IsFluentOverlayScrollbar()) { - if (!ScrollbarsHidden()) { - // Fluent scrollbars will remain being shown as long as you are - // moving your mouse, will transition into full mode when you mouse over - // them and will hide after being released from capture. - PostDelayedAnimation(MouseIsNearAnyScrollbar() - ? AnimationChange::kFadeIn - : AnimationChange::kFadeOut); - } - return; - } - if (ScrollbarsHidden()) { // Do not fade in scrollbar when user interacting with the content below - // scrollbar. - if (is_mouse_down_) + // scrollbar. Fluent scrollbars never leave invisibility due to pointer + // moves. + if (is_mouse_down_ || client_->IsFluentOverlayScrollbar()) { return; + } need_trigger_scrollbar_fade_in_ = MouseIsNearAnyScrollbar(); if (need_trigger_scrollbar_fade_in_before != need_trigger_scrollbar_fade_in_) { @@ -329,7 +319,7 @@ if (MouseIsNearAnyScrollbar()) { Show(); StopAnimation(); - } else if (!is_animating_) { + } else if (!is_animating_ || client_->IsFluentOverlayScrollbar()) { PostDelayedAnimation(AnimationChange::kFadeOut); } }
diff --git a/cc/input/scrollbar_animation_controller_unittest.cc b/cc/input/scrollbar_animation_controller_unittest.cc index ad1c364f..152d40b9 100644 --- a/cc/input/scrollbar_animation_controller_unittest.cc +++ b/cc/input/scrollbar_animation_controller_unittest.cc
@@ -14,10 +14,11 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::_; using testing::AtLeast; +using ::testing::Bool; using testing::Mock; using testing::NiceMock; -using testing::_; namespace cc { namespace { @@ -57,11 +58,12 @@ bool is_fluent_; }; -class ScrollbarAnimationControllerAuraOverlayTest +class ScrollbarAnimationControllerOverlayTest : public LayerTreeImplTestBase, - public testing::Test { + public testing::Test, + public testing::WithParamInterface<bool> { public: - explicit ScrollbarAnimationControllerAuraOverlayTest(bool is_fluent = false) + explicit ScrollbarAnimationControllerOverlayTest(bool is_fluent = GetParam()) : client_(host_impl(), is_fluent) {} void ExpectScrollbarsOpacity(float opacity) { @@ -162,19 +164,24 @@ NiceMock<MockScrollbarAnimationControllerClient> client_; }; +class ScrollbarAnimationControllerAuraOverlayTest + : public ScrollbarAnimationControllerOverlayTest { + public: + ScrollbarAnimationControllerAuraOverlayTest() + : ScrollbarAnimationControllerOverlayTest(/*is_fluent=*/false) {} +}; + // TODO(https://crbug.com/1479200): Implement unit tests for fluent overlay -// scrollbars tickmarks when they are implemented. Also, investigate if there -// are tests that work for both fluent and non fluent aura overlay scrollbars -// that can be reused. +// scrollbars tickmarks when they are implemented. class ScrollbarAnimationControllerFluentOverlayTest - : public ScrollbarAnimationControllerAuraOverlayTest { + : public ScrollbarAnimationControllerOverlayTest { public: ScrollbarAnimationControllerFluentOverlayTest() - : ScrollbarAnimationControllerAuraOverlayTest(/* is_fluent */ true) {} + : ScrollbarAnimationControllerOverlayTest(/*is_fluent=*/true) {} }; // Check initialization of scrollbar. Should start off invisible and thin. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, Idle) { +TEST_P(ScrollbarAnimationControllerOverlayTest, Idle) { ExpectScrollbarsOpacity(0); EXPECT_TRUE(scrollbar_controller_->ScrollbarsHidden()); EXPECT_FLOAT_EQ(kIdleThicknessScale, @@ -184,7 +191,7 @@ } // Check that scrollbar appears again when the layer becomes scrollable. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, AppearOnResize) { +TEST_P(ScrollbarAnimationControllerOverlayTest, AppearOnResize) { base::TimeTicks time; time += base::Seconds(1); @@ -209,7 +216,7 @@ } // Check that scrollbar disappears when the layer becomes non-scrollable. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, HideOnResize) { +TEST_P(ScrollbarAnimationControllerOverlayTest, HideOnResize) { base::TimeTicks time; time += base::Seconds(1); @@ -238,7 +245,7 @@ } // Scroll content. Confirm the scrollbar appears and fades out. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, BasicAppearAndFadeOut) { +TEST_P(ScrollbarAnimationControllerOverlayTest, BasicAppearAndFadeOut) { base::TimeTicks time; time += base::Seconds(1); @@ -272,7 +279,7 @@ } // Confirm the scrollbar appears by WillUpdateScroll and fade out. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, +TEST_P(ScrollbarAnimationControllerOverlayTest, BasicAppearByWillUpdateScrollThenFadeOut) { base::TimeTicks time; time += base::Seconds(1); @@ -401,7 +408,7 @@ // Scroll content. Move the mouse over the scrollbar and confirm it becomes // thick. Ensure it remains visible as long as the mouse is over the scrollbar. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, MoveOverAndDontFadeOut) { +TEST_P(ScrollbarAnimationControllerOverlayTest, MoveOverAndDontFadeOut) { base::TimeTicks time; time += base::Seconds(1); @@ -440,7 +447,7 @@ // Make sure a scrollbar captured before the thickening animation doesn't try // to fade out. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, +TEST_P(ScrollbarAnimationControllerOverlayTest, DontFadeWhileCapturedBeforeThick) { base::TimeTicks time; time += base::Seconds(1); @@ -466,8 +473,7 @@ } // Make sure a scrollbar captured then move mouse away doesn't try to fade out. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, - DontFadeWhileCapturedThenAway) { +TEST_P(ScrollbarAnimationControllerOverlayTest, DontFadeWhileCapturedThenAway) { base::TimeTicks time; time += base::Seconds(1); @@ -501,7 +507,7 @@ // Make sure a scrollbar captured after a thickening animation doesn't try to // fade out. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, DontFadeWhileCaptured) { +TEST_P(ScrollbarAnimationControllerOverlayTest, DontFadeWhileCaptured) { base::TimeTicks time; time += base::Seconds(1); @@ -535,9 +541,9 @@ client_.start_fade().IsCancelled()); } -// Make sure releasing a captured scrollbar when the mouse isn't near it, causes +// Make sure releasing a captured scrollbar when the mouse isn't near it causes // the scrollbar to fade out. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, FadeAfterReleasedFar) { +TEST_P(ScrollbarAnimationControllerOverlayTest, FadeAfterReleasedFar) { base::TimeTicks time; time += base::Seconds(1); @@ -574,10 +580,12 @@ time += kThinningDuration; scrollbar_controller_->Animate(time); ExpectScrollbarsOpacity(1); - EXPECT_FLOAT_EQ(kIdleThicknessScale, - v_scrollbar_layer_->thumb_thickness_scale_factor()); - EXPECT_FLOAT_EQ(kIdleThicknessScale, - h_scrollbar_layer_->thumb_thickness_scale_factor()); + if (!client_.IsFluentOverlayScrollbar()) { + EXPECT_FLOAT_EQ(kIdleThicknessScale, + v_scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + h_scrollbar_layer_->thumb_thickness_scale_factor()); + } // The thickness animation is complete, a fade out must be queued. EXPECT_FALSE(client_.start_fade().is_null()); @@ -586,7 +594,7 @@ // Make sure releasing a captured scrollbar when the mouse is near/over it, // doesn't cause the scrollbar to fade out. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, DontFadeAfterReleasedNear) { +TEST_P(ScrollbarAnimationControllerOverlayTest, DontFadeAfterReleasedNear) { base::TimeTicks time; time += base::Seconds(1); @@ -622,8 +630,7 @@ // Make sure moving near a scrollbar while it's fading out causes it to reset // the opacity and thicken. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, - MoveNearScrollbarWhileFading) { +TEST_P(ScrollbarAnimationControllerOverlayTest, MoveNearScrollbarWhileFading) { base::TimeTicks time; time += base::Seconds(1); @@ -767,8 +774,7 @@ } // Tests that main thread scroll updates immediately queue a fade out animation -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, - MainThreadScrollQueuesFade) { +TEST_P(ScrollbarAnimationControllerOverlayTest, MainThreadScrollQueuesFade) { ASSERT_TRUE(client_.start_fade().is_null()); // A ScrollUpdate indicates a main thread scroll update so we should schedule @@ -779,7 +785,7 @@ } // Tests that the fade effect is animated. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, FadeAnimated) { +TEST_P(ScrollbarAnimationControllerOverlayTest, FadeAnimated) { base::TimeTicks time; time += base::Seconds(1); @@ -808,7 +814,7 @@ } // Tests that the controller tells the client when the scrollbars hide/show. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, NotifyChangedVisibility) { +TEST_P(ScrollbarAnimationControllerOverlayTest, NotifyChangedVisibility) { base::TimeTicks time; time += base::Seconds(1); @@ -973,9 +979,10 @@ EXPECT_FLOAT_EQ(1, h_scrollbar_layer_->thumb_thickness_scale_factor()); } -// Move mouse from one to the other scrollbar before animation is finished, then -// away before animation finished. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, +// Move mouse on top of the vertical scrollbar, then to the horizontal scrollbar +// before the fade out animation is finished. Then, move the pointer away from +// both scrollbars before animation the animation is finished. +TEST_P(ScrollbarAnimationControllerOverlayTest, MouseNearOtherBeforeAnimationFinished) { base::TimeTicks time; time += base::Seconds(1); @@ -983,9 +990,10 @@ // Scroll to make the scrollbars visible. scrollbar_controller_->DidScrollUpdate(); - // Near vertical scrollbar. - scrollbar_controller_->DidMouseMove(NearVerticalScrollbarBegin(-1, 0)); + // Over vertical scrollbar. + scrollbar_controller_->DidMouseMove(NearVerticalScrollbarBegin(0, 0)); scrollbar_controller_->Animate(time); + ExpectScrollbarsOpacity(1); EXPECT_FLOAT_EQ(kIdleThicknessScale, v_scrollbar_layer_->thumb_thickness_scale_factor()); @@ -1001,12 +1009,12 @@ EXPECT_FLOAT_EQ(kIdleThicknessScale, h_scrollbar_layer_->thumb_thickness_scale_factor()); - // Away vertical scrollbar and near horizontal scrollbar. + // Away from vertical scrollbar and over horizontal scrollbar. scrollbar_controller_->DidMouseMove(gfx::PointF(0, 0)); - scrollbar_controller_->DidMouseMove(NearHorizontalScrollbarBegin(0, -1)); + scrollbar_controller_->DidMouseMove(NearHorizontalScrollbarBegin(0, 0)); scrollbar_controller_->Animate(time); - // Vertical scrollbar animate to thin. horizontal scrollbar animate to + // Vertical scrollbar animates to thin. Horizontal scrollbar animates to // thickened. time += kThinningDuration; scrollbar_controller_->Animate(time); @@ -1015,11 +1023,11 @@ v_scrollbar_layer_->thumb_thickness_scale_factor()); EXPECT_FLOAT_EQ(1, h_scrollbar_layer_->thumb_thickness_scale_factor()); - // Away horizontal scrollbar. + // Away from horizontal scrollbar. scrollbar_controller_->DidMouseMove(gfx::PointF(0, 0)); scrollbar_controller_->Animate(time); - // Horizontal scrollbar animate to thin. + // Horizontal scrollbar animates to thin. time += kThinningDuration; scrollbar_controller_->Animate(time); ExpectScrollbarsOpacity(1); @@ -1028,19 +1036,19 @@ EXPECT_FLOAT_EQ(kIdleThicknessScale, h_scrollbar_layer_->thumb_thickness_scale_factor()); - // An fade out animation should have been enqueued. + // A fade out animation should have been enqueued. EXPECT_FALSE(client_.start_fade().is_null()); EXPECT_EQ(kFadeDelay, client_.delay()); } // Ensure we have a delay fadeout animation after mouse leave without a mouse // move. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, MouseLeaveFadeOut) { +TEST_P(ScrollbarAnimationControllerOverlayTest, MouseLeaveFadeOut) { base::TimeTicks time; time += base::Seconds(1); // Move mouse near scrollbar. - scrollbar_controller_->DidMouseMove(NearVerticalScrollbarBegin(-1, 0)); + scrollbar_controller_->DidMouseMove(NearVerticalScrollbarBegin(0, 0)); // Scroll to make the scrollbars visible. scrollbar_controller_->DidScrollUpdate(); @@ -1100,7 +1108,7 @@ scrollbar_controller_->DidMouseMove( NearVerticalScrollbarBegin(-mouse_move_distance_to_trigger_fade_in_, 0)); - // An fade in animation should have been enqueued. + // A fade in animation should have been enqueued. EXPECT_FALSE(client_.start_fade().is_null()); EXPECT_FALSE(client_.start_fade().IsCancelled()); EXPECT_EQ(kFadeDelay, client_.delay()); @@ -1267,7 +1275,7 @@ // Ensure Aura Overlay Scrollbars shows and did not fade out when tickmarks show // and fade out when tickmarks hide. -TEST_F(ScrollbarAnimationControllerAuraOverlayTest, TickmarksShowHide) { +TEST_P(ScrollbarAnimationControllerOverlayTest, TickmarksShowHide) { base::TimeTicks time; time += base::Seconds(1); @@ -1885,6 +1893,7 @@ EXPECT_FLOAT_EQ(1, scrollbar_layer_->Opacity()); } +INSTANTIATE_TEST_SUITE_P(All, ScrollbarAnimationControllerOverlayTest, Bool()); } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index b8114bb..4f5b4ab 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -2662,7 +2662,8 @@ // In frame 0, scroll node has main_thread_scrolling_reasons. Prioritize // new content and not smoothness, since we need to repaint on the main // thread for the user to see the scroll. - EXPECT_EQ(NEW_CONTENT_TAKES_PRIORITY, host_impl->GetTreePriority()); + // TODO(crbug.com/1477299): Re-enable this check. + // EXPECT_EQ(NEW_CONTENT_TAKES_PRIORITY, host_impl->GetTreePriority()); input_handler.ScrollEnd(); PostSetNeedsCommitToMainThread(); }
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 185c193..0cb71cd 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -514,11 +514,17 @@ // - When the active scroll gesture requires main-thread repainting for the // scroll offset change to be visible. if (host_impl_->active_tree()->GetDeviceViewport().size().IsEmpty() || - host_impl_->EvictedUIResourcesExist() || - host_impl_->IsCurrentScrollMainRepainted()) { + host_impl_->EvictedUIResourcesExist()) { // Once we enter NEW_CONTENTS_TAKES_PRIORITY mode, visible tiles on active // tree might be freed. We need to set RequiresHighResToDraw to ensure that // high res tiles will be required to activate pending tree. + // + // TODO(crbug.com/1477299): It would be better to use this path during + // main-repainted scrolls (host_impl_->IsCurrentScrollMainRepainted()), but + // the RequiresHighResToDraw mode has a page-freezing bug triggered by + // animating scaled directly-composited images. To address the urgent + // regression, we have restored the pre-crbug.com/1418368 behavior, which + // makes main-repainted scrolls use SAME_PRIORITY_FOR_BOTH_TREES. host_impl_->SetRequiresHighResToDraw(); tree_priority = NEW_CONTENT_TAKES_PRIORITY; }
diff --git a/chrome/VERSION b/chrome/VERSION index 04e70ee..1ed6fd0 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=119 MINOR=0 -BUILD=6018 +BUILD=6019 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 9079705..f6faaf0 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -37,7 +37,6 @@ import("//third_party/jni_zero/jni_zero.gni") import("//third_party/protobuf/proto_library.gni") import("//tools/resources/generate_resource_allowlist.gni") -import("//weblayer/variables.gni") import("channel.gni") import("java_sources.gni") import("static_initializers.gni") @@ -1047,9 +1046,11 @@ "//chrome/browser/ui/android/edge_to_edge/internal:junit", "//chrome/browser/ui/android/fast_checkout/internal:junit", "//chrome/browser/ui/android/favicon:java", + "//chrome/browser/ui/android/hats:factory_java", "//chrome/browser/ui/android/hats:junit", "//chrome/browser/ui/android/hats/internal:controller_java", "//chrome/browser/ui/android/hats/internal:junit", + "//chrome/browser/ui/android/hats/internal:test_support_java", "//chrome/browser/ui/android/layouts:java", "//chrome/browser/ui/android/layouts:junit", "//chrome/browser/ui/android/layouts/glue:java", @@ -2304,13 +2305,6 @@ deps = [] additional_extra_paks = [] - if (_is_monochrome) { - if (webview_includes_weblayer) { - additional_extra_paks += - [ "$root_gen_dir/weblayer/weblayer_resources.pak" ] - deps += [ "//weblayer:resources" ] - } - } if (!dfmify_dev_ui || !_is_bundle_module) { additional_extra_paks += [ "$root_gen_dir/chrome/dev_ui_resources.pak" ] deps += [ "//chrome/browser/resources:dev_ui_paks" ] @@ -2356,9 +2350,6 @@ ] if (_is_monochrome) { deps += [ "//android_webview:locale_pak_assets" ] - if (webview_includes_weblayer && !_is_bundle_module) { - deps += [ "//weblayer:locale_pak_assets" ] - } } } } @@ -2523,9 +2514,6 @@ "//components/version_info/android:version_constants_java", "//content/public/android:content_java", ] - if (webview_includes_weblayer) { - deps += [ "//weblayer/browser/java:base_module_java" ] - } } generate_jni("base_module_jni") { @@ -3750,11 +3738,6 @@ } defines = [] - if (webview_includes_weblayer) { - defines += [ "WEBVIEW_INCLUDES_WEBLAYER" ] - deps += [ "//weblayer:weblayer_lib" ] - } - if (android_64bit_target_cpu) { java_targets = [ "//chrome/android:monochrome_64_public_bundle" ] } else {
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 93c947da..1f12f2f 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -302,7 +302,6 @@ "junit/src/org/chromium/chrome/browser/suggestions/tile/MostVisitedMediatorUnitTest.java", "junit/src/org/chromium/chrome/browser/suggestions/tile/TileRendererTest.java", "junit/src/org/chromium/chrome/browser/supervised_user/ChildAccountServiceTest.java", - "junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java", "junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java", "junit/src/org/chromium/chrome/browser/sync/SyncErrorNotifierTest.java", "junit/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageImpressionTrackerTest.java",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index ba3b253..13ab7ec 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -16,7 +16,6 @@ import("//components/crash/android/silent_java_assert_reporting.gni") import("//components/optimization_guide/features.gni") import("//device/vr/buildflags/buildflags.gni") -import("//weblayer/variables.gni") import("channel.gni") declare_args() { @@ -293,10 +292,6 @@ shared_resources_allowlist_locales = platform_pak_locales product_config_java_packages += [ webview_product_config_java_package ] - - if (webview_includes_weblayer) { - product_config_java_packages += [ weblayer_product_config_java_package ] - } } if (enable_silent_java_assert_reporting) {
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index be17d17..4b00000 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -462,7 +462,6 @@ "javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java", "javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java", "javatests/src/org/chromium/chrome/browser/survey/ChromeStartupSurveyIntegrationTest.java", - "javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java", "javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java", "javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java index 64c8fff..c3b40f6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -108,6 +108,14 @@ private int mPageInsightsToken; /** + * Stores the timestamp when the first tab page load completed. If PIH instantiation is delayed + * due to enable conditions not being met for some time, it could miss the load completion + * event necessary to auto-trigger PIH sheet. This value is passed to PIH to take care of + * the autotriggering if such race condition occurs. + */ + private long mPageInsightsFirstLoadTimeMs; + + /** * Construct a new BaseCustomTabRootUiCoordinator. * @param activity The activity whose UI the coordinator is responsible for. * @param shareDelegateSupplier Supplies the {@link ShareDelegate}. @@ -256,17 +264,15 @@ public void onFinishNativeInitialization() { super.onFinishNativeInitialization(); - maybeCreatePageInsightsComponent(); if (isPageInsightsCapable(mIntentDataProvider.get())) { - // Start sWAA checking handler while page insight-capable CCT is in use. We give some - // delay in starting it to avoid the first call failing, which is observed sometimes. + var activator = PageInsightsActivator.getForProfile(mProfileSupplier.get()); + mPageInsightsToken = activator.start(() -> maybeCreatePageInsightsComponent()); Tab tab = mTabModelSelectorSupplier.get().getCurrentTab(); tab.addObserver(new EmptyTabObserver() { @Override public void onPageLoadFinished(Tab tab, GURL url) { + mPageInsightsFirstLoadTimeMs = System.currentTimeMillis(); tab.removeObserver(this); - var activator = PageInsightsActivator.getForProfile(mProfileSupplier.get()); - mPageInsightsToken = activator.start(() -> maybeCreatePageInsightsComponent()); } }); } @@ -297,7 +303,7 @@ mPageInsightsCoordinator = new PageInsightsCoordinator(mActivity, mActivityTabProvider, mShareDelegateSupplier, controller, getBottomSheetController(), mExpandedBottomSheetHelper, mBrowserControlsManager, mBrowserControlsManager, - this::isPageInsightsHubEnabled); + this::isPageInsightsHubEnabled, mPageInsightsFirstLoadTimeMs); mContextualSearchObserver = new ContextualSearchObserver() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java index 2b985e7..ec63f3e3e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
@@ -5,94 +5,41 @@ package org.chromium.chrome.browser.survey; import android.app.Activity; -import android.content.Context; import android.content.res.Resources; -import android.os.Handler; -import android.text.TextUtils; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import org.chromium.base.CommandLine; -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; import org.chromium.base.ResettersForTesting; -import org.chromium.base.task.AsyncTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; import org.chromium.chrome.browser.privacy.settings.PrivacyPreferencesManagerImpl; -import org.chromium.chrome.browser.tab.EmptyTabObserver; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabHidingType; -import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.ui.hats.MessageSurveyUiDelegate; import org.chromium.chrome.browser.ui.hats.SurveyClient; import org.chromium.chrome.browser.ui.hats.SurveyClientFactory; import org.chromium.chrome.browser.ui.hats.SurveyConfig; -import org.chromium.chrome.browser.ui.hats.SurveyController; -import org.chromium.chrome.browser.ui.hats.SurveyControllerProvider; -import org.chromium.chrome.browser.ui.hats.SurveyThrottler; -import org.chromium.chrome.browser.ui.hats.SurveyUiDelegate; -import org.chromium.components.messages.DismissReason; import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageIdentifier; -import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.ui.modelutil.PropertyModel; -import org.chromium.url.GURL; /** * Class that controls if and when to show surveys. One instance of this class is associated with * one trigger ID, which is used to fetch a survey, at the time it is created. - * - * @see #getTriggerId() */ public class ChromeSurveyController { - private static final String TAG = "ChromeSurveyCtrler"; private static final String TRIGGER_STARTUP_SURVEY = "startup_survey"; - @VisibleForTesting - public static final String COMMAND_LINE_PARAM_NAME = "survey_override_site_id"; - @VisibleForTesting - static final String MAX_DOWNLOAD_ATTEMPTS = "max-download-attempts"; - @VisibleForTesting - static final String MAX_NUMBER = "max-number"; - @VisibleForTesting - static final String SITE_ID_PARAM_NAME = "site-id"; - - private static @Nullable SurveyController sControllerForTesting; private static boolean sForceUmaEnabledForTesting; - private static boolean sMessageShown; - private TabModelSelector mTabModelSelector; - private Handler mLoggingHandler; - private Tab mSurveyPromptTab; - private TabModelSelectorObserver mTabModelObserver; + private final SurveyClient mSurveyClient; - private final String mTriggerId; - private final @Nullable ActivityLifecycleDispatcher mLifecycleDispatcher; - private final Activity mActivity; - private final MessageDispatcher mMessageDispatcher; - private SurveyController mSurveyController; - private SurveyThrottler mSurveyThrottler; - private @Nullable TabObserver mTabObserver; - private @Nullable PauseResumeWithNativeObserver mLifecycleObserver; + ChromeSurveyController(SurveyClient client) { + mSurveyClient = client; + } - @VisibleForTesting - ChromeSurveyController(String triggerId, - @Nullable ActivityLifecycleDispatcher lifecycleDispatcher, Activity activity, - MessageDispatcher messageDispatcher) { - mTriggerId = triggerId; - mLifecycleDispatcher = lifecycleDispatcher; - mActivity = activity; - mMessageDispatcher = messageDispatcher; - mSurveyThrottler = - new SurveyThrottler(triggerId, 1f / getMaxNumber(), getMaxDownloadAttempt()); + private void showSurvey(Activity activity, ActivityLifecycleDispatcher lifecycleDispatcher) { + mSurveyClient.showSurvey(activity, lifecycleDispatcher); } /** @@ -103,309 +50,38 @@ * @param activity The {@link Activity} on which the survey will be shown. * @param messageDispatcher The {@link MessageDispatcher} for displaying messages. */ - public static void initialize(TabModelSelector tabModelSelector, + public static ChromeSurveyController initialize(TabModelSelector tabModelSelector, @Nullable ActivityLifecycleDispatcher lifecycleDispatcher, Activity activity, MessageDispatcher messageDispatcher) { - assert tabModelSelector != null; + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_HATS_REFACTOR)) return null; - if (ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_HATS_REFACTOR)) { - SurveyConfig config = SurveyConfig.get(TRIGGER_STARTUP_SURVEY); - if (config == null) return; + SurveyConfig config = SurveyConfig.get(TRIGGER_STARTUP_SURVEY); + if (config == null) return null; - assert SurveyClientFactory.getInstance() != null; + assert SurveyClientFactory.getInstance() != null; - PropertyModel message = createBasicSurveyMessage(activity.getResources()); - SurveyUiDelegate messageDelegate = new MessageSurveyUiDelegate(message, - messageDispatcher, tabModelSelector, ChromeSurveyController::isUMAEnabled); - SurveyClient client = - SurveyClientFactory.getInstance().createClient(config, messageDelegate); - if (client != null) client.showSurvey(activity, lifecycleDispatcher); - return; - } + PropertyModel message = createBasicSurveyMessage(activity.getResources()); + MessageSurveyUiDelegate messageDelegate = new MessageSurveyUiDelegate( + message, messageDispatcher, tabModelSelector, ChromeSurveyController::isUMAEnabled); + SurveyClient client = + SurveyClientFactory.getInstance().createClient(config, messageDelegate); + if (client == null) return null; - if (!isSurveyEnabled() || TextUtils.isEmpty(getTriggerId())) return; - new StartDownloadIfEligibleTask(new ChromeSurveyController(getTriggerId(), - lifecycleDispatcher, activity, messageDispatcher), - tabModelSelector) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - /** - * Downloads the survey if the user qualifies. - * @param context The current Android {@link Context}. - * @param tabModelSelector The tab model selector to access the tab on which the survey will be - * shown. - */ - private void startDownload(Context context, TabModelSelector tabModelSelector) { - mSurveyThrottler.recordDownloadAttempted(); - mLoggingHandler = new Handler(); - mTabModelSelector = tabModelSelector; - - mSurveyController = sControllerForTesting != null ? sControllerForTesting - : SurveyControllerProvider.create(); - Runnable onSuccessRunnable = () -> onSurveyAvailable(mTriggerId); - Runnable onFailureRunnable = () -> Log.w(TAG, "Survey does not exists or download failed."); - mSurveyController.downloadSurvey(context, mTriggerId, onSuccessRunnable, onFailureRunnable); - } - - /** - * Called when the survey has finished downloading to show the survey prompt. - * @param siteId The site id of the survey to display. - */ - @VisibleForTesting - void onSurveyAvailable(String siteId) { - if (!isUMAEnabled() || attemptToShowOnTab(mTabModelSelector.getCurrentTab(), siteId)) { - return; - } - - mTabModelObserver = new TabModelSelectorObserver() { - @Override - public void onChange() { - attemptToShowOnTab(mTabModelSelector.getCurrentTab(), siteId); - } - }; - - // TODO(https://crbug.com/1192719): Remove the observer properly. - mTabModelSelector.addObserver(mTabModelObserver); - } - - /** - * Show the survey prompt on the passed in tab if the tab is finished loading. - * Else, it adds a listener to the tab to show the prompt once conditions are met. - * @param tab The tab to attempt to attach the survey prompt. - * @param siteId The site id of the survey to display. - * @return If the survey prompt was successfully shown. - */ - private boolean attemptToShowOnTab(Tab tab, String siteId) { - if (!isUMAEnabled()) { - if (mTabModelObserver != null) { - mTabModelSelector.removeObserver(mTabModelObserver); - mTabModelObserver = null; - } - return false; - } - if (!isValidTabForSurvey(tab)) return false; - - if (tab.isLoading() || !tab.isUserInteractable()) { - tab.addObserver(createTabObserver(tab, siteId)); - return false; - } - - showSurveyPrompt(tab, siteId); - return true; - } - - /** - * Shows the survey prompt as a message. - * @param tab The tab to attach the survey prompt. - * @param siteId The site id of the survey to display. - */ - @VisibleForTesting - void showSurveyPrompt(@NonNull Tab tab, String siteId) { - mSurveyPromptTab = tab; - - if (mMessageDispatcher == null) { - mTabModelSelector.removeObserver(mTabModelObserver); - return; - } - - // Return early if the message is already shown once. - if (sMessageShown) { - return; - } - - // Return early without displaying the message prompt if the survey has expired. - if (mSurveyController.isSurveyExpired(siteId)) { - return; - } - PropertyModel message = createBasicSurveyMessage(mActivity.getResources()); - message.set(MessageBannerProperties.ON_PRIMARY_ACTION, () -> { - showSurvey(siteId); - return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; - }); - message.set(MessageBannerProperties.ON_DISMISSED, this::onMessageDismissed); - - // Dismiss the message when the original tab in which the message is shown is - // hidden. This prevents the prompt from being shown if the tab is opened after being - // hidden for a duration in which the survey expired. See crbug.com/1249055 for details. - mTabObserver = new EmptyTabObserver() { - @Override - public void onHidden(Tab tab, @TabHidingType int type) { - mMessageDispatcher.dismissMessage(message, DismissReason.TAB_SWITCHED); - } - }; - - // This observer will be added exactly once because of the `sMessageShown` conditional above - // that restricts enqueueing the message only once in a session. The observer will be - // removed when the enqueued message is dismissed. - mSurveyPromptTab.addObserver(mTabObserver); - - if (mLifecycleDispatcher != null) { - mLifecycleObserver = new PauseResumeWithNativeObserver() { - @Override - public void onResumeWithNative() { - if (mSurveyController.isSurveyExpired(siteId)) { - mMessageDispatcher.dismissMessage( - message, DismissReason.DISMISSED_BY_FEATURE); - } - } - - @Override - public void onPauseWithNative() {} - }; - mLifecycleDispatcher.register(mLifecycleObserver); - } - - mMessageDispatcher.enqueueWindowScopedMessage(message, false); - sMessageShown = true; - } - - /** - * Shows the survey and closes the survey prompt. - * @param siteId The site id of the survey to display. - */ - private void showSurvey(String siteId) { - mSurveyController.showSurveyIfAvailable( - mActivity, siteId, R.drawable.chrome_sync_logo, mLifecycleDispatcher, null); + ChromeSurveyController chromeSurveyController = new ChromeSurveyController(client); + chromeSurveyController.showSurvey(activity, lifecycleDispatcher); + return chromeSurveyController; } private static PropertyModel createBasicSurveyMessage(Resources resources) { - PropertyModel message = - new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS) - .with(MessageBannerProperties.MESSAGE_IDENTIFIER, - MessageIdentifier.CHROME_SURVEY) - .with(MessageBannerProperties.TITLE, - resources.getString(R.string.chrome_survey_message_title)) - .with(MessageBannerProperties.ICON_RESOURCE_ID, R.drawable.chrome_sync_logo) - .with(MessageBannerProperties.ICON_TINT_COLOR, - MessageBannerProperties.TINT_NONE) - .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, - resources.getString(R.string.chrome_survey_message_button)) - .build(); - return message; - } - - /** - * Perform tasks after the message is dismissed. - * @param dismissReason The reason for dismissal of the survey prompt. - */ - private void onMessageDismissed(@DismissReason int dismissReason) { - if (mSurveyPromptTab != null && mTabObserver != null) { - mSurveyPromptTab.removeObserver(mTabObserver); - mTabObserver = null; - } - if (mLifecycleDispatcher != null && mLifecycleObserver != null) { - mLifecycleDispatcher.unregister(mLifecycleObserver); - mLifecycleObserver = null; - } - if (dismissReason == DismissReason.GESTURE || dismissReason == DismissReason.TIMER - || dismissReason == DismissReason.TAB_SWITCHED) { - recordSurveyPromptDisplayed(); - } else if (dismissReason == DismissReason.PRIMARY_ACTION) { - recordSurveyPromptDisplayed(); - mSurveyThrottler.recordSurveyAccepted(); - } - } - - /** - * @return The observer that handles cases where the user switches tabs before the prompt is - * shown. - */ - private TabObserver createTabObserver(Tab tab, String siteId) { - return new EmptyTabObserver() { - @Override - public void onInteractabilityChanged(Tab tab, boolean isInteractable) { - showPromptIfApplicable(tab, siteId, this); - } - - @Override - public void onPageLoadFinished(Tab tab, GURL url) { - showPromptIfApplicable(tab, siteId, this); - } - - @Override - public void onHidden(Tab tab, @TabHidingType int type) { - // A prompt shouldn't appear on a tab that the user left. - tab.removeObserver(this); - } - }; - } - - private SurveyThrottler getThrottler() { - return mSurveyThrottler; - } - - /** - * Shows the prompt if the passed in tab is fully loaded and interactable. - * @param tab The tab to attach the survey info bar. - * @param siteId The site id of the survey to display. - * @param observer The tab observer to remove from the passed in tab. - */ - @VisibleForTesting - void showPromptIfApplicable(Tab tab, String siteId, TabObserver observer) { - if (!tab.isUserInteractable() || tab.isLoading()) return; - if (isUMAEnabled()) { - showSurveyPrompt(tab, siteId); - } - tab.removeObserver(observer); - } - - /** - * Checks if the tab is valid for a survey (i.e. not null, no null webcontents & not incognito). - * @param tab The tab to be checked. - * @return Whether or not the tab is valid. - */ - @VisibleForTesting - boolean isValidTabForSurvey(Tab tab) { - return tab != null && tab.getWebContents() != null && !tab.isIncognito(); - } - - /** Logs in SharedPreferences that the info bar was displayed. */ - @VisibleForTesting - void recordSurveyPromptDisplayed() { - // This can be called multiple times e.g. by mLoggingHandler. - // Return early to allow only one call to this method (http://crbug.com/791076). - if (mSurveyPromptTab == null) return; - - mLoggingHandler.removeCallbacksAndMessages(null); - - mSurveyThrottler.recordSurveyPromptDisplayed(); - mSurveyPromptTab = null; - } - - @VisibleForTesting - void setTabModelSelector(TabModelSelector tabModelSelector) { - mTabModelSelector = tabModelSelector; - } - - static class StartDownloadIfEligibleTask extends AsyncTask<Boolean> { - ChromeSurveyController mController; - final TabModelSelector mSelector; - - public StartDownloadIfEligibleTask( - ChromeSurveyController controller, TabModelSelector tabModelSelector) { - mController = controller; - mSelector = tabModelSelector; - } - - @Override - protected Boolean doInBackground() { - return isUMAEnabled() && mController.getThrottler().canShowSurvey(); - } - - @Override - protected void onPostExecute(Boolean result) { - if (result) { - mController.startDownload(ContextUtils.getApplicationContext(), mSelector); - } - } - } - - /** @return If the survey is enabled by finch flag or commandline switch. */ - @VisibleForTesting - static boolean isSurveyEnabled() { - return isSurveyForceEnabled() - || ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID); + return new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS) + .with(MessageBannerProperties.MESSAGE_IDENTIFIER, MessageIdentifier.CHROME_SURVEY) + .with(MessageBannerProperties.TITLE, + resources.getString(R.string.chrome_survey_message_title)) + .with(MessageBannerProperties.ICON_RESOURCE_ID, R.drawable.chrome_sync_logo) + .with(MessageBannerProperties.ICON_TINT_COLOR, MessageBannerProperties.TINT_NONE) + .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, + resources.getString(R.string.chrome_survey_message_button)) + .build(); } /** @return Whether metrics and crash dumps are enabled. */ @@ -414,56 +90,9 @@ || PrivacyPreferencesManagerImpl.getInstance().isUsageAndCrashReportingPermitted(); } - /** @return Whether survey is enabled by command line flag. */ - public static boolean isSurveyForceEnabled() { - return CommandLine.getInstance().hasSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY); - } - - /** @return The trigger Id that used to download / display certain survey. */ - @VisibleForTesting - static String getTriggerId() { - CommandLine commandLine = CommandLine.getInstance(); - if (commandLine.hasSwitch(COMMAND_LINE_PARAM_NAME)) { - return commandLine.getSwitchValue(COMMAND_LINE_PARAM_NAME); - } else { - return ChromeFeatureList.getFieldTrialParamByFeature( - ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID, SITE_ID_PARAM_NAME); - } - } - - /** @return The max number that used to control the rate limit from the finch config. */ - private static int getMaxNumber() { - return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( - ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID, MAX_NUMBER, -1); - } - - private static int getMaxDownloadAttempt() { - return ChromeFeatureList.getFieldTrialParamByFeatureAsInt( - ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID, MAX_DOWNLOAD_ATTEMPTS, 0); - } - - /** @return Whether the message has been previously shown to the client. */ - @VisibleForTesting - public static boolean isMessageShown() { - return sMessageShown; - } - /** Set whether UMA consent is granted during tests. Reset to "false" after tests. */ public static void forceIsUMAEnabledForTesting(boolean forcedUMAStatus) { sForceUmaEnabledForTesting = forcedUMAStatus; ResettersForTesting.register(() -> sForceUmaEnabledForTesting = false); } - - /** Reset the tracker whether HaTS messages has shown during tests. */ - public static void resetMessageShownForTesting() { - sMessageShown = false; - } - - /** - * Set the test only survey controller to use instead of creating new SurveyController. - */ - public static void setSurveyControllerForTesting(SurveyController surveyController) { - sControllerForTesting = surveyController; - ResettersForTesting.register(() -> sControllerForTesting = null); - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java deleted file mode 100644 index 33b7189..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java +++ /dev/null
@@ -1,190 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.survey; - -import android.app.Activity; -import android.content.Context; - -import androidx.test.filters.MediumTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.Batch; -import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.Restriction; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; -import org.chromium.chrome.browser.preferences.SharedPreferencesManager; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.ui.hats.SurveyController; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; -import org.chromium.components.messages.DismissReason; -import org.chromium.components.messages.MessageBannerProperties; -import org.chromium.components.messages.MessageDispatcher; -import org.chromium.components.messages.MessageDispatcherProvider; -import org.chromium.components.messages.MessageIdentifier; -import org.chromium.components.messages.MessageStateHandler; -import org.chromium.components.messages.MessagesTestHelper; -import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.ui.modelutil.PropertyModel; -import org.chromium.ui.test.util.UiRestriction; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -/** Integration test for {@link ChromeSurveyController}. */ -// clang-format off -@RunWith(ChromeJUnit4ClassRunner.class) -@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) -@EnableFeatures(ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID) -@DisableFeatures(ChromeFeatureList.ANDROID_HATS_REFACTOR) -@CommandLineFlags.Add({ - ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY, - ChromeSurveyController.COMMAND_LINE_PARAM_NAME + "=" + - ChromeSurveyControllerIntegrationTest.TEST_TRIGGER_ID}) -// Batched PER_CLASS because survey initialization is triggered at ChromeTabbedActivity creation. -// Can be updated to UNIT_TESTS when the dependency on CTA creation is removed. -@Batch(Batch.PER_CLASS) -public class ChromeSurveyControllerIntegrationTest { - // clang-format on - static final String TEST_TRIGGER_ID = "test_trigger_id"; - static final long MESSAGE_AUTO_DISMISS_DURATION_MS = 10000L; - - @Rule - public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); - - private SharedPreferencesManager mSharedPreferenceManager = - SharedPreferencesManager.getInstance(); - private AlwaysSuccessfulSurveyController mTestSurveyController; - private String mPrefKey; - private MessageDispatcher mMessageDispatcher; - - @Before - public void setUp() throws InterruptedException, TimeoutException, ExecutionException { - ChromeSurveyController.forceIsUMAEnabledForTesting(true); - mPrefKey = ChromePreferenceKeys.CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.createKey( - TEST_TRIGGER_ID); - mSharedPreferenceManager = SharedPreferencesManager.getInstance(); - - mTestSurveyController = new AlwaysSuccessfulSurveyController(); - ChromeSurveyController.setSurveyControllerForTesting(mTestSurveyController); - - mActivityTestRule.startMainActivityOnBlankPage(); - - mMessageDispatcher = TestThreadUtils.runOnUiThreadBlocking( - () - -> MessageDispatcherProvider.from( - mActivityTestRule.getActivity().getWindowAndroid())); - - waitUntilSurveyPromptPresented(); - } - - @After - public void tearDown() { - mSharedPreferenceManager.removeKey(mPrefKey); - ChromeSurveyController.resetMessageShownForTesting(); - } - - @Test - @MediumTest - public void testMessagePrimaryButtonClicked() { - PropertyModel message = getSurveyMessage(); - Assert.assertNotNull("Message should not be null.", message); - - // Simulate the message primary button click. - TestThreadUtils.runOnUiThreadBlocking( - () -> { message.get(MessageBannerProperties.ON_PRIMARY_ACTION).get(); }); - // Simulate message dismissal on primary button click. - TestThreadUtils.runOnUiThreadBlocking( - () -> mMessageDispatcher.dismissMessage(message, DismissReason.PRIMARY_ACTION)); - - Assert.assertEquals("#showSurveyIfAvailable should be attempted.", 1, - mTestSurveyController.showSurveyCallbackHelper.getCallCount()); - } - - @Test - @MediumTest - public void testMessageDismissed() { - PropertyModel message = getSurveyMessage(); - Assert.assertNotNull("Message should not be null.", message); - TestThreadUtils.runOnUiThreadBlocking( - () -> mMessageDispatcher.dismissMessage(message, DismissReason.GESTURE)); - } - - @Test - @MediumTest - public void testNoMessageInNewTab() throws InterruptedException { - // Simulate message visibility for the auto-dismiss duration length of time. - waitUntilSurveyPromptStateRecorded(MESSAGE_AUTO_DISMISS_DURATION_MS); - - // Survey prompt should not be displayed in another tab. - Tab tabTwo = mActivityTestRule.loadUrlInNewTab("about:blank", false); - - waitUntilTabIsReady(tabTwo); - Assert.assertNull("Tab two should not have the message.", getSurveyMessage()); - } - - private void waitUntilSurveyPromptPresented() throws TimeoutException { - Tab tab = mActivityTestRule.getActivity().getActivityTab(); - waitUntilTabIsReady(tab); - mTestSurveyController.downloadCallbackHelper.waitForFirst(); - // After getting the survey response, it might take momentarily longer for the message to be - // shown. Wait until the message is shown before proceeding. - CriteriaHelper.pollUiThread( - () -> getSurveyMessage() != null, "Survey message should be shown."); - Assert.assertNotNull("Tab should have a message.", getSurveyMessage()); - } - - private void waitUntilSurveyPromptStateRecorded(long visibilityDuration) - throws InterruptedException { - Thread.sleep(visibilityDuration); - CriteriaHelper.pollUiThread( - () -> SharedPreferencesManager.getInstance().contains(mPrefKey)); - } - - private void waitUntilTabIsReady(Tab tab) { - CriteriaHelper.pollUiThread(() -> !tab.isLoading() && tab.isUserInteractable()); - } - - private PropertyModel getSurveyMessage() { - List<MessageStateHandler> messages = MessagesTestHelper.getEnqueuedMessages( - mMessageDispatcher, MessageIdentifier.CHROME_SURVEY); - return messages.size() == 0 ? null : MessagesTestHelper.getCurrentMessage(messages.get(0)); - } - - private static class AlwaysSuccessfulSurveyController implements SurveyController { - public final CallbackHelper downloadCallbackHelper = new CallbackHelper(); - public final CallbackHelper showSurveyCallbackHelper = new CallbackHelper(); - - @Override - public void downloadSurvey(Context context, String triggerId, Runnable onSuccessRunnable, - Runnable onFailureRunnable) { - downloadCallbackHelper.notifyCalled(); - - Assert.assertEquals(TEST_TRIGGER_ID, triggerId); - onSuccessRunnable.run(); - } - - @Override - public void showSurveyIfAvailable(Activity activity, String siteId, int displayLogoResId, - ActivityLifecycleDispatcher lifecycleDispatcher, Map<String, String> surveyPsd) { - showSurveyCallbackHelper.notifyCalled(); - } - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java index 57b1e6dc..a724b92 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java
@@ -173,8 +173,8 @@ ThreadUtils.runOnUiThreadBlocking(() -> { CriticalPersistedTabData criticalPersistedTabData = new CriticalPersistedTabData( new MockTab(TAB_ID, isEncrypted), "", "", ROOT_ID, WEB_CONTENTS_STATE, - CONTENT_STATE_VERSION, OPENER_APP_ID, THEME_COLOR, LAUNCH_TYPE_AT_CREATION, - USER_AGENT_A, LAST_NAVIGATION_COMMITTED_TIMESTAMP); + CONTENT_STATE_VERSION, OPENER_APP_ID, LAUNCH_TYPE_AT_CREATION, USER_AGENT_A, + LAST_NAVIGATION_COMMITTED_TIMESTAMP); criticalPersistedTabData.setShouldSaveForTesting(true); mStorage.setSemaphore(saveSemaphore); ObservableSupplierImpl<Boolean> supplier = new ObservableSupplierImpl<>(); @@ -188,7 +188,6 @@ Assert.assertNotNull(mCriticalPersistedTabData); assertEquals(mCriticalPersistedTabData.getContentStateVersion(), CONTENT_STATE_VERSION); assertEquals(mCriticalPersistedTabData.getOpenerAppId(), OPENER_APP_ID); - assertEquals(mCriticalPersistedTabData.getThemeColor(), THEME_COLOR); assertEquals( mCriticalPersistedTabData.getTabLaunchTypeAtCreation(), LAUNCH_TYPE_AT_CREATION); Assert.assertArrayEquals(CriticalPersistedTabData.getContentStateByteArray( @@ -309,7 +308,7 @@ public void testSerializationBug() throws InterruptedException { Tab tab = mockTab(TAB_ID, false); CriticalPersistedTabData criticalPersistedTabData = new CriticalPersistedTabData(tab, "", - "", ROOT_ID, WEB_CONTENTS_STATE, CONTENT_STATE_VERSION, OPENER_APP_ID, THEME_COLOR, + "", ROOT_ID, WEB_CONTENTS_STATE, CONTENT_STATE_VERSION, OPENER_APP_ID, LAUNCH_TYPE_AT_CREATION, USER_AGENT_A, LAST_NAVIGATION_COMMITTED_TIMESTAMP); Serializer<ByteBuffer> serializer = criticalPersistedTabData.getSerializer(); serializer.preSerialize(); @@ -321,7 +320,6 @@ Assert.assertNotNull(deserialized); assertEquals(CONTENT_STATE_VERSION, deserialized.getContentStateVersion()); assertEquals(OPENER_APP_ID, deserialized.getOpenerAppId()); - assertEquals(THEME_COLOR, deserialized.getThemeColor()); assertEquals(LAUNCH_TYPE_AT_CREATION, deserialized.getTabLaunchTypeAtCreation()); Assert.assertArrayEquals(WEB_CONTENTS_STATE_BYTES, CriticalPersistedTabData.getContentStateByteArray( @@ -344,8 +342,8 @@ try (StrictModeContext ignored = StrictModeContext.allowAllThreadPolicies()) { CriticalPersistedTabData criticalPersistedTabData = new CriticalPersistedTabData( tab, "", "", ROOT_ID, TabStateExtractor.getWebContentsState(tab), - CONTENT_STATE_VERSION, OPENER_APP_ID, THEME_COLOR, LAUNCH_TYPE_AT_CREATION, - USER_AGENT_A, LAST_NAVIGATION_COMMITTED_TIMESTAMP); + CONTENT_STATE_VERSION, OPENER_APP_ID, LAUNCH_TYPE_AT_CREATION, USER_AGENT_A, + LAST_NAVIGATION_COMMITTED_TIMESTAMP); PersistedTabDataConfiguration config = PersistedTabDataConfiguration.get( CriticalPersistedTabData.class, tab.isIncognito()); FilePersistedTabDataStorage persistedTabDataStorage = @@ -360,9 +358,6 @@ semaphore.acquire(); ThreadUtils.runOnUiThreadBlocking(() -> { try (StrictModeContext ignored = StrictModeContext.allowAllThreadPolicies()) { - PersistedTabDataConfiguration config = PersistedTabDataConfiguration.get( - CriticalPersistedTabData.class, tab.isIncognito()); - SerializedCriticalPersistedTabData serialized = CriticalPersistedTabData.restore(tab.getId(), tab.isIncognito()); CriticalPersistedTabData deserialized = @@ -380,7 +375,7 @@ public void testOpenerAppIdNull() { Tab tab = mockTab(TAB_ID, false); CriticalPersistedTabData criticalPersistedTabData = new CriticalPersistedTabData(tab, "", - "", ROOT_ID, WEB_CONTENTS_STATE, CONTENT_STATE_VERSION, null, THEME_COLOR, + "", ROOT_ID, WEB_CONTENTS_STATE, CONTENT_STATE_VERSION, null, LAUNCH_TYPE_AT_CREATION, USER_AGENT_A, LAST_NAVIGATION_COMMITTED_TIMESTAMP); Serializer<ByteBuffer> serializer = criticalPersistedTabData.getSerializer(); serializer.preSerialize(); @@ -763,7 +758,6 @@ CriticalPersistedTabData deserialized = CriticalPersistedTabData.from(tab); assertEquals(CONTENT_STATE_VERSION, deserialized.getContentStateVersion()); assertEquals(OPENER_APP_ID, deserialized.getOpenerAppId()); - assertEquals(THEME_COLOR, deserialized.getThemeColor()); assertEquals(LaunchTypeAtCreationTest.FROM_LINK, (int) deserialized.getTabLaunchTypeAtCreation()); assertEquals(TabUserAgent.DEFAULT, deserialized.getUserAgent());
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java deleted file mode 100644 index 9d74794..0000000 --- a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java +++ /dev/null
@@ -1,670 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.survey; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.app.Activity; -import android.content.Context; - -import androidx.annotation.Nullable; -import androidx.test.core.app.ApplicationProvider; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.robolectric.annotation.Config; -import org.robolectric.annotation.LooperMode; -import org.robolectric.shadows.ShadowLooper; - -import org.chromium.base.CommandLine; -import org.chromium.base.FeatureList; -import org.chromium.base.FeatureList.TestValues; -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.base.metrics.UmaRecorderHolder; -import org.chromium.base.task.test.BackgroundShadowAsyncTask; -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.JniMocker; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; -import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; -import org.chromium.chrome.browser.preferences.SharedPreferencesManager; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabHidingType; -import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; -import org.chromium.chrome.browser.ui.hats.SurveyController; -import org.chromium.components.messages.DismissReason; -import org.chromium.components.messages.MessageBannerProperties; -import org.chromium.components.messages.MessageDispatcher; -import org.chromium.components.messages.MessageIdentifier; -import org.chromium.components.messages.PrimaryActionClickBehavior; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.modelutil.PropertyModel; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -/** - * "Integration" style unit tests for {@link ChromeSurveyController} that mocks most of the - * info bar related code, aiming to cover the workflow from initialize survey download task. - */ -// clang-format off -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE, shadows = {BackgroundShadowAsyncTask.class}) -//TODO(crbug.com/1210371): Rewrite using paused loop. See crbug for details. -@LooperMode(LooperMode.Mode.LEGACY) -// Set user is selected and by pass the rate limit. The rate limiting logic is tested in -// ChromeSurveyControllerTest. -@CommandLineFlags.Add(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY) -public class ChromeSurveyControllerFlowTest { - // clang-format on - private static final String TEST_TRIGGER_ID = "test_trigger_id"; - - @Rule - public MockitoRule mRule = MockitoJUnit.rule(); - @Rule - public JniMocker mocker = new JniMocker(); - - @Mock - TabModelSelector mMockModelSelector; - @Mock - Tab mMockTab; - @Mock - WebContents mMockWebContent; - @Mock - ActivityLifecycleDispatcher mMockLifecycleDispatcher; - @Mock - Activity mActivity; - @Mock - MessageDispatcher mMessageDispatcher; - @Captor - ArgumentCaptor<PropertyModel> mMessagePropertyCaptor; - - private final TestSurveyController mTestSurveyController = new TestSurveyController(); - - private String mPrefKeyPromptShown; - private String mPrefKeyDownloadAttempts; - private SharedPreferencesManager mSharedPreferencesManager; - - private TabModelSelectorObserver mTabModelSelectorObserver; - private TabObserver mTabObserver; - private PauseResumeWithNativeObserver mLifecycleObserver; - - Map<String, String> mFieldTrialParams; - - @Before - public void setup() { - mFieldTrialParams = new HashMap<>(); - mFieldTrialParams.put(ChromeSurveyController.SITE_ID_PARAM_NAME, TEST_TRIGGER_ID); - // By setting MAX_NUMBER to 1, #isRandomSelectedBySurvey is always true. - mFieldTrialParams.put(ChromeSurveyController.MAX_NUMBER, "1"); - enableChromeSurveyNextFeatureWithParams(mFieldTrialParams, true); - - ChromeSurveyController.setSurveyControllerForTesting(mTestSurveyController); - - ChromeSurveyController.forceIsUMAEnabledForTesting(true); - mPrefKeyPromptShown = - ChromePreferenceKeys.CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.createKey( - TEST_TRIGGER_ID); - mPrefKeyDownloadAttempts = - ChromePreferenceKeys.CHROME_SURVEY_DOWNLOAD_ATTEMPTS.createKey(TEST_TRIGGER_ID); - mSharedPreferencesManager = SharedPreferencesManager.getInstance(); - - Mockito.when(mActivity.getResources()) - .thenReturn(ApplicationProvider.getApplicationContext().getResources()); - } - - @After - public void tearDown() { - ChromeSurveyController.resetMessageShownForTesting(); - FeatureList.setTestValues(null); - UmaRecorderHolder.resetForTesting(); - - CommandLine.getInstance().removeSwitch(ChromeSurveyController.COMMAND_LINE_PARAM_NAME); - } - - @Test - public void testCommandLine_GetTriggerId() { - Assert.assertEquals("TriggerId does not match feature flag setting.", TEST_TRIGGER_ID, - ChromeSurveyController.getTriggerId()); - - final String commandLineTriggerId = "command_line_trigger_id"; - CommandLine.getInstance().appendSwitchWithValue( - ChromeSurveyController.COMMAND_LINE_PARAM_NAME, commandLineTriggerId); - Assert.assertEquals("TriggerId does not match commandline overrides.", commandLineTriggerId, - ChromeSurveyController.getTriggerId()); - } - - @Test - public void testCommandLine_ForceEnableSurvey() { - CommandLine.getInstance().removeSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY); - Assert.assertTrue("Survey should be enabled by feature flag.", - ChromeSurveyController.isSurveyEnabled()); - - enableChromeSurveyNextFeatureWithParams(null, false); - Assert.assertFalse("Survey should be disabled by feature flag.", - ChromeSurveyController.isSurveyEnabled()); - - CommandLine.getInstance().appendSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY); - Assert.assertTrue("Survey should be enabled by commandline switch.", - ChromeSurveyController.isSurveyEnabled()); - } - - @Test - public void testStartDownloadIfEligibleTask() { - assertDownloadAttempted(false); - initializeChromeSurveyController(); - assertDownloadAttempted(true); - } - - @Test - public void testStartDownloadIfEligibleTask_ShowedBefore() { - CommandLine.getInstance().removeSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY); - mSharedPreferencesManager.writeLong(mPrefKeyPromptShown, 1000L); - - initializeChromeSurveyController(); - assertDownloadAttempted(false); - } - - @Test - public void testStartDownloadIfEligibleTask_ShowedBefore_ForceEnabled() { - mSharedPreferencesManager.writeLong(mPrefKeyPromptShown, 1000L); - - assertDownloadAttempted(false); - initializeChromeSurveyController(); - assertDownloadAttempted(true); - } - - @Test - public void testStartDownloadIfEligibleTask_UmaDisabled() { - ChromeSurveyController.forceIsUMAEnabledForTesting(false); - mSharedPreferencesManager.writeBoolean( - ChromePreferenceKeys.PRIVACY_METRICS_REPORTING_PERMITTED_BY_USER, false); - - initializeChromeSurveyController(); - assertDownloadAttempted(false); - } - - @Test - public void testStartDownloadIfEligibleTask_UmaEnabled() { - ChromeSurveyController.forceIsUMAEnabledForTesting(false); - mSharedPreferencesManager.writeBoolean( - ChromePreferenceKeys.PRIVACY_METRICS_REPORTING_PERMITTED_BY_USER, true); - - assertDownloadAttempted(false); - initializeChromeSurveyController(); - assertDownloadAttempted(true); - } - - @Test - public void testStartDownloadIfEligibleTask_DownloadCapZero() { - CommandLine.getInstance().removeSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY); - mFieldTrialParams.put(ChromeSurveyController.MAX_DOWNLOAD_ATTEMPTS, "0"); - enableChromeSurveyNextFeatureWithParams(mFieldTrialParams, true); - - initializeChromeSurveyController(); - assertDownloadAttempted(true); - } - - @Test - public void testStartDownloadIfEligibleTask_DownloadWithinCap() { - CommandLine.getInstance().removeSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY); - mFieldTrialParams.put(ChromeSurveyController.MAX_DOWNLOAD_ATTEMPTS, "99"); - enableChromeSurveyNextFeatureWithParams(mFieldTrialParams, true); - - assertDownloadAttempted(false); - initializeChromeSurveyController(); - assertDownloadAttempted(true); - } - - @Test - public void testStartDownloadIfEligibleTask_DownloadReachCap() { - CommandLine.getInstance().removeSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY); - mFieldTrialParams.put(ChromeSurveyController.MAX_DOWNLOAD_ATTEMPTS, "2"); - enableChromeSurveyNextFeatureWithParams(mFieldTrialParams, true); - mSharedPreferencesManager.writeInt(mPrefKeyDownloadAttempts, 2); - - initializeChromeSurveyController(); - Assert.assertEquals("Download should not be triggered.", 0, - mTestSurveyController.downloadIfApplicableCallback.getCallCount()); - } - - @Test - public void testStartDownloadIfEligibleTask_DownloadCapZero_ForceEnable() { - mFieldTrialParams.put(ChromeSurveyController.MAX_DOWNLOAD_ATTEMPTS, "0"); - enableChromeSurveyNextFeatureWithParams(mFieldTrialParams, true); - - assertDownloadAttempted(false); - initializeChromeSurveyController(); - assertDownloadAttempted(true); - } - - @Test - public void testSurveyMessagesUI() { - setupTabMocks(); - initializeChromeSurveyController(); - assertCallbackAssignedInSurveyController(); - - // Verify the survey should be attempted to present on a valid tab. - mockTabReady(); - Assert.assertNotNull(mMessageDispatcher); - mTestSurveyController.onDownloadSuccessRunnable.run(); - assertSurveyMessageEnqueued(true); - } - - @Test - public void testPresentSurvey_LoadingTab() { - setupTabMocks(); - initializeChromeSurveyController(); - assertCallbackAssignedInSurveyController(); - - // Verify the survey should be attempted to present on a valid tab. - Mockito.doReturn(true).when(mMockTab).isLoading(); - mTestSurveyController.onDownloadSuccessRunnable.run(); - - assertSurveyMessageEnqueued(false); - Assert.assertNotNull("Tab observer should be registered.", mTabObserver); - - // Assume tab loading is complete. - mockTabReady(); - mTabObserver.onPageLoadFinished(mMockTab, null); - assertSurveyMessageEnqueued(true); - } - - @Test - public void testPresentSurvey_TabInteractabilityChanged() { - setupTabMocks(); - initializeChromeSurveyController(); - assertCallbackAssignedInSurveyController(); - - // Verify the survey should be attempted to present on a valid tab. - Mockito.doReturn(false).when(mMockTab).isUserInteractable(); - mTestSurveyController.onDownloadSuccessRunnable.run(); - - assertSurveyMessageEnqueued(false); - Assert.assertNotNull("Tab observer should be registered.", mTabObserver); - - // Assume tab loading is complete. - mockTabReady(); - mTabObserver.onInteractabilityChanged(mMockTab, true); - assertSurveyMessageEnqueued(true); - } - - @Test - public void testPresentSurvey_SwitchingTab() { - setupTabMocks(); - initializeChromeSurveyController(); - assertCallbackAssignedInSurveyController(); - - // Verify the survey should be attempted to present on a valid tab. - Mockito.when(mMockModelSelector.getCurrentTab()).thenReturn(null); - mTestSurveyController.onDownloadSuccessRunnable.run(); - - assertSurveyMessageEnqueued(false); - Assert.assertNotNull( - "TabModelSelectorObserver should be registered.", mTabModelSelectorObserver); - - // Assume tab selector can provide a tab (e.g. switch to a fully loaded tab). - mockTabReady(); - Mockito.when(mMockModelSelector.getCurrentTab()).thenReturn(mMockTab); - mTabModelSelectorObserver.onChange(); - assertSurveyMessageEnqueued(true); - } - - @Test - public void testPresentSurvey_UmaDisabledBeforeTabReady() { - setupTabMocks(); - initializeChromeSurveyController(); - assertCallbackAssignedInSurveyController(); - - // Verify the survey should be attempted to present on a valid tab. - Mockito.when(mMockModelSelector.getCurrentTab()).thenReturn(null); - mTestSurveyController.onDownloadSuccessRunnable.run(); - - assertSurveyMessageEnqueued(false); - Assert.assertNotNull( - "TabModelSelectorObserver should be registered.", mTabModelSelectorObserver); - - // Assume user turn off UMA upload before survey is shown. - ChromeSurveyController.forceIsUMAEnabledForTesting(false); - - mockTabReady(); - Mockito.when(mMockModelSelector.getCurrentTab()).thenReturn(mMockTab); - mTabModelSelectorObserver.onChange(); - assertSurveyMessageEnqueued(false); - Assert.assertNull("TabModelSelectorObserver is unregistered since UMA upload is disabled.", - mTabModelSelectorObserver); - } - - @Test - public void testMessages_PrimaryAction() { - presentMessages(); - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - - messageModel.get(MessageBannerProperties.ON_DISMISSED) - .onResult(DismissReason.PRIMARY_ACTION); - assertPromptDisplayedRecorded(); - assertDownloadAttemptRecordedWithSample(1); - } - - @Test - public void testMessages_PrimaryAction_DownloadBefore() { - final int downloadAttempted = 3; - mSharedPreferencesManager.writeInt(mPrefKeyDownloadAttempts, downloadAttempted); - - presentMessages(); - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - - messageModel.get(MessageBannerProperties.ON_DISMISSED) - .onResult(DismissReason.PRIMARY_ACTION); - assertPromptDisplayedRecorded(); - assertDownloadAttemptRecordedWithSample(downloadAttempted + 1); - } - - @Test - public void testMessages_Properties() { - presentMessages(); - - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - Assert.assertEquals("Message identifier is different.", MessageIdentifier.CHROME_SURVEY, - messageModel.get(MessageBannerProperties.MESSAGE_IDENTIFIER)); - Assert.assertEquals("Message icon resource is different.", R.drawable.chrome_sync_logo, - messageModel.get(MessageBannerProperties.ICON_RESOURCE_ID)); - Assert.assertEquals("Message icon tint is different.", MessageBannerProperties.TINT_NONE, - messageModel.get(MessageBannerProperties.ICON_TINT_COLOR)); - Assert.assertEquals("Message title string is different.", - ApplicationProvider.getApplicationContext().getResources().getString( - R.string.chrome_survey_message_title), - messageModel.get(MessageBannerProperties.TITLE)); - Assert.assertEquals("Message action button string is different.", - ApplicationProvider.getApplicationContext().getResources().getString( - R.string.chrome_survey_message_button), - messageModel.get(MessageBannerProperties.PRIMARY_BUTTON_TEXT)); - - Assert.assertNotNull("Message primary action is null.", - messageModel.get(MessageBannerProperties.ON_PRIMARY_ACTION)); - Assert.assertNotNull("Message dismissal action is null.", - messageModel.get(MessageBannerProperties.ON_DISMISSED)); - - Assert.assertEquals("Message ON_PRIMARY_ACTION should return DISMISS_IMMEDIATELY.", - PrimaryActionClickBehavior.DISMISS_IMMEDIATELY, - messageModel.get(MessageBannerProperties.ON_PRIMARY_ACTION).get().intValue()); - Assert.assertEquals("showSurvey should be called.", 1, - mTestSurveyController.showSurveyIfAvailableCallback.getCallCount()); - } - - @Test - public void testMessages_NotShownOnExpiredSurvey() { - setupTabMocks(); - initializeChromeSurveyController(); - assertCallbackAssignedInSurveyController(); - mockTabReady(); - // Simulate an expired survey. - mTestSurveyController.isSurveyExpired = true; - mTestSurveyController.onDownloadSuccessRunnable.run(); - verifyNoMoreInteractions(mMessageDispatcher); - Assert.assertEquals("showSurvey should not be called.", 0, - mTestSurveyController.showSurveyIfAvailableCallback.getCallCount()); - } - - @Test - public void testMessages_MessageShownOnce() { - presentMessages(); - Assert.assertTrue("Message should be shown.", ChromeSurveyController.isMessageShown()); - verify(mMessageDispatcher).enqueueWindowScopedMessage(any(), anyBoolean()); - - // Simulate survey download that triggers invocation of #showSurveyPrompt. - mTestSurveyController.onDownloadSuccessRunnable.run(); - verifyNoMoreInteractions(mMessageDispatcher); - } - - @Test - public void testMessages_Dismiss_Gesture() { - presentMessages(); - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - - messageModel.get(MessageBannerProperties.ON_DISMISSED).onResult(DismissReason.GESTURE); - assertPromptDisplayedRecorded(); - } - - @Test - public void testMessages_Dismiss_Timer() { - presentMessages(); - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - - messageModel.get(MessageBannerProperties.ON_DISMISSED).onResult(DismissReason.TIMER); - assertPromptDisplayedRecorded(); - } - - // Inspired by crbug.com/1245624: When tab is destroyed, PromptDisplayed should not be - // recorded. - @Test - public void testMessages_Dismiss_Destroy() { - presentMessages(); - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - - int[] dismissReasons = {DismissReason.TAB_DESTROYED, DismissReason.ACTIVITY_DESTROYED, - DismissReason.SCOPE_DESTROYED}; - for (int reason : dismissReasons) { - messageModel.get(MessageBannerProperties.ON_DISMISSED).onResult(reason); - assertPromptDisplayedNotRecorded( - "Messages destroyed should not directly result in close state recorded."); - } - } - - @Test - public void testMessages_Dismiss_OnTabHidden() { - presentMessages(); - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - - mTabObserver.onHidden(mMockTab, TabHidingType.ACTIVITY_HIDDEN); - verify(mMessageDispatcher).dismissMessage(messageModel, DismissReason.TAB_SWITCHED); - - // Simulate the invocation of the message dismissal callback. - messageModel.get(MessageBannerProperties.ON_DISMISSED).onResult(DismissReason.TAB_SWITCHED); - assertPromptDisplayedRecorded(); - } - - @Test - public void testMessages_Dismiss_OnResumeActivity() { - presentMessages(); - PropertyModel messageModel = mMessagePropertyCaptor.getValue(); - - // Simulate survey expiration. - mTestSurveyController.isSurveyExpired = true; - mLifecycleObserver.onResumeWithNative(); - verify(mMessageDispatcher).dismissMessage(messageModel, DismissReason.DISMISSED_BY_FEATURE); - - // Simulate the invocation of the message dismissal callback. - messageModel.get(MessageBannerProperties.ON_DISMISSED) - .onResult(DismissReason.DISMISSED_BY_FEATURE); - Assert.assertFalse("SharedPreference for PromptShown should not be recorded.", - SharedPreferencesManager.getInstance().contains(mPrefKeyPromptShown)); - } - - private void initializeChromeSurveyController() { - ChromeSurveyController.initialize( - mMockModelSelector, mMockLifecycleDispatcher, mActivity, mMessageDispatcher); - try { - BackgroundShadowAsyncTask.runBackgroundTasks(); - } catch (Exception e) { - throw new AssertionError("#runBackgroundTasks failed", e); - } - ShadowLooper.runUiThreadTasks(); - } - - private void presentMessages() { - setupTabMocks(); - initializeChromeSurveyController(); - assertCallbackAssignedInSurveyController(); - Mockito.doAnswer(invocation -> { - mLifecycleObserver = invocation.getArgument(0); - return null; - }) - .when(mMockLifecycleDispatcher) - .register(any()); - - // Verify the survey should be attempted to present on a valid tab. - mockTabReady(); - mTestSurveyController.onDownloadSuccessRunnable.run(); - assertSurveyMessageEnqueued(true); - Assert.assertNotNull("mTabObserver is null.", mTabObserver); - Assert.assertNotNull("mLifecycleObserver is null.", mLifecycleObserver); - } - - private void mockTabReady() { - Mockito.doReturn(false).when(mMockTab).isLoading(); - Mockito.doReturn(true).when(mMockTab).isUserInteractable(); - } - - private void setupTabMocks() { - Mockito.when(mMockModelSelector.getCurrentTab()).thenReturn(mMockTab); - Mockito.doAnswer(invocation -> { - mTabModelSelectorObserver = invocation.getArgument(0); - return null; - }) - .when(mMockModelSelector) - .addObserver(any()); - Mockito.doAnswer(invocation -> { - if (mTabModelSelectorObserver == invocation.getArgument(0)) { - mTabModelSelectorObserver = null; - } - return null; - }) - .when(mMockModelSelector) - .removeObserver(any()); - - // Make the mock tab always valid. The cases with invalid tab are tested in - // ChromeSurveyControllerTest. - Mockito.when(mMockTab.getWebContents()).thenReturn(mMockWebContent); - Mockito.when(mMockTab.isIncognito()).thenReturn(false); - Mockito.doAnswer(invocation -> { - mTabObserver = invocation.getArgument(0); - return null; - }) - .when(mMockTab) - .addObserver(any()); - } - - private void assertCallbackAssignedInSurveyController() { - Assert.assertNotNull("onDownloadSuccessRunnable is null.", - mTestSurveyController.onDownloadSuccessRunnable); - Assert.assertNotNull("onDownloadFailureRunnable is null.", - mTestSurveyController.onDownloadFailureRunnable); - } - - private void assertSurveyMessageEnqueued(boolean enqueued) { - if (enqueued) { - verify(mMessageDispatcher) - .enqueueWindowScopedMessage(mMessagePropertyCaptor.capture(), eq(false)); - Assert.assertNotNull("Message captor is null.", mMessagePropertyCaptor.getValue()); - } else { - verify(mMessageDispatcher, never()) - .enqueueWindowScopedMessage(mMessagePropertyCaptor.capture(), eq(false)); - } - } - - private void assertPromptDisplayedRecorded() { - if (mTabObserver != null) { - verify(mMockTab).removeObserver(mTabObserver); - } - if (mLifecycleObserver != null) { - verify(mMockLifecycleDispatcher).unregister(mLifecycleObserver); - } - Assert.assertTrue("SharedPreference for PromptShown is not recorded.", - SharedPreferencesManager.getInstance().contains(mPrefKeyPromptShown)); - } - - private void assertPromptDisplayedNotRecorded(String reason) { - Assert.assertFalse( - reason, SharedPreferencesManager.getInstance().contains(mPrefKeyPromptShown)); - } - - private void assertDownloadAttempted(boolean attempted) { - int expectedCount = attempted ? 1 : 0; - Assert.assertEquals("Times of download triggered does not match.", expectedCount, - mTestSurveyController.downloadIfApplicableCallback.getCallCount()); - Assert.assertEquals("Download attempt count is not recorded as expected.", expectedCount, - mSharedPreferencesManager.readInt(mPrefKeyDownloadAttempts)); - } - - private void assertDownloadAttemptRecordedWithSample(int sample) { - Assert.assertEquals(String.format("<Android.Survey.DownloadAttemptsBeforeAccepted> " - + "with sample <%d> is not recorded.", - sample), - 1, - RecordHistogram.getHistogramValueCountForTesting( - "Android.Survey.DownloadAttemptsBeforeAccepted", sample)); - } - - private void enableChromeSurveyNextFeatureWithParams( - Map<String, String> params, boolean enable) { - TestValues testValues = new TestValues(); - String featureName = ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID; - testValues.addFeatureFlagOverride(featureName, enable); - if (params != null) { - for (Entry<String, String> param : params.entrySet()) { - testValues.addFieldTrialParamOverride( - featureName, param.getKey(), param.getValue()); - } - } - testValues.addFeatureFlagOverride(ChromeFeatureList.ANDROID_HATS_REFACTOR, false); - FeatureList.setTestValues(testValues); - } - - private static class TestSurveyController implements SurveyController { - public final CallbackHelper downloadIfApplicableCallback = new CallbackHelper(); - public final CallbackHelper showSurveyIfAvailableCallback = new CallbackHelper(); - public boolean isSurveyExpired; - - @Nullable - public Runnable onDownloadSuccessRunnable; - @Nullable - public Runnable onDownloadFailureRunnable; - - @Override - public void downloadSurvey(Context context, String triggerId, Runnable onSuccessRunnable, - Runnable onFailureRunnable) { - downloadIfApplicableCallback.notifyCalled(); - - onDownloadSuccessRunnable = onSuccessRunnable; - onDownloadFailureRunnable = onFailureRunnable; - } - - @Override - public void showSurveyIfAvailable(Activity activity, String triggerId, int displayLogoResId, - @Nullable ActivityLifecycleDispatcher lifecycleDispatcher, - @Nullable Map<String, String> psd) { - showSurveyIfAvailableCallback.notifyCalled(); - } - - @Override - public boolean isSurveyExpired(String triggerId) { - return isSurveyExpired; - } - } -}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java index a5ec5e72..0fcc129 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java
@@ -4,15 +4,10 @@ package org.chromium.chrome.browser.survey; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; import android.app.Activity; - -import androidx.annotation.NonNull; +import android.content.res.Resources; import org.junit.Assert; import org.junit.Before; @@ -21,38 +16,32 @@ import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; -import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.ui.hats.SurveyClientFactory; import org.chromium.chrome.browser.ui.hats.SurveyThrottler; +import org.chromium.chrome.browser.ui.hats.TestSurveyUtils; import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.messages.MessageDispatcher; -import org.chromium.content_public.browser.WebContents; /** * Unit tests for {@link ChromeSurveyController} and {@link SurveyThrottler}. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) +@Features.EnableFeatures(ChromeFeatureList.ANDROID_HATS_REFACTOR) public class ChromeSurveyControllerTest { - private static final String TEST_SURVEY_TRIGGER_ID = "foobar"; - - private TestChromeSurveyController mTestController; - @Rule public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor(); @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); - - @Mock - Tab mTab; - @Mock - WebContents mWebContents; @Mock TabModelSelector mSelector; @Mock @@ -64,123 +53,26 @@ @Before public void before() { - ChromeSurveyController.forceIsUMAEnabledForTesting(true); - mTestController = new TestChromeSurveyController(TEST_SURVEY_TRIGGER_ID, - mActivityLifecycleDispatcher, mActivity, mMessageDispatcher); - mTestController.setTabModelSelector(mSelector); - Assert.assertNull("Tab should be null", mTestController.getLastTabPromptShown()); + doReturn(Mockito.mock(Resources.class)).when(mActivity).getResources(); + SurveyClientFactory.initialize(null); } @Test - public void testIsValidTabForSurvey_ValidTab() { - doReturn(mWebContents).when(mTab).getWebContents(); - doReturn(false).when(mTab).isIncognito(); - - Assert.assertTrue(mTestController.isValidTabForSurvey(mTab)); - - verify(mTab, atLeastOnce()).getWebContents(); - verify(mTab, atLeastOnce()).isIncognito(); + public void testInitialization() { + TestSurveyUtils.setTestSurveyConfigForTrigger( + "startup_survey", new String[0], new String[0]); + ChromeSurveyController controller = ChromeSurveyController.initialize( + mSelector, mActivityLifecycleDispatcher, mActivity, mMessageDispatcher); + Assert.assertNotNull(controller); } @Test - public void testIsValidTabForSurvey_NullTab() { - Assert.assertFalse(mTestController.isValidTabForSurvey(null)); - } - - @Test - public void testIsValidTabForSurvey_IncognitoTab() { - doReturn(mWebContents).when(mTab).getWebContents(); - doReturn(true).when(mTab).isIncognito(); - - Assert.assertFalse(mTestController.isValidTabForSurvey(mTab)); - - verify(mTab, atLeastOnce()).isIncognito(); - } - - @Test - public void testIsValidTabForSurvey_NoWebContents() { - doReturn(null).when(mTab).getWebContents(); - - Assert.assertFalse(mTestController.isValidTabForSurvey(mTab)); - - verify(mTab, atLeastOnce()).getWebContents(); - verify(mTab, never()).isIncognito(); - } - - @Test - public void testShowPromptTabApplicable() { - doReturn(true).when(mTab).isUserInteractable(); - doReturn(false).when(mTab).isLoading(); - - mTestController.showPromptIfApplicable(mTab, null, null); - Assert.assertEquals("Tabs should be equal", mTab, mTestController.getLastTabPromptShown()); - verify(mTab, atLeastOnce()).isUserInteractable(); - verify(mTab, atLeastOnce()).isLoading(); - } - - @Test - public void testShowPromptTabNotApplicable() { - doReturn(false).when(mTab).isUserInteractable(); - doReturn(true).when(mTab).isLoading(); - - mTestController.showPromptIfApplicable(mTab, null, null); - Assert.assertNull("Tab should be null", mTestController.getLastTabPromptShown()); - verify(mTab, atLeastOnce()).isUserInteractable(); - } - - @Test - public void testShowPromptUmaUploadNotEnabled() { - doReturn(true).when(mTab).isUserInteractable(); - doReturn(true).when(mTab).isLoading(); - ChromeSurveyController.forceIsUMAEnabledForTesting(false); - - mTestController.showPromptIfApplicable(mTab, null, null); - Assert.assertNull("Tab should be null", mTestController.getLastTabPromptShown()); - verify(mTab, atLeastOnce()).isUserInteractable(); - } - - @Test - public void testSurveyAvailableWebContentsLoaded() { - doReturn(mTab).when(mSelector).getCurrentTab(); - doReturn(mWebContents).when(mTab).getWebContents(); - doReturn(false).when(mTab).isIncognito(); - doReturn(true).when(mTab).isUserInteractable(); - doReturn(false).when(mWebContents).isLoading(); - - mTestController.onSurveyAvailable(null); - Assert.assertEquals("Tabs should be equal", mTab, mTestController.getLastTabPromptShown()); - - verify(mSelector, atLeastOnce()).getCurrentTab(); - verify(mTab, atLeastOnce()).isIncognito(); - verify(mTab, atLeastOnce()).isUserInteractable(); - verify(mTab, atLeastOnce()).isLoading(); - } - - @Test - public void testSurveyAvailableNullTab() { - doReturn(null).when(mSelector).getCurrentTab(); - - mTestController.onSurveyAvailable(null); - Assert.assertNull("Tab should be null", mTestController.getLastTabPromptShown()); - verify(mSelector).addObserver(any()); - } - - static class TestChromeSurveyController extends ChromeSurveyController { - private Tab mTab; - - public TestChromeSurveyController(String triggerId, - ActivityLifecycleDispatcher activityLifecycleDispatcher, Activity activity, - MessageDispatcher messageDispatcher) { - super(triggerId, activityLifecycleDispatcher, activity, messageDispatcher); - } - - @Override - void showSurveyPrompt(@NonNull Tab tab, String siteId) { - mTab = tab; - } - - public Tab getLastTabPromptShown() { - return mTab; - } + @Features.DisableFeatures(ChromeFeatureList.ANDROID_HATS_REFACTOR) + public void doNotInitializationWhenFeatureDisabled() { + TestSurveyUtils.setTestSurveyConfigForTrigger( + "startup_survey", new String[0], new String[0]); + ChromeSurveyController controller = ChromeSurveyController.initialize( + mSelector, mActivityLifecycleDispatcher, mActivity, mMessageDispatcher); + Assert.assertNull(controller); } }
diff --git a/chrome/android/modules/chrome_feature_modules.gni b/chrome/android/modules/chrome_feature_modules.gni index aada489..fa0c7ca 100644 --- a/chrome/android/modules/chrome_feature_modules.gni +++ b/chrome/android/modules/chrome_feature_modules.gni
@@ -10,8 +10,6 @@ import("//chrome/android/modules/stack_unwinder/stack_unwinder_module.gni") import("//chrome/android/modules/test_dummy/test_dummy_module.gni") import("//device/vr/buildflags/buildflags.gni") -import("//weblayer/variables.gni") -import("//weblayer/weblayer_module.gni") if (enable_vr) { import("//chrome/android/features/vr/vr_module.gni") @@ -54,9 +52,6 @@ } monochrome_module_descs = chrome_module_descs -if (webview_includes_weblayer) { - monochrome_module_descs += [ weblayer_module_desc ] -} # TODO: Remove once unused downstream. trichrome_module_descs = chrome_module_descs
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 0f3c46a1..c238493 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8071,13 +8071,7 @@ <message name="IDS_NTP_MODULES_HISTORY_CLUSTERS_BOOKMARKED" desc="A label for the bookmarked annotation in NTP Quests Module."> Bookmarked </message> - <message name="IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO" desc="Text shown in the body of the info dialog of the history clusters module."> - You’re seeing pages you've visited and suggested searches to help you easily get back to your most recent activity in Chrome Journeys. - <ph name="BREAK"><br></ph> - <ph name="BREAK"><br></ph> - You can manage settings from the card menu or see more options in Customize Chrome. - </message> - <message name="IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO2" desc="Text shown in the body of the info dialog of the NTP History Clusters module."> + <message name="IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO" desc="Text shown in the body of the info dialog of the NTP History Clusters module."> You’re seeing pages you've visited and suggested searches to help you easily get back to your most recent activity. <ph name="BREAK"><br></ph> <ph name="BREAK"><br></ph> @@ -8098,9 +8092,6 @@ <message name="IDS_NTP_MODULES_HISTORY_CLUSTERS_DISMISS_BUTTON" desc="A label for the dismiss button in the dropdown."> No longer interested </message> - <message name="IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_TEXT" desc="A label to append to the disable text in the dropdown."> - Journeys card - </message> <message name="IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_DROPDOWN_TEXT" desc="A label to append to the disable text in the dropdown."> this card </message>
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_TEXT.png.sha1 deleted file mode 100644 index 63c2c83..0000000 --- a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -08ba1a40d838efa46d4b3ca2cddf0f9e2d0c42bb \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO.png.sha1 index 18fe47e..f3f839d 100644 --- a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO.png.sha1
@@ -1 +1 @@ -5baf709aed54d7d4c1a9034d8b3dd3e05d549614 \ No newline at end of file +df376783cd68b34ff8d4fda10e89ec4702f14094 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO2.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO2.png.sha1 deleted file mode 100644 index 5fbfaa9..0000000 --- a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO2.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -b6a96118410cedd6ff3eec739ab180318cad0b82 \ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 8100a7a..0a62b84 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -255,6 +255,7 @@ "user_menu_guest.icon", "user_menu_right_arrow.icon", "web.icon", + "webauthn/icloud_keychain.icon", "webauthn/passkey_aoa.icon", "webauthn/passkey_aoa_dark.icon", "webauthn/passkey_error.icon", @@ -269,7 +270,6 @@ "webauthn/passkey_phone_dark.icon", "webauthn/passkey_usb.icon", "webauthn/passkey_usb_dark.icon", - "webauthn/icloud_keychain.icon", "webauthn/webauthn_error.icon", "webauthn/webauthn_error_dark.icon", "zoom_in.icon", @@ -327,7 +327,7 @@ "game_controls_delete.icon", "game_controls_done.icon", "game_controls_dpad_keyboard.icon", - "game_controls_gamepad.icon", + "game_controls_edit_pen.icon", "game_controls_single_button.icon", "mouse_left_click_edit.icon", "mouse_left_click_view.icon",
diff --git a/chrome/app/vector_icons/game_controls_edit_pen.icon b/chrome/app/vector_icons/game_controls_edit_pen.icon new file mode 100644 index 0000000..fe17b86 --- /dev/null +++ b/chrome/app/vector_icons/game_controls_edit_pen.icon
@@ -0,0 +1,22 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 17.41f, 3.94f, +R_LINE_TO, -1.35f, -1.35f, +R_CUBIC_TO, -0.78f, -0.78f, -2.05f, -0.78f, -2.83f, 0, +R_LINE_TO, -2.83f, 2.82f, +R_LINE_TO, -8.4f, 8.41f, +R_V_LINE_TO, 4.18f, +R_H_LINE_TO, 4.18f, +R_LINE_TO, 11.23f, -11.23f, +R_CUBIC_TO, 0.79f, -0.78f, 0.79f, -2.05f, 0, -2.83f, +CLOSE, +MOVE_TO, 4, 16, +R_V_LINE_TO, -1.36f, +R_LINE_TO, 7.82f, -7.82f, +R_LINE_TO, 1.41f, 1.41f, +R_LINE_TO, -7.82f, 7.83f, +R_LINE_TO, -1.41f, -0.06f, +CLOSE
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 62f0ed73..f4f8b927 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2973,6 +2973,8 @@ "android/usage_stats/usage_stats_database.h", "android/warmup_manager.cc", "android/web_contents_factory.cc", + "android/webapk/webapk_database.cc", + "android/webapk/webapk_database.h", "android/webapk/webapk_database_factory.cc", "android/webapk/webapk_database_factory.h", "android/webapk/webapk_install_coordinator_bridge.cc", @@ -2983,6 +2985,8 @@ "android/webapk/webapk_install_service_factory.h", "android/webapk/webapk_installer.cc", "android/webapk/webapk_installer.h", + "android/webapk/webapk_sync_bridge.cc", + "android/webapk/webapk_sync_bridge.h", "android/webapk/webapk_update_manager.cc", "android/webapps/webapp_registry.cc", "android/webapps/webapp_registry.h", @@ -3399,6 +3403,7 @@ "//chrome/browser/android/messages:jni_headers", "//chrome/browser/android/metrics:jni_headers", "//chrome/browser/android/webapk:webapk_sources", + "//chrome/browser/android/webapk/proto", "//chrome/browser/autofill/android:jni_headers", "//chrome/browser/banners/android:jni_headers", "//chrome/browser/bluetooth/android:jni_headers", @@ -3752,8 +3757,6 @@ "download/download_item_web_app_data.h", "download/download_open_prompt.cc", "download/download_open_prompt.h", - "download/download_session_durations_metrics_recorder.cc", - "download/download_session_durations_metrics_recorder.h", "download/download_shelf.cc", "download/download_shelf.h", "download/download_shelf_context_menu.cc", @@ -5257,6 +5260,7 @@ "//chrome/browser/ui/webui/ash/crostini_installer:mojo_bindings", "//chrome/browser/ui/webui/ash/crostini_upgrader:mojo_bindings", "//chrome/browser/ui/webui/ash/emoji:mojo_bindings", + "//chrome/browser/ui/webui/ash/enterprise_reporting:mojo_bindings", "//chrome/browser/ui/webui/ash/launcher_internals:mojo_bindings", "//chrome/browser/ui/webui/ash/manage_mirrorsync:mojo_bindings", "//chrome/browser/ui/webui/ash/office_fallback:mojo_bindings",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2f3b044..43c6027 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -8383,10 +8383,6 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(ash::features::kEolIncentive, kEolIncentiveVariations, "EolIncentive")}, - {"autocomplete-extended-suggestions", - flag_descriptions::kAutocompleteExtendedSuggestionsName, - flag_descriptions::kAutocompleteExtendedSuggestionsDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kAutocompleteExtendedSuggestions)}, {"productivity-launcher-image-search", flag_descriptions::kProductivityLauncherImageSearchName, flag_descriptions::kProductivityLauncherImageSearchDescription, kOsCrOS, @@ -8430,10 +8426,6 @@ {"text-in-shelf", flag_descriptions::kTextInShelfName, flag_descriptions::kTextInShelfDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kHomeButtonWithText)}, - {"app-collection-folder-refresh", - flag_descriptions::kAppCollectionFolderRefreshName, - flag_descriptions::kAppCollectionFolderRefreshDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kAppCollectionFolderRefresh)}, {"launcher-local-image-search", flag_descriptions::kLauncherLocalImageSearchName, flag_descriptions::kLauncherLocalImageSearchDescription, kOsCrOS, @@ -8468,11 +8460,6 @@ flag_descriptions::kOobeSimonDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kOobeSimon)}, - {"search-result-inline-icon", - flag_descriptions::kSearchResultInlineIconName, - flag_descriptions::kSearchResultInlineIconDescription, kOsCrOS, - FEATURE_VALUE_TYPE(app_list_features::kSearchResultInlineIcon)}, - {"smds-support", flag_descriptions::kSmdsSupportName, flag_descriptions::kSmdsSupportDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kSmdsSupport)},
diff --git a/chrome/browser/android/monochrome_entry_point.cc b/chrome/browser/android/monochrome_entry_point.cc index 139658d..e5f1661 100644 --- a/chrome/browser/android/monochrome_entry_point.cc +++ b/chrome/browser/android/monochrome_entry_point.cc
@@ -9,10 +9,6 @@ #include "base/functional/bind.h" #include "chrome/app/android/chrome_jni_onload.h" -#if defined(WEBVIEW_INCLUDES_WEBLAYER) -#include "weblayer/app/jni_onload.h" -#endif - namespace { bool NativeInit(base::android::LibraryProcessType library_process_type) { @@ -27,12 +23,6 @@ case base::android::PROCESS_WEBVIEW_NONEMBEDDED: return base::android::OnJNIOnLoadInit(); -#if defined(WEBVIEW_INCLUDES_WEBLAYER) - case base::android::PROCESS_WEBLAYER: - case base::android::PROCESS_WEBLAYER_CHILD: - return weblayer::OnJNIOnLoadInit(); -#endif - default: NOTREACHED(); return false;
diff --git a/chrome/browser/android/webapk/BUILD.gn b/chrome/browser/android/webapk/BUILD.gn index df825e2..f69d2dd 100644 --- a/chrome/browser/android/webapk/BUILD.gn +++ b/chrome/browser/android/webapk/BUILD.gn
@@ -6,8 +6,6 @@ source_set("webapk_sources") { sources = [ - "webapk_database.cc", - "webapk_database.h", "webapk_features.cc", "webapk_features.h", "webapk_handler_delegate.cc", @@ -23,8 +21,6 @@ "webapk_registrar.h", "webapk_registry_update.cc", "webapk_registry_update.h", - "webapk_sync_bridge.cc", - "webapk_sync_bridge.h", "webapk_ukm_recorder.cc", "webapk_ukm_recorder.h", "webapk_update_data_fetcher.cc",
diff --git a/chrome/browser/android/webapk/webapk_database.cc b/chrome/browser/android/webapk/webapk_database.cc index acf3a2f..312dd35 100644 --- a/chrome/browser/android/webapk/webapk_database.cc +++ b/chrome/browser/android/webapk/webapk_database.cc
@@ -4,17 +4,43 @@ #include "chrome/browser/android/webapk/webapk_database.h" +#include <memory> +#include <string> + +#include "base/check.h" +#include "base/functional/bind.h" +#include "base/logging.h" +#include "base/sequence_checker.h" +#include "chrome/browser/android/webapk/proto/webapk_database.pb.h" +#include "chrome/browser/android/webapk/webapk_database_factory.h" +#include "chrome/browser/android/webapk/webapk_registry_update.h" +#include "components/sync/model/metadata_batch.h" +#include "components/sync/model/metadata_change_list.h" +#include "components/sync/model/model_error.h" +#include "components/sync/model/model_type_store.h" +#include "components/sync/protocol/web_apk_specifics.pb.h" + namespace webapk { WebApkDatabase::WebApkDatabase(AbstractWebApkDatabaseFactory* database_factory, - ReportErrorCallback error_callback) { - // TODO(parsam): implement -} + ReportErrorCallback error_callback) + : database_factory_(database_factory), + error_callback_(std::move(error_callback)) {} + WebApkDatabase::~WebApkDatabase() { - // TODO(parsam): implement + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } void WebApkDatabase::OpenDatabase(RegistryOpenedCallback callback) { - // TODO(parsam): implement + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(!store_); + + syncer::OnceModelTypeStoreFactory store_factory = + database_factory_->GetStoreFactory(); + + std::move(store_factory) + .Run(syncer::WEB_APPS, + base::BindOnce(&WebApkDatabase::OnDatabaseOpened, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void WebApkDatabase::Write( @@ -24,4 +50,67 @@ // TODO(parsam): implement } +void WebApkDatabase::OnDatabaseOpened( + RegistryOpenedCallback callback, + const absl::optional<syncer::ModelError>& error, + std::unique_ptr<syncer::ModelTypeStore> store) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (error) { + error_callback_.Run(*error); + DLOG(ERROR) << "WebApks LevelDB opening error: " << error->ToString(); + return; + } + + store_ = std::move(store); + store_->ReadAllData(base::BindOnce(&WebApkDatabase::OnAllDataRead, + weak_ptr_factory_.GetWeakPtr(), + std::move(callback))); +} + +void WebApkDatabase::OnAllDataRead( + RegistryOpenedCallback callback, + const absl::optional<syncer::ModelError>& error, + std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (error) { + error_callback_.Run(*error); + DLOG(ERROR) << "WebApks LevelDB data read error: " << error->ToString(); + return; + } + + store_->ReadAllMetadata(base::BindOnce( + &WebApkDatabase::OnAllMetadataRead, weak_ptr_factory_.GetWeakPtr(), + std::move(data_records), std::move(callback))); +} + +void WebApkDatabase::OnAllMetadataRead( + std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records, + RegistryOpenedCallback callback, + const absl::optional<syncer::ModelError>& error, + std::unique_ptr<syncer::MetadataBatch> metadata_batch) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (error) { + error_callback_.Run(*error); + DLOG(ERROR) << "WebApks LevelDB metadata read error: " << error->ToString(); + return; + } + + Registry registry; + for (const syncer::ModelTypeStore::Record& record : *data_records) { + std::unique_ptr<WebApkProto> proto = std::make_unique<WebApkProto>(); + const bool parsed = proto->ParseFromString(record.value); + if (!parsed) { + DLOG(ERROR) << "WebApks LevelDB parse error: can't parse proto."; + } + + registry.emplace(record.id, std::move(proto)); + } + + opened_ = true; + // This should be a tail call: a callback code may indirectly call |this| + // methods, like WebApkDatabase::Write() + std::move(callback).Run(std::move(registry), std::move(metadata_batch)); +} + } // namespace webapk
diff --git a/chrome/browser/android/webapk/webapk_database.h b/chrome/browser/android/webapk/webapk_database.h index bf3cda1..bee7d2c 100644 --- a/chrome/browser/android/webapk/webapk_database.h +++ b/chrome/browser/android/webapk/webapk_database.h
@@ -5,6 +5,12 @@ #ifndef CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_DATABASE_H_ #define CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_DATABASE_H_ +#include <memory> + +#include "base/functional/callback_forward.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" #include "chrome/browser/android/webapk/webapk_registrar.h" #include "components/sync/model/model_type_store.h" @@ -22,7 +28,7 @@ class WebApkDatabase { public: using ReportErrorCallback = - base::RepeatingCallback<void(const syncer::ModelError)>; + base::RepeatingCallback<void(const syncer::ModelError&)>; WebApkDatabase(AbstractWebApkDatabaseFactory* database_factory, ReportErrorCallback error_callback); @@ -42,6 +48,34 @@ void Write(const RegistryUpdateData& update_data, std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, CompletionCallback callback); + + bool is_opened() const { return opened_; } + + private: + void OnDatabaseOpened(RegistryOpenedCallback callback, + const absl::optional<syncer::ModelError>& error, + std::unique_ptr<syncer::ModelTypeStore> store); + void OnAllDataRead( + RegistryOpenedCallback callback, + const absl::optional<syncer::ModelError>& error, + std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records); + void OnAllMetadataRead( + std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records, + RegistryOpenedCallback callback, + const absl::optional<syncer::ModelError>& error, + std::unique_ptr<syncer::MetadataBatch> metadata_batch); + + std::unique_ptr<syncer::ModelTypeStore> store_; + const raw_ptr<AbstractWebApkDatabaseFactory, DanglingUntriaged> + database_factory_; + ReportErrorCallback error_callback_; + + // Database is opened if store is created and all data read. + bool opened_ = false; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<WebApkDatabase> weak_ptr_factory_{this}; }; } // namespace webapk
diff --git a/chrome/browser/android/webapk/webapk_database_unittest.cc b/chrome/browser/android/webapk/webapk_database_unittest.cc new file mode 100644 index 0000000..aadaf67a --- /dev/null +++ b/chrome/browser/android/webapk/webapk_database_unittest.cc
@@ -0,0 +1,169 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/android/webapk/webapk_database.h" + +#include <memory> +#include <string> + +#include "base/strings/to_string.h" +#include "base/test/bind.h" +#include "chrome/browser/android/webapk/fake_webapk_database_factory.h" +#include "chrome/browser/android/webapk/webapk_helpers.h" +#include "chrome/browser/android/webapk/webapk_registrar.h" +#include "chrome/browser/web_applications/web_app_helpers.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "components/sync/model/metadata_batch.h" +#include "components/sync/protocol/web_apk_specifics.pb.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_web_contents_factory.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace webapk { + +// Note: this only compares basic sync attributes, it doesn't do a full deep +// comparison. +bool IsRegistryEqual(const Registry& registry, const Registry& registry2) { + if (registry.size() != registry2.size()) { + return false; + } + + for (auto& kv : registry) { + const WebApkProto* web_app = kv.second.get(); + const WebApkProto* web_app2 = registry2.at(kv.first).get(); + + const sync_pb::WebApkSpecifics& specifics = web_app->sync_data(); + const sync_pb::WebApkSpecifics& specifics2 = web_app2->sync_data(); + + if (web_app->is_locally_installed() != web_app2->is_locally_installed() || + specifics.manifest_id() != specifics2.manifest_id() || + specifics.start_url() != specifics2.start_url() || + specifics.name() != specifics2.name()) { + return false; + } + } + + return true; +} + +class WebApkDatabaseTest : public ::testing::Test { + public: + WebApkDatabaseTest() + : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {} + + void SetUp() override { + ASSERT_TRUE(testing_profile_manager_.SetUp()); + profile_ = testing_profile_manager_.CreateTestingProfile( + TestingProfile::kDefaultProfileUserName, true); + + database_factory_ = std::make_unique<FakeWebApkDatabaseFactory>(); + + web_contents_ = web_contents_factory_.CreateWebContents(profile()); + }; + + // Creates a random WebApkProto based off of a suffix. + static std::unique_ptr<WebApkProto> CreateWebApkProto( + int suffix, + bool is_locally_installed) { + const std::string start_url = + "https://example.com/" + base::ToString(suffix); + const std::string manifest_id = + "https://example.com/id/" + base::ToString(suffix); + const std::string name = "App Name " + base::ToString(suffix); + + std::unique_ptr<WebApkProto> proto = std::make_unique<WebApkProto>(); + sync_pb::WebApkSpecifics* sync_proto = proto->mutable_sync_data(); + + sync_proto->set_manifest_id(manifest_id); + sync_proto->set_start_url(GURL(start_url).spec()); + sync_proto->set_name(name); + proto->set_is_locally_installed(is_locally_installed); + + return proto; + } + + void WriteBatch( + std::unique_ptr<syncer::ModelTypeStore::WriteBatch> write_batch) { + base::RunLoop run_loop; + + database_factory().GetStore()->CommitWriteBatch( + std::move(write_batch), + base::BindLambdaForTesting( + [&](const absl::optional<syncer::ModelError>& error) { + EXPECT_FALSE(error); + run_loop.Quit(); + })); + + run_loop.Run(); + } + + Registry WriteWebApps(uint32_t num_apps) { + Registry registry; + + auto write_batch = database_factory().GetStore()->CreateWriteBatch(); + + for (uint32_t i = 0; i < num_apps; ++i) { + std::unique_ptr<WebApkProto> proto = CreateWebApkProto(i, false); + const std::string app_id = + GenerateAppIdFromManifestId(GURL(proto->sync_data().manifest_id())); + + write_batch->WriteData(app_id, proto->SerializeAsString()); + + registry.emplace(app_id, std::move(proto)); + } + + WriteBatch(std::move(write_batch)); + + return registry; + } + + TestingProfile* profile() { return profile_.get(); } + + protected: + FakeWebApkDatabaseFactory& database_factory() { return *database_factory_; } + FakeWebApkDatabaseFactory* database_factory_ptr() { + return database_factory_.get(); + } + + private: + content::BrowserTaskEnvironment task_environment_; + std::unique_ptr<FakeWebApkDatabaseFactory> database_factory_; + TestingProfileManager testing_profile_manager_{ + TestingBrowserProcess::GetGlobal()}; + + raw_ptr<TestingProfile> profile_; + + content::TestWebContentsFactory web_contents_factory_; + raw_ptr<content::WebContents> + web_contents_; // Owned by `web_contents_factory_`. +}; + +TEST_F(WebApkDatabaseTest, OpenDatabaseAndReadRegistry) { + Registry registry = WriteWebApps(100); + + std::unique_ptr<WebApkDatabase> web_apk_database; + + web_apk_database = std::make_unique<WebApkDatabase>( + database_factory_ptr(), + base::BindLambdaForTesting([&](const syncer::ModelError& error) { + ASSERT_TRUE(false); // should not be reached + })); + + { + base::RunLoop run_loop; + web_apk_database->OpenDatabase(base::BindLambdaForTesting( + [&](Registry inner_registry, + std::unique_ptr<syncer::MetadataBatch> metadata_batch) { + EXPECT_TRUE(IsRegistryEqual(inner_registry, registry)); + // TODO(hartmanng): it might be a good idea to test the metadata_batch + // here too, although currently it's empty. + run_loop.Quit(); + })); + run_loop.Run(); + } +} + +} // namespace webapk
diff --git a/chrome/browser/ash/app_list/search/chrome_search_result.cc b/chrome/browser/ash/app_list/search/chrome_search_result.cc index cf757c7..0f9b409 100644 --- a/chrome/browser/ash/app_list/search/chrome_search_result.cc +++ b/chrome/browser/ash/app_list/search/chrome_search_result.cc
@@ -154,11 +154,6 @@ SetSearchResultMetadata(); } -void ChromeSearchResult::SetIsOmniboxSearch(bool is_omnibox_search) { - metadata_->is_omnibox_search = is_omnibox_search; - SetSearchResultMetadata(); -} - void ChromeSearchResult::SetIsRecommendation(bool is_recommendation) { metadata_->is_recommendation = is_recommendation; SetSearchResultMetadata();
diff --git a/chrome/browser/ash/app_list/search/chrome_search_result.h b/chrome/browser/ash/app_list/search/chrome_search_result.h index 893d1e7..ae2f0148 100644 --- a/chrome/browser/ash/app_list/search/chrome_search_result.h +++ b/chrome/browser/ash/app_list/search/chrome_search_result.h
@@ -138,7 +138,6 @@ void SetMetricsType(MetricsType metrics_type); void SetDisplayScore(double display_score); void SetActions(const Actions& actions); - void SetIsOmniboxSearch(bool is_omnibox_search); void SetIsRecommendation(bool is_recommendation); void SetSkipUpdateAnimation(bool skip_update_animation); void SetIcon(const IconInfo& icon);
diff --git a/chrome/browser/ash/app_list/search/keyboard_shortcut_result.cc b/chrome/browser/ash/app_list/search/keyboard_shortcut_result.cc index d4cfe13..d7bdf0a1 100644 --- a/chrome/browser/ash/app_list/search/keyboard_shortcut_result.cc +++ b/chrome/browser/ash/app_list/search/keyboard_shortcut_result.cc
@@ -12,6 +12,7 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/app_list/internal_app_id_constants.h" #include "ash/public/mojom/accelerator_info.mojom-shared.h" +#include "ash/public/mojom/accelerator_info.mojom.h" #include "ash/shell.h" #include "ash/shortcut_viewer/keyboard_shortcut_viewer_metadata.h" #include "ash/shortcut_viewer/strings/grit/shortcut_viewer_strings.h" @@ -162,6 +163,19 @@ IDS_SHORTCUT_CUSTOMIZATION_ARIA_LABEL_FOR_A_KEY, key_string); } +bool IsModifierKey(ui::KeyboardCode keycode) { + switch (keycode) { + case ui::KeyboardCode::VKEY_COMMAND: + case ui::KeyboardCode::VKEY_LMENU: + case ui::KeyboardCode::VKEY_RCONTROL: + case ui::KeyboardCode::VKEY_CONTROL: + case ui::KeyboardCode::VKEY_SHIFT: + return true; + default: + return false; + } +} + } // namespace absl::optional<IconCode> KeyboardShortcutResult::GetIconCodeFromKeyboardCode( @@ -387,10 +401,14 @@ for (auto key_code : key_codes) { const absl::optional<IconCode> icon_code = GetIconCodeFromKeyboardCode(key_code); + bool use_alternative_styling = IsModifierKey(key_code); if (icon_code) { // The KeyboardCode has a corresponding IconCode, and therefore an // icon image is supported by the front-end. - text_vector->push_back(CreateIconCodeTextItem(icon_code.value())); + ash::SearchResultTextItem result_item = + CreateIconCodeTextItem(icon_code.value()); + result_item.SetAlternateIconAndTextStyling(use_alternative_styling); + text_vector->push_back(result_item); accessible_strings.push_back( GetAccessibleStringForIcon(icon_code.value())); } else { @@ -401,7 +419,11 @@ // All keys including modifiers should be displayed in lower case. const std::u16string key_string = base::ToLowerASCII(ash::GetStringForKeyboardCode(key_code)); - text_vector->push_back(CreateIconifiedTextTextItem(key_string)); + ash::SearchResultTextItem result_item = + CreateIconifiedTextTextItem(key_string); + + result_item.SetAlternateIconAndTextStyling(use_alternative_styling); + text_vector->push_back(result_item); accessible_strings.push_back(GetAccessibleStringForKey(key_string)); } } @@ -432,14 +454,22 @@ case ash::mojom::TextAcceleratorPartType::kKey: case ash::mojom::TextAcceleratorPartType::kModifier: const auto icon_code = GetIconCodeByKeyString(part->text); + bool use_alternative_styling = + part->type == ash::mojom::TextAcceleratorPartType::kModifier; if (icon_code) { - text_vector->push_back(CreateIconCodeTextItem(icon_code.value())); + ash::SearchResultTextItem result_item = + CreateIconCodeTextItem(icon_code.value()); + result_item.SetAlternateIconAndTextStyling(use_alternative_styling); + text_vector->push_back(result_item); accessible_strings.push_back( GetAccessibleStringForIcon(icon_code.value())); } else { // All keys including modifiers should be displayed in lower case. const std::u16string key_string = base::ToLowerASCII(part->text); - text_vector->push_back(CreateIconifiedTextTextItem(key_string)); + ash::SearchResultTextItem result_item = + CreateIconifiedTextTextItem(key_string); + result_item.SetAlternateIconAndTextStyling(use_alternative_styling); + text_vector->push_back(result_item); accessible_strings.push_back(GetAccessibleStringForKey(key_string)); } break;
diff --git a/chrome/browser/ash/app_list/search/omnibox/omnibox_answer_result.cc b/chrome/browser/ash/app_list/search/omnibox/omnibox_answer_result.cc index 706d5e2..d4fd11f 100644 --- a/chrome/browser/ash/app_list/search/omnibox/omnibox_answer_result.cc +++ b/chrome/browser/ash/app_list/search/omnibox/omnibox_answer_result.cc
@@ -146,9 +146,6 @@ // Derive relevance from omnibox relevance and normalize it to [0, 1]. set_relevance(search_result_->relevance / kMaxOmniboxScore); - if (crosapi::OptionalBoolIsTrue(search_result_->is_omnibox_search)) - SetIsOmniboxSearch(true); - UpdateIcon(); UpdateTitleAndDetails();
diff --git a/chrome/browser/ash/app_list/search/omnibox/omnibox_result.cc b/chrome/browser/ash/app_list/search/omnibox/omnibox_result.cc index 1dee431..dfdc88f 100644 --- a/chrome/browser/ash/app_list/search/omnibox/omnibox_result.cc +++ b/chrome/browser/ash/app_list/search/omnibox/omnibox_result.cc
@@ -103,8 +103,6 @@ dedup_priority_ = kDefaultPriority; } - SetIsOmniboxSearch( - crosapi::OptionalBoolIsTrue(search_result_->is_omnibox_search)); SetSkipUpdateAnimation(search_result_->metrics_type == CrosApiSearchResult::MetricsType::kSearchWhatYouTyped);
diff --git a/chrome/browser/ash/app_list/search/omnibox/omnibox_result_unittest.cc b/chrome/browser/ash/app_list/search/omnibox/omnibox_result_unittest.cc index 8dd27c2..f65c047f 100644 --- a/chrome/browser/ash/app_list/search/omnibox/omnibox_result_unittest.cc +++ b/chrome/browser/ash/app_list/search/omnibox/omnibox_result_unittest.cc
@@ -300,7 +300,6 @@ // action set. const auto search_result = CreateOmniboxResult( "https://example.com", AutocompleteMatchType::SEARCH_SUGGEST); - EXPECT_TRUE(search_result->CloneMetadata()->is_omnibox_search); ASSERT_EQ(1u, search_result->actions().size()); EXPECT_EQ(ash::SearchResultActionType::kRemove, search_result->actions()[0].type); @@ -308,7 +307,6 @@ // Non-Omnibox-search-type results have no actions. const auto non_search_result = CreateOmniboxResult( "https://example.com", AutocompleteMatchType::HISTORY_URL); - EXPECT_FALSE(non_search_result->CloneMetadata()->is_omnibox_search); EXPECT_EQ(0u, non_search_result->actions().size()); }
diff --git a/chrome/browser/ash/arc/input_overlay/actions/input_element.cc b/chrome/browser/ash/arc/input_overlay/actions/input_element.cc index c633170..b91ede1 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/input_element.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/input_element.cc
@@ -122,7 +122,7 @@ } if (input_sources_ == InputSource::IS_KEYBOARD) { for (auto key : input_element.keys()) { - if (base::Contains(keys_, key)) { + if (key != ui::DomCode::NONE && base::Contains(keys_, key)) { return true; } }
diff --git a/chrome/browser/ash/arc/input_overlay/actions/input_element_unittest.cc b/chrome/browser/ash/arc/input_overlay/actions/input_element_unittest.cc index dfb95f58..c52237c8 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/input_element_unittest.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/input_element_unittest.cc
@@ -7,6 +7,7 @@ #include "base/json/json_reader.h" #include "chrome/browser/ash/arc/input_overlay/util.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/keycodes/dom/dom_code.h" namespace arc::input_overlay { @@ -32,4 +33,28 @@ EXPECT_FALSE(*tap_primary_click1 == *tap_secondary_click); } +TEST(InputElementTest, TestInputElementOverlap) { + auto move_a = InputElement::CreateActionMoveKeyElement( + {ui::DomCode::US_A, ui::DomCode::NONE, ui::DomCode::NONE, + ui::DomCode::NONE}); + auto move_b = InputElement::CreateActionMoveKeyElement( + {ui::DomCode::US_B, ui::DomCode::NONE, ui::DomCode::NONE, + ui::DomCode::NONE}); + auto move_c = InputElement::CreateActionMoveKeyElement( + {ui::DomCode::US_A, ui::DomCode::NONE, ui::DomCode::NONE, + ui::DomCode::NONE}); + auto tap_a = InputElement::CreateActionTapKeyElement(ui::DomCode::US_A); + auto tap_b = InputElement::CreateActionTapKeyElement(ui::DomCode::NONE); + EXPECT_FALSE(move_a->IsOverlapped(*move_b)); + EXPECT_TRUE(move_a->IsOverlapped(*move_c)); + EXPECT_TRUE(move_a->IsOverlapped(*tap_a)); + EXPECT_TRUE(move_c->IsOverlapped(*tap_a)); + EXPECT_FALSE(move_b->IsOverlapped(*move_c)); + + EXPECT_FALSE(tap_b->IsOverlapped(*move_a)); + EXPECT_FALSE(tap_b->IsOverlapped(*move_b)); + EXPECT_FALSE(tap_b->IsOverlapped(*move_c)); + EXPECT_FALSE(tap_b->IsOverlapped(*tap_a)); +} + } // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/edit_label.cc b/chrome/browser/ash/arc/input_overlay/ui/edit_label.cc index 56e7e249..7fc25fc3 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/edit_label.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/edit_label.cc
@@ -7,6 +7,7 @@ #include "ash/bubble/bubble_utils.h" #include "ash/style/typography.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ash/arc/input_overlay/actions/action.h" #include "chrome/browser/ash/arc/input_overlay/actions/input_element.h" #include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" @@ -18,9 +19,11 @@ #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/models/image_model.h" #include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/views/background.h" #include "ui/views/border.h" +#include "ui/views/controls/button/button.h" namespace arc::input_overlay { @@ -39,23 +42,16 @@ void EditLabel::OnActionInputBindingUpdated() { is_new_ = false; - if (action_->GetCurrentDisplayedInput().input_sources() == - InputSource::IS_NONE) { - SetTextLabel(kUnknownBind); - } else { - const auto& keys = action_->GetCurrentDisplayedInput().keys(); - DCHECK(index_ < keys.size()); - SetTextLabel(GetDisplayText(keys[index_])); - } + SetLabelContent(); } bool EditLabel::IsInputUnbound() { - return GetText().compare(kUnknownBind) == 0; + return GetText().compare(kUnknownBind) == 0 || GetText().empty(); } void EditLabel::RemoveNewState() { is_new_ = false; - OnActionInputBindingUpdated(); + SetLabelContent(); } void EditLabel::Init() { @@ -72,7 +68,31 @@ SetHasInkDropActionOnClick(false); ash::bubble_utils::ApplyStyle(label(), ash::TypographyToken::kCrosHeadline1, cros_tokens::kCrosSysOnPrimaryContainer); - OnActionInputBindingUpdated(); + SetLabelContent(); +} + +void EditLabel::SetLabelContent() { + // Clear icon if it is not for new action label. + SetImageModel(views::Button::STATE_NORMAL, + is_new_ ? ui::ImageModel::FromVectorIcon( + kGameControlsEditPenIcon, + cros_tokens::kCrosSysHighlightShape) + : ui::ImageModel()); + if (is_new_) { + SetBackground(views::CreateThemedRoundedRectBackground( + cros_tokens::kCrosSysHighlightShape, + /*radius=*/8)); + return; + } + + std::u16string output_string = kUnknownBind; + if (action_->GetCurrentDisplayedInput().input_sources() != + InputSource::IS_NONE) { + const auto& keys = action_->GetCurrentDisplayedInput().keys(); + DCHECK(index_ < keys.size()); + output_string = GetDisplayText(keys[index_]); + } + SetTextLabel(output_string); } void EditLabel::SetTextLabel(const std::u16string& text) { @@ -92,8 +112,9 @@ void EditLabel::SetNameTagState(bool is_error, const std::u16string& error_tooltip) { DCHECK(parent()); + DCHECK(!is_new_); auto* parent_view = static_cast<EditLabels*>(parent()); - parent_view->SetNameTagState(is_error && !is_new_, error_tooltip); + parent_view->SetNameTagState(is_error, error_tooltip); } std::u16string EditLabel::CalculateAccessibleName() { @@ -119,21 +140,36 @@ void EditLabel::OnFocus() { LabelButton::OnFocus(); + if (is_new_) { + // Hide the pen icon once the label is focused to edit. + SetImageModel(views::Button::STATE_NORMAL, ui::ImageModel()); + } SetToFocused(); } void EditLabel::OnBlur() { LabelButton::OnBlur(); + // The label is considered not in new state anymore once it leaves focus. + is_new_ = false; SetToDefault(); // Reset the error state if an reserved key was pressed. SetNameTagState(/*is_error=*/false, u""); } bool EditLabel::OnKeyPressed(const ui::KeyEvent& event) { + // The label is considered not in new state anymore once it tries to edit the + // label. + is_new_ = false; auto code = event.code(); std::u16string new_bind = GetDisplayText(code); - if (GetText() == new_bind || - (!action_->support_modifier_key() && + // Don't show error when the same key is pressed. + if (GetText() == new_bind) { + SetNameTagState(/*is_error=*/false, u""); + return true; + } + + // Show error when the reserved keys and modifier keys are pressed. + if ((!action_->support_modifier_key() && ModifierDomCodeToEventFlag(code) != ui::EF_NONE) || IsReservedDomCode(code)) { SetNameTagState(
diff --git a/chrome/browser/ash/arc/input_overlay/ui/edit_label.h b/chrome/browser/ash/arc/input_overlay/ui/edit_label.h index a38c32a..b03c7cf5 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/edit_label.h +++ b/chrome/browser/ash/arc/input_overlay/ui/edit_label.h
@@ -38,6 +38,8 @@ friend class EditLabelTest; void Init(); + // Set label content depends on whether the label is in new state. + void SetLabelContent(); void SetTextLabel(const std::u16string& text); void SetNameTagState(bool is_error, const std::u16string& error_tooltip); std::u16string CalculateAccessibleName();
diff --git a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc index ec7a790..0e6bae2e 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc
@@ -204,10 +204,8 @@ DCHECK(scroll_content_); auto* content_container = - scroll_content_->AddChildView(std::make_unique<ash::RoundedContainer>()); - content_container->SetBackground( - views::CreateThemedSolidBackground(cros_tokens::kCrosSysSystemOnBase)); - content_container->SetBorderInsets(gfx::Insets::VH(48, 32)); + scroll_content_->AddChildView(std::make_unique<views::View>()); + content_container->SetProperty(views::kMarginsKey, gfx::Insets::VH(48, 32)); content_container ->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical))
diff --git a/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view.cc b/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view.cc index 7996267..b3fbb7ec 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/menu_entry_view.cc
@@ -8,13 +8,13 @@ #include "ash/app_list/app_list_util.h" #include "ash/style/style_util.h" -#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ash/arc/input_overlay/arc_input_overlay_uma.h" #include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" #include "chrome/browser/ash/arc/input_overlay/touch_injector.h" #include "chrome/browser/ash/arc/input_overlay/util.h" #include "chrome/grit/generated_resources.h" #include "chromeos/strings/grit/chromeos_strings.h" +#include "chromeos/ui/vector_icons/vector_icons.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" #include "ui/color/color_id.h" @@ -159,8 +159,8 @@ SetImageModel( views::Button::STATE_NORMAL, - ui::ImageModel::FromVectorIcon(kGameControlsGamepadIcon, SK_ColorBLACK, - kMenuEntryIconSize)); + ui::ImageModel::FromVectorIcon(chromeos::kGameDashboardGamepadIcon, + SK_ColorBLACK, kMenuEntryIconSize)); SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER); SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc index 5660fe4..1aebaeb351 100644 --- a/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc +++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_apitest.cc
@@ -547,10 +547,7 @@ : public AutotestPrivateApiTest, public ::testing::WithParamInterface</* tablet_mode =*/bool> { public: - AutotestPrivateSearchTest() { - feature_list.InitAndEnableFeature( - ash::features::kAutocompleteExtendedSuggestions); - } + AutotestPrivateSearchTest() = default; ~AutotestPrivateSearchTest() override = default; AutotestPrivateSearchTest(const AutotestPrivateSearchTest&) = delete; @@ -595,9 +592,6 @@ } return results; } - - private: - base::test::ScopedFeatureList feature_list; }; INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chrome/browser/ash/featured_integration_test.cc b/chrome/browser/ash/featured_integration_test.cc index cb4f881..4676184b 100644 --- a/chrome/browser/ash/featured_integration_test.cc +++ b/chrome/browser/ash/featured_integration_test.cc
@@ -13,6 +13,8 @@ #include "base/task/task_traits.h" #include "base/test/scoped_feature_list.h" #include "base/values.h" +#include "chrome/test/base/chromeos/crosier/chromeos_test_definition.pb.h" +#include "chrome/test/base/chromeos/crosier/crosier_util.h" #include "chrome/test/base/chromeos/crosier/interactive_ash_test.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -46,6 +48,22 @@ GetParam().disabled_features); } + // InteractiveAshTest: + void SetUpOnMainThread() override { + InteractiveAshTest::SetUpOnMainThread(); + + chrome_test_base_chromeos_crosier::TestInfo info; + info.set_description( + "Verifies features are enabled/disabled as expected and parameters are " + "unchanged"); + info.set_team_email("cros-telemetry@google.com"); + info.add_contacts("kendraketsui@google.com"); + info.add_contacts("mutexlox@google.com"); + info.add_contacts("jamescook@google.com"); // Ported from Tast to Crosier. + info.set_buganizer("1096648"); + crosier_util::AddTestInfo(info); + } + base::test::ScopedFeatureList feature_list_; };
diff --git a/chrome/browser/ash/login/screens/multidevice_setup_screen.cc b/chrome/browser/ash/login/screens/multidevice_setup_screen.cc index 674e799f..e6eed61 100644 --- a/chrome/browser/ash/login/screens/multidevice_setup_screen.cc +++ b/chrome/browser/ash/login/screens/multidevice_setup_screen.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash/login/screens/multidevice_setup_screen.h" +#include "ash/constants/ash_switches.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/logging.h" @@ -78,6 +79,11 @@ } bool MultiDeviceSetupScreen::MaybeSkip(WizardContext& context) { + // Skip multidevice setup screen during oobe.SmokeEndToEnd test. + if (switches::ShouldMultideviceScreenBeSkippedForTesting()) { + return true; + } + // Only attempt the setup flow for non-guest users. if (context.skip_post_login_screens_for_tests || chrome_user_manager_util::IsManagedGuestSessionOrEphemeralLogin()) {
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums.cc index 7aa98718..faa766306 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums.cc
@@ -8,7 +8,7 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/ambient/ambient_backend_controller.h" -#include "ash/public/cpp/ambient/common/ambient_settings.h" +#include "ash/webui/personalization_app/mojom/personalization_app.mojom-shared.h" #include "base/strings/utf_string_conversions.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -53,7 +53,7 @@ IDS_PERSONALIZATION_APP_TIME_OF_DAY_VIDEO_ALBUM_DESCRIPTION, product_name); album->url = GURL(video_album_info.url); - album->topic_source = AmbientModeTopicSource::kVideo; + album->topic_source = mojom::TopicSource::kVideo; output.emplace_back(std::move(album)); } }
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums_unittest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums_unittest.cc index 3672446..dcc7259e 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums_unittest.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/ambient_video_albums_unittest.cc
@@ -32,9 +32,9 @@ EXPECT_THAT(albums, UnorderedElementsAre( Pointee(FieldsAre(kCloudsAlbumId, false, "Cloud Flow", _, _, - AmbientModeTopicSource::kVideo, _)), + mojom::TopicSource::kVideo, _)), Pointee(FieldsAre(kNewMexicoAlbumId, true, "Earth Flow", _, _, - AmbientModeTopicSource::kVideo, _)))); + mojom::TopicSource::kVideo, _)))); albums.clear(); AppendAmbientVideoAlbums(AmbientVideo::kClouds, albums);
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc index 6f958425..2571781 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc
@@ -205,28 +205,28 @@ } void PersonalizationAppAmbientProviderImpl::SetTopicSource( - ash::AmbientModeTopicSource topic_source) { + mojom::TopicSource topic_source) { mojom::AmbientTheme current_theme = GetCurrentUiSettings().theme(); // The presence of the `kVideo` theme in pref automatically means the `kVideo` // topic source is active. `settings_` should be kept as the server's view of // the user's ambient settings, and `SetAmbientTheme(kVideo)` already // broadcasts an `OnTopicSourceChanged()`, so there's no work to do here. if (current_theme == mojom::AmbientTheme::kVideo) { - if (topic_source != AmbientModeTopicSource::kVideo) { + if (topic_source != mojom::TopicSource::kVideo) { LOG(ERROR) << "Cannot set topic source to " << static_cast<int>(topic_source) << " for video theme"; } return; } - if (topic_source == AmbientModeTopicSource::kVideo) { + if (topic_source == mojom::TopicSource::kVideo) { LOG(ERROR) << "Video topic source does not apply to theme " << ambient::util::AmbientThemeToString(current_theme); return; } // If this is an Art gallery album page, will select art gallery topic source. - if (topic_source == ash::AmbientModeTopicSource::kArtGallery) { + if (topic_source == mojom::TopicSource::kArtGallery) { MaybeUpdateTopicSource(topic_source); return; } @@ -234,12 +234,12 @@ // If this is a Google Photos album page, will // 1. Select art gallery topic source if no albums or no album is selected. if (settings_->selected_album_ids.empty()) { - MaybeUpdateTopicSource(ash::AmbientModeTopicSource::kArtGallery); + MaybeUpdateTopicSource(mojom::TopicSource::kArtGallery); return; } // 2. Select Google Photos topic source if at least one album is selected. - MaybeUpdateTopicSource(ash::AmbientModeTopicSource::kGooglePhotos); + MaybeUpdateTopicSource(mojom::TopicSource::kGooglePhotos); } void PersonalizationAppAmbientProviderImpl::SetScreenSaverDuration( @@ -260,10 +260,10 @@ void PersonalizationAppAmbientProviderImpl::SetAlbumSelected( const std::string& id, - ash::AmbientModeTopicSource topic_source, + mojom::TopicSource topic_source, bool selected) { switch (topic_source) { - case (ash::AmbientModeTopicSource::kGooglePhotos): { + case (mojom::TopicSource::kGooglePhotos): { ash::PersonalAlbum* target_personal_album = FindPersonalAlbumById(id); if (!target_personal_album) { ambient_receiver_.ReportBadMessage("Invalid album id."); @@ -282,9 +282,9 @@ // Update topic source based on selections. if (settings_->selected_album_ids.empty()) { - settings_->topic_source = ash::AmbientModeTopicSource::kArtGallery; + settings_->topic_source = mojom::TopicSource::kArtGallery; } else { - settings_->topic_source = ash::AmbientModeTopicSource::kGooglePhotos; + settings_->topic_source = mojom::TopicSource::kGooglePhotos; } ash::ambient::RecordAmbientModeTotalNumberOfAlbums( @@ -293,7 +293,7 @@ settings_->selected_album_ids.size()); break; } - case (ash::AmbientModeTopicSource::kArtGallery): { + case (mojom::TopicSource::kArtGallery): { // For Art gallery, we set the corresponding setting to be enabled or not // based on the selections. auto* art_setting = FindArtAlbumById(id); @@ -304,7 +304,7 @@ art_setting->enabled = selected; break; } - case AmbientModeTopicSource::kVideo: + case mojom::TopicSource::kVideo: if (!selected) { DVLOG(4) << "Exactly one video must be selected at all times. Setting " "the desired video to selected==true automatically " @@ -426,8 +426,8 @@ // previews. OnPreviewsFetched(std::vector<GURL>()); if (features::IsPersonalizationJellyEnabled() || - GetCurrentTopicSource() == AmbientModeTopicSource::kGooglePhotos || - GetCurrentTopicSource() == AmbientModeTopicSource::kVideo) { + GetCurrentTopicSource() == mojom::TopicSource::kGooglePhotos || + GetCurrentTopicSource() == mojom::TopicSource::kVideo) { if (is_updating_backend_) { // Once settings updated, fetch preview images. needs_update_previews_ = true; @@ -457,7 +457,7 @@ album->description = personal_album.description; album->number_of_photos = personal_album.number_of_photos; album->url = GURL(personal_album.banner_image_url); - album->topic_source = ash::AmbientModeTopicSource::kGooglePhotos; + album->topic_source = mojom::TopicSource::kGooglePhotos; albums.emplace_back(std::move(album)); } @@ -475,7 +475,7 @@ album->title = setting.title; album->description = setting.description; album->url = GURL(setting.preview_image_url); - album->topic_source = ash::AmbientModeTopicSource::kArtGallery; + album->topic_source = mojom::TopicSource::kArtGallery; albums.emplace_back(std::move(album)); } @@ -510,7 +510,7 @@ DCHECK(IsAmbientModeEnabled()) << "Ambient mode must be enabled to update settings"; DCHECK(settings_); - DCHECK_NE(settings_->topic_source, AmbientModeTopicSource::kVideo) + DCHECK_NE(settings_->topic_source, mojom::TopicSource::kVideo) << "Ambient backend is not aware of the video topic source"; // Prevent fetch settings callback changing `settings_` and `personal_albums_` @@ -625,13 +625,13 @@ } if (settings_->selected_album_ids.empty()) { - MaybeUpdateTopicSource(ash::AmbientModeTopicSource::kArtGallery); + MaybeUpdateTopicSource(mojom::TopicSource::kArtGallery); } } void PersonalizationAppAmbientProviderImpl::MaybeUpdateTopicSource( - ash::AmbientModeTopicSource topic_source) { - DCHECK_NE(settings_->topic_source, AmbientModeTopicSource::kVideo) + mojom::TopicSource topic_source) { + DCHECK_NE(settings_->topic_source, mojom::TopicSource::kVideo) << "Video topic source should automatically get set via the video " "AmbientTheme. Should not be reflected in the server."; // If the setting is the same, no need to update. @@ -748,10 +748,10 @@ } } -AmbientModeTopicSource +mojom::TopicSource PersonalizationAppAmbientProviderImpl::GetCurrentTopicSource() const { if (GetCurrentUiSettings().theme() == mojom::AmbientTheme::kVideo) { - return AmbientModeTopicSource::kVideo; + return mojom::TopicSource::kVideo; } else { DCHECK(settings_); return settings_->topic_source;
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h index 854213e0..05f7376 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h
@@ -54,11 +54,11 @@ void SetAmbientModeEnabled(bool enabled) override; void SetAmbientTheme(mojom::AmbientTheme ambient_theme) override; void SetScreenSaverDuration(int minutes) override; - void SetTopicSource(ash::AmbientModeTopicSource topic_source) override; + void SetTopicSource(mojom::TopicSource topic_source) override; void SetTemperatureUnit( ash::AmbientModeTemperatureUnit temperature_unit) override; void SetAlbumSelected(const std::string& id, - ash::AmbientModeTopicSource topic_source, + mojom::TopicSource topic_source, bool selected) override; void SetPageViewed() override; void FetchSettingsAndAlbums() override; @@ -100,7 +100,7 @@ void SyncSettingsAndAlbums(); // Update topic source if needed. - void MaybeUpdateTopicSource(ash::AmbientModeTopicSource topic_source); + void MaybeUpdateTopicSource(mojom::TopicSource topic_source); void FetchPreviewImages(); void OnPreviewsFetched(const std::vector<GURL>& preview_urls); @@ -118,7 +118,7 @@ // leave `settings_` untouched while the video theme is active so that the // user's exact `AmbientSettings` can be restored when switching back to a // non-video theme (ex: slideshow). - AmbientModeTopicSource GetCurrentTopicSource() const; + mojom::TopicSource GetCurrentTopicSource() const; void BroadcastAmbientModeEnabledStatus(bool enabled);
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc index 7ace8d1..c13e88d 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc
@@ -69,7 +69,7 @@ ambient_theme_ = ambient_theme; } - void OnTopicSourceChanged(ash::AmbientModeTopicSource topic_source) override { + void OnTopicSourceChanged(mojom::TopicSource topic_source) override { topic_source_ = topic_source; } @@ -116,7 +116,7 @@ return ambient_theme_; } - ash::AmbientModeTopicSource topic_source() { + mojom::TopicSource topic_source() { ambient_observer_receiver_.FlushForTesting(); return topic_source_; } @@ -150,8 +150,7 @@ mojom::AmbientTheme ambient_theme_ = mojom::AmbientTheme::kSlideshow; uint32_t duration_ = 10; - ash::AmbientModeTopicSource topic_source_ = - ash::AmbientModeTopicSource::kArtGallery; + mojom::TopicSource topic_source_ = mojom::TopicSource::kArtGallery; ash::AmbientModeTemperatureUnit temperature_unit_ = ash::AmbientModeTemperatureUnit::kFahrenheit; ash::AmbientUiVisibility ambient_ui_visibility_ = @@ -247,7 +246,7 @@ return test_ambient_observer_.ambient_theme(); } - ash::AmbientModeTopicSource ObservedTopicSource() { + mojom::TopicSource ObservedTopicSource() { ambient_provider_remote_.FlushForTesting(); return test_ambient_observer_.topic_source(); } @@ -303,12 +302,12 @@ ambient_provider_->SetScreenSaverDuration(minutes); } - void SetTopicSource(ash::AmbientModeTopicSource topic_source) { + void SetTopicSource(mojom::TopicSource topic_source) { ambient_provider_->SetTopicSource(topic_source); } void SetAlbumSelected(base::StringPiece id, - ash::AmbientModeTopicSource topic_source, + mojom::TopicSource topic_source, bool selected) { ambient_provider_->SetAlbumSelected(std::string(id), topic_source, selected); @@ -316,7 +315,7 @@ void FetchPreviewImages() { ambient_provider_->FetchPreviewImages(); } - ash::AmbientModeTopicSource TopicSource() { + mojom::TopicSource TopicSource() { return ambient_provider_->settings_->topic_source; } @@ -535,27 +534,27 @@ FetchSettings(); ReplyFetchSettingsAndAlbums(/*success=*/true); // The default theme is video theme. - EXPECT_EQ(AmbientModeTopicSource::kVideo, ObservedTopicSource()); + EXPECT_EQ(mojom::TopicSource::kVideo, ObservedTopicSource()); EXPECT_FALSE(ObservedPreviews().empty()); // The other topic sources do not apply to the video theme, so all other // `SetTopicSource()` calls should be rejected. - SetTopicSource(AmbientModeTopicSource::kArtGallery); - EXPECT_EQ(AmbientModeTopicSource::kVideo, ObservedTopicSource()); - SetTopicSource(AmbientModeTopicSource::kGooglePhotos); - EXPECT_EQ(AmbientModeTopicSource::kVideo, ObservedTopicSource()); + SetTopicSource(mojom::TopicSource::kArtGallery); + EXPECT_EQ(mojom::TopicSource::kVideo, ObservedTopicSource()); + SetTopicSource(mojom::TopicSource::kGooglePhotos); + EXPECT_EQ(mojom::TopicSource::kVideo, ObservedTopicSource()); // Set to a different theme and select different topic source. SetAmbientTheme(mojom::AmbientTheme::kSlideshow); - EXPECT_EQ(ash::AmbientModeTopicSource::kGooglePhotos, ObservedTopicSource()); + EXPECT_EQ(mojom::TopicSource::kGooglePhotos, ObservedTopicSource()); - SetTopicSource(ash::AmbientModeTopicSource::kArtGallery); - EXPECT_EQ(ash::AmbientModeTopicSource::kArtGallery, ObservedTopicSource()); + SetTopicSource(mojom::TopicSource::kArtGallery); + EXPECT_EQ(mojom::TopicSource::kArtGallery, ObservedTopicSource()); // The `kVideo` topic source is exclusive to the `kVideo` theme. It does not // apply to any of the other themes, so the existing topic source sticks. - SetTopicSource(ash::AmbientModeTopicSource::kVideo); - EXPECT_EQ(ash::AmbientModeTopicSource::kArtGallery, ObservedTopicSource()); + SetTopicSource(mojom::TopicSource::kVideo); + EXPECT_EQ(mojom::TopicSource::kArtGallery, ObservedTopicSource()); } TEST_F(PersonalizationAppAmbientProviderImplTest, ShouldCallOnAlbumsChanged) { @@ -612,22 +611,22 @@ // Switch to other theme (kSlideshow) to try different topic sources. SetAmbientTheme(mojom::AmbientTheme::kSlideshow); - EXPECT_EQ(ash::AmbientModeTopicSource::kGooglePhotos, TopicSource()); + EXPECT_EQ(mojom::TopicSource::kGooglePhotos, TopicSource()); - SetTopicSource(ash::AmbientModeTopicSource::kArtGallery); - EXPECT_EQ(ash::AmbientModeTopicSource::kArtGallery, TopicSource()); + SetTopicSource(mojom::TopicSource::kArtGallery); + EXPECT_EQ(mojom::TopicSource::kArtGallery, TopicSource()); - SetTopicSource(ash::AmbientModeTopicSource::kGooglePhotos); - EXPECT_EQ(ash::AmbientModeTopicSource::kGooglePhotos, TopicSource()); + SetTopicSource(mojom::TopicSource::kGooglePhotos); + EXPECT_EQ(mojom::TopicSource::kGooglePhotos, TopicSource()); // If `settings_->selected_album_ids` is empty, will fallback to kArtGallery. SetSelectedAlbumIds(/*ids=*/{}); - SetTopicSource(ash::AmbientModeTopicSource::kGooglePhotos); - EXPECT_EQ(ash::AmbientModeTopicSource::kArtGallery, TopicSource()); + SetTopicSource(mojom::TopicSource::kGooglePhotos); + EXPECT_EQ(mojom::TopicSource::kArtGallery, TopicSource()); SetSelectedAlbumIds(/*ids=*/{"1"}); - SetTopicSource(ash::AmbientModeTopicSource::kGooglePhotos); - EXPECT_EQ(ash::AmbientModeTopicSource::kGooglePhotos, TopicSource()); + SetTopicSource(mojom::TopicSource::kGooglePhotos); + EXPECT_EQ(mojom::TopicSource::kGooglePhotos, TopicSource()); } TEST_F(PersonalizationAppAmbientProviderImplTest, SetTemperatureUnit) { @@ -863,25 +862,25 @@ ash::personalization_app::mojom::AmbientModeAlbumPtr album = ash::personalization_app::mojom::AmbientModeAlbum::New(); album->id = '1'; - album->topic_source = ash::AmbientModeTopicSource::kGooglePhotos; + album->topic_source = mojom::TopicSource::kGooglePhotos; album->checked = false; SetAlbumSelected(album->id, album->topic_source, album->checked); selected_ids = SelectedAlbumIds(); EXPECT_TRUE(selected_ids.empty()); // Will fallback to Art topic source if no selected Google Photos. - EXPECT_EQ(ash::AmbientModeTopicSource::kArtGallery, TopicSource()); + EXPECT_EQ(mojom::TopicSource::kArtGallery, TopicSource()); album = ash::personalization_app::mojom::AmbientModeAlbum::New(); album->id = '1'; - album->topic_source = ash::AmbientModeTopicSource::kGooglePhotos; + album->topic_source = mojom::TopicSource::kGooglePhotos; album->checked = true; SetAlbumSelected(album->id, album->topic_source, album->checked); selected_ids = SelectedAlbumIds(); EXPECT_EQ(1u, selected_ids.size()); EXPECT_TRUE(base::Contains(selected_ids, "1")); - EXPECT_EQ(ash::AmbientModeTopicSource::kGooglePhotos, TopicSource()); + EXPECT_EQ(mojom::TopicSource::kGooglePhotos, TopicSource()); } TEST_F(PersonalizationAppAmbientProviderImplTest, TestSetSelectedArtAlbum) { @@ -897,7 +896,7 @@ ash::personalization_app::mojom::AmbientModeAlbumPtr album = ash::personalization_app::mojom::AmbientModeAlbum::New(); album->id = '0'; - album->topic_source = ash::AmbientModeTopicSource::kArtGallery; + album->topic_source = mojom::TopicSource::kArtGallery; album->checked = false; SetAlbumSelected(album->id, album->topic_source, album->checked); @@ -906,7 +905,7 @@ album = ash::personalization_app::mojom::AmbientModeAlbum::New(); album->id = '1'; - album->topic_source = ash::AmbientModeTopicSource::kArtGallery; + album->topic_source = mojom::TopicSource::kArtGallery; album->checked = true; SetAlbumSelected(album->id, album->topic_source, album->checked); @@ -941,24 +940,24 @@ FetchSettings(); ReplyFetchSettingsAndAlbums(/*success=*/true); // As Time of Day features are enabled, the default theme should be kVideo. - EXPECT_EQ(ObservedTopicSource(), AmbientModeTopicSource::kVideo); + EXPECT_EQ(ObservedTopicSource(), mojom::TopicSource::kVideo); // The default video should be checked. expect_videos_selected(/*clouds_selected=*/false, /*new_mexico_selected=*/true); // Switch video to clouds. - SetAlbumSelected(kCloudsAlbumId, AmbientModeTopicSource::kVideo, true); + SetAlbumSelected(kCloudsAlbumId, mojom::TopicSource::kVideo, true); expect_videos_selected(/*clouds_selected=*/true, /*new_mexico_selected=*/false); // Switch back to new mexico. - SetAlbumSelected(kNewMexicoAlbumId, AmbientModeTopicSource::kVideo, true); + SetAlbumSelected(kNewMexicoAlbumId, mojom::TopicSource::kVideo, true); expect_videos_selected(/*clouds_selected=*/false, /*new_mexico_selected=*/true); // Should never be in a state where there are no videos selected. - SetAlbumSelected(kNewMexicoAlbumId, AmbientModeTopicSource::kVideo, false); + SetAlbumSelected(kNewMexicoAlbumId, mojom::TopicSource::kVideo, false); expect_videos_selected(/*clouds_selected=*/false, /*new_mexico_selected=*/true); @@ -975,7 +974,7 @@ ash::personalization_app::mojom::AmbientModeAlbumPtr album = ash::personalization_app::mojom::AmbientModeAlbum::New(); album->id = '0'; - album->topic_source = ash::AmbientModeTopicSource::kGooglePhotos; + album->topic_source = mojom::TopicSource::kGooglePhotos; SetAlbumSelected(album->id, album->topic_source, album->checked); histogram_tester().ExpectTotalCount("Ash.AmbientMode.TotalNumberOfAlbums", /*count=*/1); @@ -1036,7 +1035,7 @@ FetchSettings(); // Reply with settings with |kGooglePhotos| but empty |selected_album_ids|. ash::AmbientSettings settings; - settings.topic_source = AmbientModeTopicSource::kGooglePhotos; + settings.topic_source = mojom::TopicSource::kGooglePhotos; ReplyFetchSettingsAndAlbums(/*success=*/true, /*settings=*/std::move(settings)); } @@ -1051,7 +1050,7 @@ FetchSettings(); ReplyFetchSettingsAndAlbums(/*success=*/true); - EXPECT_EQ(ObservedTopicSource(), AmbientModeTopicSource::kVideo); + EXPECT_EQ(ObservedTopicSource(), mojom::TopicSource::kVideo); EXPECT_THAT(ObservedAlbums(), Contains(Pointee( AllOf(Field(&mojom::AmbientModeAlbum::id, Eq(kCloudsAlbumId)), @@ -1059,13 +1058,13 @@ // Switch to slide show mode and change settings to some custom configuration. SetAmbientTheme(mojom::AmbientTheme::kSlideshow); - SetTopicSource(AmbientModeTopicSource::kArtGallery); - SetAlbumSelected("1", AmbientModeTopicSource::kArtGallery, /*selected=*/true); + SetTopicSource(mojom::TopicSource::kArtGallery); + SetAlbumSelected("1", mojom::TopicSource::kArtGallery, /*selected=*/true); ReplyUpdateSettings(/*success=*/true); // Switch back to video theme. Same video settings should remain. SetAmbientTheme(mojom::AmbientTheme::kVideo); - EXPECT_EQ(ObservedTopicSource(), AmbientModeTopicSource::kVideo); + EXPECT_EQ(ObservedTopicSource(), mojom::TopicSource::kVideo); EXPECT_THAT(ObservedAlbums(), Contains(Pointee( AllOf(Field(&mojom::AmbientModeAlbum::id, Eq(kCloudsAlbumId)), @@ -1073,7 +1072,7 @@ // Switch back to slide show. The custom setting set previously should stick. SetAmbientTheme(mojom::AmbientTheme::kSlideshow); - EXPECT_EQ(ObservedTopicSource(), AmbientModeTopicSource::kArtGallery); + EXPECT_EQ(ObservedTopicSource(), mojom::TopicSource::kArtGallery); EXPECT_THAT(ObservedAlbums(), Contains(Pointee( AllOf(Field(&mojom::AmbientModeAlbum::id, Eq("1")), @@ -1094,7 +1093,7 @@ // Should not get stuck in a state where video theme is active with a // non-video topic source. ASSERT_EQ(ObservedAmbientTheme(), mojom::AmbientTheme::kVideo); - EXPECT_EQ(ObservedTopicSource(), AmbientModeTopicSource::kVideo); + EXPECT_EQ(ObservedTopicSource(), mojom::TopicSource::kVideo); EXPECT_THAT(ObservedAlbums(), Contains(Pointee(AllOf( Field(&mojom::AmbientModeAlbum::id, Eq(kNewMexicoAlbumId)),
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc index 4f733bd..b710e59 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.cc +++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -229,12 +229,12 @@ std::string guid = ConvertJavaStringToUTF8(env, jguid); AutofillProfile profile = AutofillProfile::CreateFromJavaObject( - jprofile, g_browser_process->GetApplicationLocale()); + jprofile, personal_data_manager_->GetProfileByGUID(guid), + g_browser_process->GetApplicationLocale()); if (guid.empty()) { personal_data_manager_->AddProfile(profile); } else { - profile.set_guid(guid); personal_data_manager_->UpdateProfile(profile); } @@ -246,15 +246,14 @@ const JavaParamRef<jobject>& unused_obj, const JavaParamRef<jobject>& jprofile, const JavaParamRef<jstring>& jguid) { + const AutofillProfile* target_profile = + personal_data_manager_->GetProfileByGUID( + ConvertJavaStringToUTF8(env, jguid)); AutofillProfile profile = AutofillProfile::CreateFromJavaObject( - jprofile, g_browser_process->GetApplicationLocale()); - - AutofillProfile* target_profile = personal_data_manager_->GetProfileByGUID( - ConvertJavaStringToUTF8(env, jguid)); + jprofile, target_profile, g_browser_process->GetApplicationLocale()); if (target_profile != nullptr && target_profile->record_type() == AutofillProfile::LOCAL_PROFILE) { - profile.set_guid(target_profile->guid()); personal_data_manager_->UpdateProfile(profile); } else { personal_data_manager_->AddProfile(profile); @@ -318,8 +317,10 @@ ADDRESS_HOME_ZIP, ADDRESS_HOME_SORTING_CODE, }; + // TODO(crbug.com/1484006): Check if existing profile needs to be passed. AutofillProfile profile = AutofillProfile::CreateFromJavaObject( - jprofile, g_browser_process->GetApplicationLocale()); + jprofile, /*existing_profile=*/nullptr, + g_browser_process->GetApplicationLocale()); return ConvertUTF16ToJavaString( env, profile.ConstructInferredLabel( @@ -682,8 +683,10 @@ if (!include_country_in_label) --kLabelFields_size; + // TODO(crbug.com/1484006): Check if existing profile needs to be passed. AutofillProfile profile = AutofillProfile::CreateFromJavaObject( - jprofile, g_browser_process->GetApplicationLocale()); + jprofile, /*existing_profile=*/nullptr, + g_browser_process->GetApplicationLocale()); return ConvertUTF16ToJavaString( env, profile.ConstructInferredLabel(
diff --git a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc index 9838b63..84723db 100644 --- a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc +++ b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
@@ -245,8 +245,10 @@ const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& jprofile) { had_user_interaction_ = true; + AutofillProfile* existing_profile = + original_profile_.has_value() ? &original_profile_.value() : nullptr; AutofillProfile edited_profile = AutofillProfile::CreateFromJavaObject( - jprofile, g_browser_process->GetApplicationLocale()); + jprofile, existing_profile, g_browser_process->GetApplicationLocale()); profile_ = edited_profile; RunSaveAddressProfileCallback( AutofillClient::SaveAddressProfileOfferUserDecision::kEditAccepted);
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index c190a9d..9f62e9b 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -309,6 +309,8 @@ #include "chrome/browser/ui/webui/ash/emoji/emoji_ui.h" #include "chrome/browser/ui/webui/ash/emoji/new_window_proxy.h" #include "chrome/browser/ui/webui/ash/emoji/new_window_proxy.mojom.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.h" #include "chrome/browser/ui/webui/ash/internet_config_dialog.h" #include "chrome/browser/ui/webui/ash/internet_detail_dialog.h" #include "chrome/browser/ui/webui/ash/launcher_internals/launcher_internals.mojom.h" @@ -1477,6 +1479,10 @@ emoji_picker::mojom::PageHandlerFactory, ash::EmojiUI>(map); RegisterWebUIControllerInterfaceBinder< + enterprise_reporting::mojom::PageHandlerFactory, + ash::reporting::EnterpriseReportingUI>(map); + + RegisterWebUIControllerInterfaceBinder< ash::personalization_app::mojom::WallpaperProvider, ash::personalization_app::PersonalizationAppUI>(map);
diff --git a/chrome/browser/devtools/protocol/cast_handler.cc b/chrome/browser/devtools/protocol/cast_handler.cc index 42be5dbd..6b97e3f4a 100644 --- a/chrome/browser/devtools/protocol/cast_handler.cc +++ b/chrome/browser/devtools/protocol/cast_handler.cc
@@ -122,8 +122,7 @@ base::BindOnce(&CastHandler::OnDesktopMirroringStarted, weak_factory_.GetWeakPtr(), std::move(callback)), media_router::GetRouteRequestTimeout( - media_router::MediaCastMode::DESKTOP_MIRROR), - web_contents_->GetBrowserContext()->IsOffTheRecord()); + media_router::MediaCastMode::DESKTOP_MIRROR)); } void CastHandler::StartTabMirroring( @@ -147,8 +146,7 @@ base::BindOnce(&CastHandler::OnTabMirroringStarted, weak_factory_.GetWeakPtr(), std::move(callback)), media_router::GetRouteRequestTimeout( - media_router::MediaCastMode::TAB_MIRROR), - web_contents_->GetBrowserContext()->IsOffTheRecord()); + media_router::MediaCastMode::TAB_MIRROR)); } Response CastHandler::StopCasting(const std::string& in_sink_name) { @@ -233,8 +231,7 @@ base::BindOnce(&CastHandler::OnPresentationStarted, weak_factory_.GetWeakPtr(), std::move(context)), media_router::GetRouteRequestTimeout( - media_router::MediaCastMode::PRESENTATION), - web_contents_->GetBrowserContext()->IsOffTheRecord()); + media_router::MediaCastMode::PRESENTATION)); } media_router::MediaSink::Id CastHandler::GetSinkIdByName(
diff --git a/chrome/browser/devtools/protocol/cast_handler_unittest.cc b/chrome/browser/devtools/protocol/cast_handler_unittest.cc index 1846534..65dd9f8 100644 --- a/chrome/browser/devtools/protocol/cast_handler_unittest.cc +++ b/chrome/browser/devtools/protocol/cast_handler_unittest.cc
@@ -121,7 +121,7 @@ })); EXPECT_CALL(*router_, - CreateRouteInternal(presentation_url, kSinkId1, _, _, _, _, _)); + CreateRouteInternal(presentation_url, kSinkId1, _, _, _, _)); media_router::PresentationServiceDelegateImpl::GetOrCreateForWebContents( web_contents()) ->StartPresentation(request, base::DoNothing(), base::DoNothing()); @@ -137,7 +137,7 @@ EXPECT_CALL( *router_, CreateRouteInternal(media_router::MediaSource::ForUnchosenDesktop().id(), - kSinkId1, _, _, _, _, _)) + kSinkId1, _, _, _, _)) .WillOnce( WithArg<4>([](media_router::MediaRouteResponseCallback& callback) { std::move(callback).Run( @@ -172,7 +172,7 @@ media_router::MediaSource::ForTab( sessions::SessionTabHelper::IdForTab(web_contents()).id()) .id(), - kSinkId1, _, _, _, _, _)) + kSinkId1, _, _, _, _)) .WillOnce( WithArg<4>([](media_router::MediaRouteResponseCallback& callback) { std::move(callback).Run(
diff --git a/chrome/browser/download/bubble/download_display_controller.cc b/chrome/browser/download/bubble/download_display_controller.cc index 7d3466d..b74271a9 100644 --- a/chrome/browser/download/bubble/download_display_controller.cc +++ b/chrome/browser/download/bubble/download_display_controller.cc
@@ -324,7 +324,3 @@ return time_since_last_completion < interval && current_time >= last_complete_time; } - -bool DownloadDisplayController::IsDisplayShowingDetails() { - return display_->IsShowingDetails(); -}
diff --git a/chrome/browser/download/bubble/download_display_controller.h b/chrome/browser/download/bubble/download_display_controller.h index 414249c8..da26e048 100644 --- a/chrome/browser/download/bubble/download_display_controller.h +++ b/chrome/browser/download/bubble/download_display_controller.h
@@ -44,9 +44,6 @@ delete; ~DownloadDisplayController() override; - // Returns whether the display is showing details. - bool IsDisplayShowingDetails(); - // Notifies the controller that the button is pressed. Called by `display_`. void OnButtonPressed();
diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc index 9ebb1097..2129f56c 100644 --- a/chrome/browser/download/download_item_model.cc +++ b/chrome/browser/download/download_item_model.cc
@@ -234,19 +234,6 @@ #endif -// Enum representing reasons why a download is not preferred to be opened in -// browser. -enum class NotOpenedInBrowserReason { - // The total number of checks. This value should be used as the denominator - // when calculating the percentage of a specific reason below. - TOTAL_DOWNLOAD_CHECKED = 0, - DOWNLOAD_PATH_EMPTY = 1, - NOT_PREFERRED_IN_DELEGATE = 2, - CANNOT_BE_HANDLED_SAFELY = 3, - - kMaxValue = CANNOT_BE_HANDLED_SAFELY -}; - } // namespace // ----------------------------------------------------------------------------- @@ -812,7 +799,6 @@ case DownloadCommands::ALWAYS_OPEN_TYPE: { bool is_checked = IsCommandChecked(download_commands, DownloadCommands::ALWAYS_OPEN_TYPE); - base::UmaHistogramBoolean("Download.SetAlwaysOpenTo", !is_checked); DownloadPrefs* prefs = DownloadPrefs::FromBrowserContext(profile()); #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ BUILDFLAG(IS_MAC) @@ -1175,24 +1161,6 @@ if (!delegate) return; - // TODO(crbug.com/1372476): Remove this histogram and the associated enum - // after debugging. - base::UmaHistogramEnumeration( - "Download.NotPreferredOpeningInBrowserReasons", - NotOpenedInBrowserReason::TOTAL_DOWNLOAD_CHECKED); - if (target_path.empty()) { - base::UmaHistogramEnumeration( - "Download.NotPreferredOpeningInBrowserReasons", - NotOpenedInBrowserReason::DOWNLOAD_PATH_EMPTY); - } else if (!delegate->IsOpenInBrowserPreferreredForFile(target_path)) { - base::UmaHistogramEnumeration( - "Download.NotPreferredOpeningInBrowserReasons", - NotOpenedInBrowserReason::NOT_PREFERRED_IN_DELEGATE); - } else if (!is_filetype_handled_safely) { - base::UmaHistogramEnumeration( - "Download.NotPreferredOpeningInBrowserReasons", - NotOpenedInBrowserReason::CANNOT_BE_HANDLED_SAFELY); - } if (!target_path.empty() && delegate->IsOpenInBrowserPreferreredForFile(target_path) && is_filetype_handled_safely) {
diff --git a/chrome/browser/download/download_session_durations_metrics_recorder.cc b/chrome/browser/download/download_session_durations_metrics_recorder.cc deleted file mode 100644 index 22ac608b5..0000000 --- a/chrome/browser/download/download_session_durations_metrics_recorder.cc +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/download/download_session_durations_metrics_recorder.h" - -#include "base/metrics/histogram_functions.h" -#include "chrome/browser/download/bubble/download_bubble_ui_controller.h" -#include "chrome/browser/download/bubble/download_display_controller.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" - -namespace { -bool IsDownloadBubbleShowing() { - Browser* browser = chrome::FindLastActive(); - return browser && browser->window() && - browser->window()->GetDownloadBubbleUIController() && - browser->window() - ->GetDownloadBubbleUIController() - ->GetDownloadDisplayController() - ->IsDisplayShowingDetails(); -} -} // namespace - -DownloadSessionDurationsMetricsRecorder:: - DownloadSessionDurationsMetricsRecorder() - : session_start_(base::TimeTicks::Now()) {} - -void DownloadSessionDurationsMetricsRecorder::OnSessionStarted( - base::TimeTicks session_start) { - base::UmaHistogramBoolean( - "Download.Session.IsDownloadBubbleShowingWhenSessionStarts", - IsDownloadBubbleShowing()); - // Do not reset the session start time if the bubble is showing when the last - // session ends. Assume user is spending time on the bubble during this - // period. - if (!is_bubble_showing_when_session_end_) { - session_start_ = session_start; - } -} - -void DownloadSessionDurationsMetricsRecorder::OnSessionEnded( - base::TimeTicks session_end) { - is_bubble_showing_when_session_end_ = IsDownloadBubbleShowing(); - base::UmaHistogramBoolean( - "Download.Session.IsDownloadBubbleShowingWhenSessionEnds", - is_bubble_showing_when_session_end_); - if (!is_bubble_showing_when_session_end_) { - // `OnSessionEnded` can be called with some delays, so we can't use - // base::TimeTicks::Now() here. - base::UmaHistogramLongTimes( - "Download.Session.TotalDurationIncludingBubbleTime", - session_end - session_start_); - } -}
diff --git a/chrome/browser/download/download_session_durations_metrics_recorder.h b/chrome/browser/download/download_session_durations_metrics_recorder.h deleted file mode 100644 index 174f54e..0000000 --- a/chrome/browser/download/download_session_durations_metrics_recorder.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_SESSION_DURATIONS_METRICS_RECORDER_H_ -#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_SESSION_DURATIONS_METRICS_RECORDER_H_ - -#include "base/time/time.h" - -class DownloadSessionDurationsMetricsRecorder { - public: - DownloadSessionDurationsMetricsRecorder(); - ~DownloadSessionDurationsMetricsRecorder() = default; - DownloadSessionDurationsMetricsRecorder( - const DownloadSessionDurationsMetricsRecorder&) = delete; - - // Called from DesktopProfileSessionDurationsService - void OnSessionStarted(base::TimeTicks session_start); - void OnSessionEnded(base::TimeTicks session_end); - - private: - base::TimeTicks session_start_; - bool is_bubble_showing_when_session_end_ = false; -}; - -#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_SESSION_DURATIONS_METRICS_RECORDER_H_
diff --git a/chrome/browser/download/download_stats.cc b/chrome/browser/download/download_stats.cc index 33666536..2f5ba5e 100644 --- a/chrome/browser/download/download_stats.cc +++ b/chrome/browser/download/download_stats.cc
@@ -40,11 +40,6 @@ download::DownloadContent::MAX); } -void RecordDownloadOpenButtonPressed(bool is_download_completed) { - base::UmaHistogramBoolean("Download.OpenButtonPressed.IsDownloadCompleted", - is_download_completed); -} - void RecordDatabaseAvailability(bool is_available) { base::UmaHistogramBoolean("Download.Database.IsAvailable", is_available); }
diff --git a/chrome/browser/download/download_stats.h b/chrome/browser/download/download_stats.h index e84599b..f3baea37 100644 --- a/chrome/browser/download/download_stats.h +++ b/chrome/browser/download/download_stats.h
@@ -112,11 +112,6 @@ void RecordDownloadOpen(ChromeDownloadOpenMethod open_method, const std::string& mime_type_string); -// TODO(crbug.com/1372476): Remove this function after debugging. -// Record that a download open button was pressed, either on download shelf or -// download bubble. -void RecordDownloadOpenButtonPressed(bool is_download_completed); - // Record if the database is available to provide the next download id before // starting all downloads. void RecordDatabaseAvailability(bool is_available);
diff --git a/chrome/browser/enterprise/connectors/device_trust/test/device_trust_browsertest_base.cc b/chrome/browser/enterprise/connectors/device_trust/test/device_trust_browsertest_base.cc index 001d5c8..c5b70fa 100644 --- a/chrome/browser/enterprise/connectors/device_trust/test/device_trust_browsertest_base.cc +++ b/chrome/browser/enterprise/connectors/device_trust/test/device_trust_browsertest_base.cc
@@ -153,6 +153,9 @@ // Response header should always be set, even in error cases (i.e. // when using v1 header). EXPECT_TRUE(challenge_response_request_.has_value()); + if (!challenge_response_request_.has_value()) { + return std::string(); + } ExpectFunnelStep(DTAttestationFunnelStep::kAttestationFlowStarted); ExpectFunnelStep(DTAttestationFunnelStep::kChallengeReceived);
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc index 934cbef..0522b985 100644 --- a/chrome/browser/extensions/extension_context_menu_model.cc +++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -429,7 +429,7 @@ case PAGE_ACCESS_RUN_ON_CLICK: case PAGE_ACCESS_RUN_ON_SITE: case PAGE_ACCESS_RUN_ON_ALL_SITES: { - // If the web contents have navigated to a different origin, do nothing. + // Do nothing if the web contents have navigated to a different origin. auto* web_contents = GetActiveWebContents(); if (!web_contents || !origin_.IsSameOriginWith(web_contents->GetLastCommittedURL())) { @@ -437,6 +437,16 @@ } LogPageAccessAction(command_id); + + // Do nothing if the extension cannot have its site permissions updated. + // Page access option should only be enabled when the extension site + // permissions can be changed. However, sometimes the command still gets + // invoked (crbug.com/1468151). Thus, we exit early to prevent any + // crashes. + if (!PermissionsManager::Get(profile_)->CanAffectExtension(*extension)) { + return; + } + SitePermissionsHelper permissions(profile_); permissions.UpdateSiteAccess(*extension, web_contents, CommandIdToSiteAccess(command_id));
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 1c1a5fe..0301b4e5 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -217,11 +217,6 @@ "expiry_milestone": 128 }, { - "name": "app-collection-folder-refresh", - "owners": [ "wcwang", "//ash/app_list/OWNERS" ], - "expiry_milestone": 118 - }, - { "name": "app-deduplication-service-fondue", "owners": [ "tsergeant", "chromeos-apps-foundation-team@google.com" ], "expiry_milestone": 125 @@ -492,11 +487,6 @@ "expiry_milestone": 116 }, { - "name": "autocomplete-extended-suggestions", - "owners": [ "yulunwu", "tbarzic" ], - "expiry_milestone": 113 - }, - { "name": "autofill-account-profiles-storage", "owners": [ "vidhanj", "koerber" ], "expiry_milestone": 120 @@ -5111,7 +5101,7 @@ { "name": "ios-password-checkup", "owners": ["noemies", "eic", "bling-integrations-team@google.com"], - "expiry_milestone": 117 + "expiry_milestone": 120 }, { "name": "ios-password-ui-split", @@ -5163,6 +5153,11 @@ "expiry_milestone": 123 }, { + "name": "iph-ios-promo-manager-widget-promo", + "owners": [ "noemies", "tmartino", "bling-transactions@google.com", "bling-flags@google.com" ], + "expiry_milestone": 122 + }, + { "name": "iph-price-notifications-while-browsing", "owners": [ "danieltwhite", "ajuma" ], "expiry_milestone": 118 @@ -7331,11 +7326,6 @@ "expiry_milestone": 92 }, { - "name": "search-result-inline-icon", - "owners": ["yulunwu"], - "expiry_milestone": 103 - }, - { "name": "search-suggestion-for-prerender2", "owners": [ "//content/browser/preloading/prerender/OWNERS" ], "expiry_milestone": 122 @@ -7423,11 +7413,6 @@ "expiry_milestone": 114 }, { - "name": "shelf-drag-to-pin", - "owners": ["tbarzic", "//ash/shelf/OWNERS" ], - "expiry_milestone": 112 - }, - { "name": "shelf-stacked-hotseat", "owners": ["yulunwu", "//ash/shelf/OWNERS"], "expiry_milestone": 116
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 351301c..71e5d62 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -103,12 +103,6 @@ "Resumes animated images from the last frame drawn rather than attempt " "to catch up to the frame that should be drawn based on current time."; -const char kAppCollectionFolderRefreshName[] = - "App Collection feature: Folder icon refresh"; -const char kAppCollectionFolderRefreshDescription[] = - "Enables the App Collection feature: the new folder icon style in the app " - "list."; - const char kAriaElementReflectionName[] = "Enable ARIA element reflection"; const char kAriaElementReflectionDescription[] = "Enable setting ARIA relationship attributes that reference other elements " @@ -3074,11 +3068,6 @@ "Splits pinned and unpinned tabs into separate TabStrips under the hood. " "Pure refactoring, no user-visible behavioral changes are included."; -const char kSearchResultInlineIconName[] = "Search Result Inline Icons"; -const char kSearchResultInlineIconDescription[] = - "Show iconified text and vector icons " - "in launcher search results."; - const char kDynamicSearchUpdateAnimationName[] = "Dynamic Search Result Update Animation"; const char kDynamicSearchUpdateAnimationDescription[] = @@ -5533,11 +5522,6 @@ "Overrides the default to forcibly enable or disable the auto-framing " "feature"; -const char kAutocompleteExtendedSuggestionsName[] = - "Extended suggestions for CrOS autocomplete"; -const char kAutocompleteExtendedSuggestionsDescription[] = - "Enables extended autocomplete suggestions experiment on ChromeOS."; - const char kAutocorrectByDefaultName[] = "CrOS autocorrect by default"; const char kAutocorrectByDefaultDescription[] = "Enables autocorrect by default experiment on ChromeOS";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 61f89108..08119b7b 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -90,9 +90,6 @@ extern const char kAnimatedImageResumeName[]; extern const char kAnimatedImageResumeDescription[]; -extern const char kAppCollectionFolderRefreshName[]; -extern const char kAppCollectionFolderRefreshDescription[]; - extern const char kAriaElementReflectionName[]; extern const char kAriaElementReflectionDescription[]; @@ -1763,9 +1760,6 @@ extern const char kSplitTabStripName[]; extern const char kSplitTabStripDescription[]; -extern const char kSearchResultInlineIconName[]; -extern const char kSearchResultInlineIconDescription[]; - extern const char kDynamicSearchUpdateAnimationName[]; extern const char kDynamicSearchUpdateAnimationDescription[]; @@ -3204,9 +3198,6 @@ extern const char kAutoFramingOverrideName[]; extern const char kAutoFramingOverrideDescription[]; -extern const char kAutocompleteExtendedSuggestionsName[]; -extern const char kAutocompleteExtendedSuggestionsDescription[]; - extern const char kAutocorrectByDefaultName[]; extern const char kAutocorrectByDefaultDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 35bb334..ff3837b0 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -469,7 +469,7 @@ BASE_FEATURE(kAndroidAppIntegration, "AndroidAppIntegration", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kAndroidAppIntegrationSafeSearch, "AndroidAppIntegrationSafeSearch",
diff --git a/chrome/browser/media/router/chrome_media_router_factory.h b/chrome/browser/media/router/chrome_media_router_factory.h index 09f718de9..eb90ae66 100644 --- a/chrome/browser/media/router/chrome_media_router_factory.h +++ b/chrome/browser/media/router/chrome_media_router_factory.h
@@ -15,8 +15,8 @@ namespace media_router { -// A version of MediaRouterFactory for Chrome, which refers incognito contexts -// to their parent Profile. It also adds support for desktop features. +// A version of MediaRouterFactory for Chrome. It adds support for desktop +// features. class ChromeMediaRouterFactory : public MediaRouterFactory { public: ChromeMediaRouterFactory(const ChromeMediaRouterFactory&) = delete;
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index 1cbd65b..a0645c3 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -154,8 +154,7 @@ const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool off_the_record) { + base::TimeDelta timeout) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); CHECK(callback); const MediaSink* sink = GetSinkById(sink_id); @@ -192,9 +191,9 @@ const mojom::MediaRouteProviderId provider_id = sink->provider_id(); const std::string presentation_id = MediaRouterBase::CreatePresentationId(); - auto mr_callback = base::BindOnce(&MediaRouterDesktop::RouteResponseReceived, - AsWeakPtr(), presentation_id, provider_id, - off_the_record, std::move(callback), false); + auto mr_callback = + base::BindOnce(&MediaRouterDesktop::RouteResponseReceived, AsWeakPtr(), + presentation_id, provider_id, std::move(callback), false); if (source.IsDesktopMirroringSource()) { desktop_picker_.Show( @@ -203,15 +202,14 @@ base::BindRepeating([](content::WebContents* wc) { return true; }), base::BindOnce(&MediaRouterDesktop::CreateRouteWithSelectedDesktop, AsWeakPtr(), provider_id, sink_id, presentation_id, - origin, web_contents, timeout, off_the_record, - std::move(mr_callback))); + origin, web_contents, timeout, std::move(mr_callback))); } else { const int frame_tree_node_id = web_contents ? web_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId() : kDefaultFrameTreeNodeId; media_route_providers_[provider_id]->CreateRoute( source_id, sink_id, presentation_id, origin, frame_tree_node_id, - timeout, off_the_record, std::move(mr_callback)); + timeout, std::move(mr_callback)); } } @@ -224,8 +222,7 @@ const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool off_the_record) { + base::TimeDelta timeout) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); absl::optional<mojom::MediaRouteProviderId> provider_id = GetProviderIdForPresentation(presentation_id); @@ -242,12 +239,12 @@ const int frame_tree_node_id = web_contents ? web_contents->GetPrimaryMainFrame()->GetFrameTreeNodeId() : kDefaultFrameTreeNodeId; - auto mr_callback = base::BindOnce(&MediaRouterDesktop::RouteResponseReceived, - AsWeakPtr(), presentation_id, *provider_id, - off_the_record, std::move(callback), true); + auto mr_callback = + base::BindOnce(&MediaRouterDesktop::RouteResponseReceived, AsWeakPtr(), + presentation_id, *provider_id, std::move(callback), true); media_route_providers_[*provider_id]->JoinRoute( source_id, presentation_id, origin, frame_tree_node_id, timeout, - off_the_record, std::move(mr_callback)); + std::move(mr_callback)); } void MediaRouterDesktop::TerminateRoute(const MediaRoute::Id& route_id) { @@ -685,7 +682,6 @@ void MediaRouterDesktop::RouteResponseReceived( const std::string& presentation_id, mojom::MediaRouteProviderId provider_id, - bool is_off_the_record, MediaRouteResponseCallback callback, bool is_join, const absl::optional<MediaRoute>& media_route, @@ -701,12 +697,6 @@ ? *error_text : std::string("Unknown error."); result = RouteRequestResult::FromError(error, result_code); - } else if (media_route->is_off_the_record() != is_off_the_record) { - std::string error = base::StringPrintf( - "Mismatch in OffTheRecord status: request = %d, response = %d", - is_off_the_record, media_route->is_off_the_record()); - result = RouteRequestResult::FromError( - error, mojom::RouteRequestResultCode::ROUTE_NOT_FOUND); } else { result = RouteRequestResult::FromSuccess(*media_route, presentation_id); OnRouteAdded(provider_id, *media_route); @@ -866,7 +856,6 @@ const url::Origin& origin, content::WebContents* web_contents, base::TimeDelta timeout, - bool off_the_record, mojom::MediaRouteProvider::CreateRouteCallback mr_callback, const std::string& err, content::DesktopMediaID media_id) { @@ -887,7 +876,6 @@ media_route_providers_[provider_id]->CreateRoute( MediaSource::ForDesktop(media_id.ToString(), media_id.audio_share).id(), sink_id, presentation_id, origin, kDefaultFrameTreeNodeId, timeout, - off_the_record, base::BindOnce( [](mojom::MediaRouteProvider::CreateRouteCallback inner_callback, const absl::optional<media_router::MediaRoute>& route,
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.h b/chrome/browser/media/router/mojo/media_router_desktop.h index 5f8b8e5..f7c7827a 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.h +++ b/chrome/browser/media/router/mojo/media_router_desktop.h
@@ -77,15 +77,13 @@ const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool off_the_record) final; + base::TimeDelta timeout) final; void JoinRoute(const MediaSource::Id& source_id, const std::string& presentation_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool off_the_record) final; + base::TimeDelta timeout) final; void TerminateRoute(const MediaRoute::Id& route_id) final; // TODO(https://crbug.com/1198580): Remove DetachRoute(), SendRouteMessage(), // and SendRouteBinaryMessage(). @@ -178,7 +176,6 @@ // into a local callback. void RouteResponseReceived(const std::string& presentation_id, mojom::MediaRouteProviderId provider_id, - bool is_off_the_record, MediaRouteResponseCallback callback, bool is_join, const absl::optional<MediaRoute>& media_route, @@ -231,7 +228,6 @@ const url::Origin& origin, content::WebContents* web_contents, base::TimeDelta timeout, - bool off_the_record, mojom::MediaRouteProvider::CreateRouteCallback mr_callback, const std::string& err, content::DesktopMediaID media_id); @@ -300,8 +296,6 @@ friend class MediaRouterIntegrationBrowserTest; friend class MediaRouterNativeIntegrationBrowserTest; FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, JoinRouteTimedOutFails); - FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, - JoinRouteIncognitoMismatchFails); FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, HandleIssue); FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, PresentationConnectionStateChangedCallback); @@ -310,7 +304,6 @@ FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, TestRecordPresentationRequestUrlBySink); FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, TestGetCurrentRoutes); - FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, CreateIncognitoRoute); FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, CreateRouteFails); FRIEND_TEST_ALL_PREFIXES(MediaRouterDesktopTest, CreateRouteIncognitoMismatchFails);
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc index f723343..ad7b793 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -253,48 +253,13 @@ base::RunLoop().RunUntilIdle(); } -TEST_F(MediaRouterDesktopTest, CreateIncognitoRoute) { - ProvideTestSink(mojom::MediaRouteProviderId::CAST, kSinkId); - MediaSource media_source(kSource); - MediaRoute expected_route(kRouteId, media_source, kSinkId, "", false); - expected_route.set_off_the_record(true); - - // Use a lambda function as an invocation target here to work around - // a limitation with GMock::Invoke that prevents it from using move-only types - // in runnable parameter lists. - EXPECT_CALL(mock_cast_provider_, - CreateRouteInternal(kSource, kSinkId, _, - url::Origin::Create(GURL(kOrigin)), - kInvalidFrameNodeId, _, _, _)) - .WillOnce(WithArg<7>( - Invoke([&expected_route]( - mojom::MediaRouteProvider::CreateRouteCallback& cb) { - std::move(cb).Run(expected_route, nullptr, std::string(), - mojom::RouteRequestResultCode::OK); - }))); - - base::RunLoop run_loop; - RouteResponseCallbackHandler handler; - EXPECT_CALL(handler, DoInvoke(Pointee(expected_route), Not(""), "", - mojom::RouteRequestResultCode::OK, _)) - .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - router()->CreateRoute(kSource, kSinkId, url::Origin::Create(GURL(kOrigin)), - nullptr, - base::BindOnce(&RouteResponseCallbackHandler::Invoke, - base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), true); - run_loop.Run(); - ExpectCastResultBucketCount("CreateRoute", mojom::RouteRequestResultCode::OK, - 1); -} - TEST_F(MediaRouterDesktopTest, CreateRouteFails) { ProvideTestSink(mojom::MediaRouteProviderId::CAST, kSinkId); EXPECT_CALL(mock_cast_provider_, CreateRouteInternal(kSource, kSinkId, _, url::Origin::Create(GURL(kOrigin)), - kInvalidFrameNodeId, _, _, _)) - .WillOnce(WithArg<7>( + kInvalidFrameNodeId, _, _)) + .WillOnce(WithArg<6>( Invoke([](mojom::MediaRouteProvider::CreateRouteCallback& cb) { std::move(cb).Run(absl::nullopt, nullptr, std::string(kError), mojom::RouteRequestResultCode::TIMED_OUT); @@ -309,42 +274,12 @@ nullptr, base::BindOnce(&RouteResponseCallbackHandler::Invoke, base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), false); + base::Milliseconds(kTimeoutMillis)); run_loop.Run(); ExpectCastResultBucketCount("CreateRoute", mojom::RouteRequestResultCode::TIMED_OUT, 1); } -TEST_F(MediaRouterDesktopTest, CreateRouteIncognitoMismatchFails) { - ProvideTestSink(mojom::MediaRouteProviderId::CAST, kSinkId); - EXPECT_CALL(mock_cast_provider_, - CreateRouteInternal(kSource, kSinkId, _, - url::Origin::Create(GURL(kOrigin)), - kInvalidFrameNodeId, _, _, _)) - .WillOnce(WithArg<7>( - Invoke([](mojom::MediaRouteProvider::CreateRouteCallback& cb) { - std::move(cb).Run(CreateMediaRoute(), nullptr, std::string(), - mojom::RouteRequestResultCode::OK); - }))); - - RouteResponseCallbackHandler handler; - base::RunLoop run_loop; - std::string error( - "Mismatch in OffTheRecord status: request = 1, response = 0"); - EXPECT_CALL(handler, - DoInvoke(nullptr, "", error, - mojom::RouteRequestResultCode::ROUTE_NOT_FOUND, _)) - .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - router()->CreateRoute(kSource, kSinkId, url::Origin::Create(GURL(kOrigin)), - nullptr, - base::BindOnce(&RouteResponseCallbackHandler::Invoke, - base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), true); - run_loop.Run(); - ExpectCastResultBucketCount( - "CreateRoute", mojom::RouteRequestResultCode::ROUTE_NOT_FOUND, 1); -} - TEST_F(MediaRouterDesktopTest, JoinRoute) { TestJoinRoute(kPresentationId); ExpectCastResultBucketCount("JoinRoute", mojom::RouteRequestResultCode::OK, @@ -362,7 +297,7 @@ url::Origin::Create(GURL(kOrigin)), nullptr, base::BindOnce(&RouteResponseCallbackHandler::Invoke, base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), false); + base::Milliseconds(kTimeoutMillis)); run_loop.Run(); ExpectResultBucketCount("JoinRoute", mojom::RouteRequestResultCode::ROUTE_NOT_FOUND, 1); @@ -375,12 +310,11 @@ UpdateRoutes(mojom::MediaRouteProviderId::CAST, routes); EXPECT_TRUE(router()->HasJoinableRoute()); - EXPECT_CALL( - mock_cast_provider_, - JoinRouteInternal(kSource, kPresentationId, - url::Origin::Create(GURL(kOrigin)), kInvalidFrameNodeId, - base::Milliseconds(kTimeoutMillis), _, _)) - .WillOnce(WithArg<6>( + EXPECT_CALL(mock_cast_provider_, + JoinRouteInternal( + kSource, kPresentationId, url::Origin::Create(GURL(kOrigin)), + kInvalidFrameNodeId, base::Milliseconds(kTimeoutMillis), _)) + .WillOnce(WithArg<5>( Invoke([](mojom::MediaRouteProvider::JoinRouteCallback& cb) { std::move(cb).Run(absl::nullopt, nullptr, std::string(kError), mojom::RouteRequestResultCode::TIMED_OUT); @@ -395,53 +329,12 @@ url::Origin::Create(GURL(kOrigin)), nullptr, base::BindOnce(&RouteResponseCallbackHandler::Invoke, base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), false); + base::Milliseconds(kTimeoutMillis)); run_loop.Run(); ExpectCastResultBucketCount("JoinRoute", mojom::RouteRequestResultCode::TIMED_OUT, 1); } -TEST_F(MediaRouterDesktopTest, JoinRouteIncognitoMismatchFails) { - const MediaRoute route = CreateMediaRoute(); - - // Make sure the MR has received an update with the route, so it knows there - // is a route to join. - const std::vector<MediaRoute> routes{route}; - UpdateRoutes(mojom::MediaRouteProviderId::CAST, routes); - EXPECT_TRUE(router()->HasJoinableRoute()); - - // Use a lambda function as an invocation target here to work around - // a limitation with GMock::Invoke that prevents it from using move-only types - // in runnable parameter lists. - EXPECT_CALL( - mock_cast_provider_, - JoinRouteInternal(kSource, kPresentationId, - url::Origin::Create(GURL(kOrigin)), kInvalidFrameNodeId, - base::Milliseconds(kTimeoutMillis), _, _)) - .WillOnce(WithArg<6>( - Invoke([&route](mojom::MediaRouteProvider::JoinRouteCallback& cb) { - std::move(cb).Run(route, nullptr, std::string(), - mojom::RouteRequestResultCode::OK); - }))); - - RouteResponseCallbackHandler handler; - base::RunLoop run_loop; - std::string error( - "Mismatch in OffTheRecord status: request = 1, response = 0"); - EXPECT_CALL(handler, - DoInvoke(nullptr, "", error, - mojom::RouteRequestResultCode::ROUTE_NOT_FOUND, _)) - .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - router()->JoinRoute(kSource, kPresentationId, - url::Origin::Create(GURL(kOrigin)), nullptr, - base::BindOnce(&RouteResponseCallbackHandler::Invoke, - base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), true); - run_loop.Run(); - ExpectCastResultBucketCount( - "JoinRoute", mojom::RouteRequestResultCode::ROUTE_NOT_FOUND, 1); -} - TEST_F(MediaRouterDesktopTest, DetachRoute) { TestDetachRoute(); } @@ -656,11 +549,6 @@ std::vector<MediaRoute> expected_routes{ MediaRoute(kRouteId, media_source, kSinkId, kDescription, false)}; - MediaRoute incognito_expected_route(kRouteId2, media_source, kSinkId, - kDescription, false); - incognito_expected_route.set_off_the_record(true); - expected_routes.push_back(incognito_expected_route); - EXPECT_CALL(*routes_observer, OnRoutesUpdated(expected_routes)).Times(1); EXPECT_CALL(*extra_routes_observer, OnRoutesUpdated(expected_routes)) .Times(1); @@ -908,29 +796,29 @@ // A request to |kSinkId| should only be sent to |mock_cast_provider_|. EXPECT_CALL(mock_cast_provider_, - CreateRouteInternal(_, kSinkId, _, _, _, _, _, _)) - .WillOnce(WithArg<7>(Invoke( + CreateRouteInternal(_, kSinkId, _, _, _, _, _)) + .WillOnce(WithArg<6>(Invoke( &mock_cast_provider_, &MockMediaRouteProvider::RouteRequestSuccess))); EXPECT_CALL(mock_wired_display_provider_, - CreateRouteInternal(_, kSinkId, _, _, _, _, _, _)) + CreateRouteInternal(_, kSinkId, _, _, _, _, _)) .Times(0); router()->CreateRoute(kSource, kSinkId, url::Origin::Create(GURL(kOrigin)), nullptr, base::DoNothing(), - base::Milliseconds(kTimeoutMillis), true); + base::Milliseconds(kTimeoutMillis)); // A request to |kSinkId2| should only be sent to // |mock_wired_display_provider_|. EXPECT_CALL(mock_cast_provider_, - CreateRouteInternal(_, kSinkId2, _, _, _, _, _, _)) + CreateRouteInternal(_, kSinkId2, _, _, _, _, _)) .Times(0); EXPECT_CALL(mock_wired_display_provider_, - CreateRouteInternal(_, kSinkId2, _, _, _, _, _, _)) + CreateRouteInternal(_, kSinkId2, _, _, _, _, _)) .WillOnce( - WithArg<7>(Invoke(&mock_wired_display_provider_, + WithArg<6>(Invoke(&mock_wired_display_provider_, &MockMediaRouteProvider::RouteRequestSuccess))); router()->CreateRoute(kSource, kSinkId2, url::Origin::Create(GURL(kOrigin)), nullptr, base::DoNothing(), - base::Milliseconds(kTimeoutMillis), true); + base::Milliseconds(kTimeoutMillis)); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc index 318bbd27..aa26ac3 100644 --- a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc +++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
@@ -185,7 +185,7 @@ return *mock_local_manager_; } - void RunDefaultPresentationUrlCallbackTest(bool off_the_record) { + void RunDefaultPresentationUrlCallbackTest() { auto callback = base::BindRepeating( &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted, base::Unretained(this)); @@ -209,7 +209,6 @@ frame_origin_); MediaRoute media_route("differentRouteId", source2_, "mediaSinkId", "", true); - media_route.set_off_the_record(off_the_record); result = RouteRequestResult::FromSuccess(media_route, "differentPresentationId"); delegate_impl_->OnPresentationResponse(different_request, @@ -219,7 +218,6 @@ // Should trigger callback since request matches. EXPECT_CALL(*this, OnDefaultPresentationStarted(_)).Times(1); MediaRoute media_route2("routeId", source1_, "mediaSinkId", "", true); - media_route2.set_off_the_record(off_the_record); result = RouteRequestResult::FromSuccess(media_route2, "presentationId"); delegate_impl_->OnPresentationResponse(request, /** connection */ nullptr, *result); @@ -268,34 +266,6 @@ std::unique_ptr<content::PresentationRequest> presentation_request_; }; -class PresentationServiceDelegateImplIncognitoTest - : public PresentationServiceDelegateImplTest { - public: - PresentationServiceDelegateImplIncognitoTest() = default; - - protected: - content::WebContents* GetWebContents() override { - if (!off_the_record_web_contents_) { - Profile* incognito_profile = - profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true); - off_the_record_web_contents_ = - content::WebContentsTester::CreateTestWebContents(incognito_profile, - nullptr); - } - return off_the_record_web_contents_.get(); - } - - void TearDown() override { - // We must delete the OffTheRecord WC first, as that triggers observers - // which require RenderViewHost, etc., that in turn are deleted by - // RenderViewHostTestHarness::TearDown(). - off_the_record_web_contents_.reset(); - PresentationServiceDelegateImplTest::TearDown(); - } - - std::unique_ptr<content::WebContents> off_the_record_web_contents_{nullptr}; -}; - TEST_F(PresentationServiceDelegateImplTest, AddScreenAvailabilityListener) { EXPECT_CALL(*router_, RegisterMediaSinksObserver(_)).WillOnce(Return(true)); EXPECT_TRUE(delegate_impl_->AddScreenAvailabilityListener( @@ -392,12 +362,7 @@ } TEST_F(PresentationServiceDelegateImplTest, DefaultPresentationUrlCallback) { - RunDefaultPresentationUrlCallbackTest(false); -} - -TEST_F(PresentationServiceDelegateImplIncognitoTest, - DefaultPresentationUrlCallback) { - RunDefaultPresentationUrlCallbackTest(true); + RunDefaultPresentationUrlCallbackTest(); } TEST_F(PresentationServiceDelegateImplTest, NotifyDefaultPresentationChanged) { @@ -464,7 +429,7 @@ // Set up a PresentationConnection so we can listen to it. MediaRouteResponseCallback route_response_callback; - EXPECT_CALL(*router_, JoinRouteInternal(_, _, _, _, _, _, false)) + EXPECT_CALL(*router_, JoinRouteInternal(_, _, _, _, _, _)) .WillOnce(WithArgs<4>(Invoke( [&route_response_callback](MediaRouteResponseCallback& callback) { route_response_callback = std::move(callback); @@ -771,7 +736,7 @@ // A request to reconnect to a presentation with the special presentation ID // should succeed. ASSERT_TRUE(IsAutoJoinPresentationId(kPresentationId)); - EXPECT_CALL(*router_, JoinRouteInternal(_, kPresentationId, _, _, _, _, _)) + EXPECT_CALL(*router_, JoinRouteInternal(_, kPresentationId, _, _, _, _)) .Times(1); delegate_impl_->ReconnectPresentation( *presentation_request_, kPresentationId,
diff --git a/chrome/browser/media/router/providers/cast/app_activity.cc b/chrome/browser/media/router/providers/cast/app_activity.cc index eeff1c22..75e3852 100644 --- a/chrome/browser/media/router/providers/cast/app_activity.cc +++ b/chrome/browser/media/router/providers/cast/app_activity.cc
@@ -172,17 +172,13 @@ } } -bool AppActivity::CanJoinSession(const CastMediaSource& cast_source, - bool off_the_record) const { +bool AppActivity::CanJoinSession(const CastMediaSource& cast_source) const { if (!cast_source.ContainsApp(app_id())) return false; if (base::Contains(connected_clients_, cast_source.client_id())) return false; - if (route().is_off_the_record() != off_the_record) - return false; - return true; }
diff --git a/chrome/browser/media/router/providers/cast/app_activity.h b/chrome/browser/media/router/providers/cast/app_activity.h index 7795876..f00bcf3 100644 --- a/chrome/browser/media/router/providers/cast/app_activity.h +++ b/chrome/browser/media/router/providers/cast/app_activity.h
@@ -53,8 +53,7 @@ const CastInternalMessage& cast_message, cast_channel::ResultCallback callback) override; - bool CanJoinSession(const CastMediaSource& cast_source, - bool off_the_record) const; + bool CanJoinSession(const CastMediaSource& cast_source) const; bool HasJoinableClient(AutoJoinPolicy policy, const url::Origin& origin, int tab_id) const;
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc index 1ba5e93..48f50c9 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -104,12 +104,11 @@ const std::string& presentation_id, const url::Origin& origin, int frame_tree_node_id, - bool off_the_record, mojom::MediaRouteProvider::CreateRouteCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (cast_source.app_params().empty()) { LaunchSessionParsed(cast_source, sink, presentation_id, origin, - frame_tree_node_id, off_the_record, std::move(callback), + frame_tree_node_id, std::move(callback), data_decoder::DataDecoder::ValueOrError()); } else { GetDataDecoder().ParseJson( @@ -117,7 +116,7 @@ base::BindOnce(&CastActivityManager::LaunchSessionParsed, weak_ptr_factory_.GetWeakPtr(), cast_source, sink, presentation_id, origin, frame_tree_node_id, - off_the_record, std::move(callback))); + std::move(callback))); } } @@ -127,7 +126,6 @@ const std::string& presentation_id, const url::Origin& origin, int frame_tree_node_id, - bool off_the_record, mojom::MediaRouteProvider::CreateRouteCallback callback, data_decoder::DataDecoder::ValueOrError result) { if (!cast_source.app_params().empty() && !result.has_value()) { @@ -151,7 +149,6 @@ /* is_local */ true); route.set_presentation_id(presentation_id); route.set_local_presentation(true); - route.set_off_the_record(off_the_record); if (cast_source.ContainsStreamingApp()) { route.set_controller_type(RouteControllerType::kMirroring); } else { @@ -309,7 +306,6 @@ const std::string& presentation_id, const url::Origin& origin, int frame_tree_node_id, - bool off_the_record, mojom::MediaRouteProvider::JoinRouteCallback callback) { AppActivity* activity = nullptr; if (presentation_id == kAutoJoinPresentationId) { @@ -319,7 +315,7 @@ auto sink = GetSinkForMirroringActivity(frame_tree_node_id); if (sink) { LaunchSession(cast_source, *sink, presentation_id, origin, - frame_tree_node_id, off_the_record, std::move(callback)); + frame_tree_node_id, std::move(callback)); return; } } @@ -327,7 +323,7 @@ activity = FindActivityForSessionJoin(cast_source, presentation_id); } - if (!activity || !activity->CanJoinSession(cast_source, off_the_record)) { + if (!activity || !activity->CanJoinSession(cast_source)) { std::move(callback).Run(absl::nullopt, nullptr, std::string("No matching route"), mojom::RouteRequestResultCode::ROUTE_NOT_FOUND);
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.h b/chrome/browser/media/router/providers/cast/cast_activity_manager.h index 7af820f..35d1d4a 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager.h +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.h
@@ -81,14 +81,12 @@ const std::string& presentation_id, const url::Origin& origin, int frame_tree_node_id, - bool incognito, mojom::MediaRouteProvider::CreateRouteCallback callback); void JoinSession(const CastMediaSource& cast_source, const std::string& presentation_id, const url::Origin& origin, int frame_tree_node_id, - bool incognito, mojom::MediaRouteProvider::JoinRouteCallback callback); // Terminates a Cast session represented by |route_id|. @@ -168,7 +166,6 @@ const std::string& presentation_id, const url::Origin& origin, int frame_tree_node_id, - bool incognito, mojom::MediaRouteProvider::CreateRouteCallback callback, data_decoder::DataDecoder::ValueOrError result); @@ -266,8 +263,7 @@ const url::Origin& origin, int frame_tree_node_id); bool CanJoinSession(const AppActivity& activity, - const CastMediaSource& cast_source, - bool incognito) const; + const CastMediaSource& cast_source) const; AppActivity* FindActivityForSessionJoin(const CastMediaSource& cast_source, const std::string& presentation_id);
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc index f6c7da7e..b38de36 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc
@@ -251,8 +251,7 @@ // Callback needs to be invoked by running |launch_session_callback_|. manager_->LaunchSession(*source, sink_, kPresentationId, origin_, - kFrameTreeNodeId, - /*incognito*/ false, std::move(callback)); + kFrameTreeNodeId, std::move(callback)); RunUntilIdle(); } @@ -697,7 +696,6 @@ // Callback will be invoked synchronously. manager_->LaunchSession( *source, sink_, kPresentationId, origin_, kFrameTreeNodeId, - /*incognito*/ false, base::BindOnce(&CastActivityManagerTest::ExpectLaunchSessionFailure, base::Unretained(this))); @@ -713,9 +711,7 @@ // Use LaunchSessionParsed() instead of LaunchSession() here because // LaunchSessionParsed() is called asynchronously and will fail the test. manager_->LaunchSessionParsed( - *source, sink2_, kPresentationId2, origin_, - kFrameTreeNodeId, /*incognito*/ - false, + *source, sink2_, kPresentationId2, origin_, kFrameTreeNodeId, base::BindOnce(&CastActivityManagerTest::ExpectLaunchSessionSuccess, base::Unretained(this)), data_decoder::DataDecoder::ValueOrError()); @@ -731,9 +727,7 @@ // Use LaunchSessionParsed() instead of LaunchSession() here because // LaunchSessionParsed() is called asynchronously and will fail the test. manager_->LaunchSessionParsed( - *source, sink2_, kPresentationId2, origin_, - kFrameTreeNodeId, /*incognito*/ - false, + *source, sink2_, kPresentationId2, origin_, kFrameTreeNodeId, base::BindOnce(&CastActivityManagerTest::ExpectLaunchSessionSuccess, base::Unretained(this)), data_decoder::DataDecoder::ValueOrError()); @@ -877,9 +871,7 @@ auto source2 = CastMediaSource::FromMediaSourceId(MakeSourceId(cast_streaming_app_id_)); manager_->LaunchSession( - *source2, sink2_, kPresentationId2, origin_, - kFrameTreeNodeId2, /*incognito*/ - false, + *source2, sink2_, kPresentationId2, origin_, kFrameTreeNodeId2, base::BindOnce(&CastActivityManagerTest::ExpectLaunchSessionSuccess, base::Unretained(this))); @@ -904,7 +896,6 @@ auto source = CastMediaSource::FromMediaSourceId(MakeSourceId(kAppId2)); manager_->LaunchSessionParsed( *source, sink_, kPresentationId2, origin_, kFrameTreeNodeId2, - /*incognito*/ false, base::BindOnce(&CastActivityManagerTest::ExpectLaunchSessionSuccess, base::Unretained(this)), data_decoder::DataDecoder::ValueOrError()); @@ -953,9 +944,7 @@ // LaunchSessionParsed() is called asynchronously and will fail the test. manager_->LaunchSessionParsed( // TODO(crbug.com/1291744): Verify that presentation ID is used correctly. - *source, sink_, kPresentationId2, origin_, - kFrameTreeNodeId2, /*incognito*/ - false, + *source, sink_, kPresentationId2, origin_, kFrameTreeNodeId2, base::BindOnce(&CastActivityManagerTest::ExpectLaunchSessionSuccess, base::Unretained(this)), data_decoder::DataDecoder::ValueOrError()); @@ -993,7 +982,6 @@ for (int i = 0; i < 2; i++) { manager_->LaunchSession(*source, sink_, kPresentationId, origin_, kFrameTreeNodeId, - /*incognito*/ false, base::BindOnce(&MockLaunchSessionCallback::Run, base::Unretained(&callback))); }
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc index 49464149..31fbe05 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
@@ -173,7 +173,6 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, CreateRouteCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -202,8 +201,7 @@ return; } activity_manager_->LaunchSession(*cast_source, *sink, presentation_id, origin, - frame_tree_node_id, incognito, - std::move(callback)); + frame_tree_node_id, std::move(callback)); } void CastMediaRouteProvider::JoinRoute(const std::string& media_source, @@ -211,7 +209,6 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback callback) { std::unique_ptr<CastMediaSource> cast_source = CastMediaSource::FromMediaSourceId(media_source); @@ -241,8 +238,7 @@ return; } activity_manager_->JoinSession(*cast_source, presentation_id, origin, - frame_tree_node_id, incognito, - std::move(callback)); + frame_tree_node_id, std::move(callback)); } void CastMediaRouteProvider::TerminateRoute(const std::string& route_id,
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h index c00596d..72cbdc78 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h
@@ -61,14 +61,12 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, CreateRouteCallback callback) override; void JoinRoute(const std::string& media_source, const std::string& presentation_id, const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback callback) override; void TerminateRoute(const std::string& route_id, TerminateRouteCallback callback) override;
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc index 06db49c3..692a3f9 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
@@ -192,7 +192,6 @@ provider_->CreateRoute( kCastSource, "sinkId", kPresentationId, origin_, kFrameTreeNodeId, kRouteTimeout, - /* incognito */ false, base::BindOnce(&CastMediaRouteProviderTest::ExpectCreateRouteFailure, base::Unretained(this), mojom::RouteRequestResultCode::SINK_NOT_FOUND)); @@ -204,7 +203,7 @@ provider_->CreateRoute( "invalidSource", sink.sink().id(), kPresentationId, origin_, - kFrameTreeNodeId, kRouteTimeout, /* incognito */ false, + kFrameTreeNodeId, kRouteTimeout, base::BindOnce(&CastMediaRouteProviderTest::ExpectCreateRouteFailure, base::Unretained(this), mojom::RouteRequestResultCode::NO_SUPPORTED_PROVIDER)); @@ -226,7 +225,7 @@ })); provider_->CreateRoute( kCastSource, sink.sink().id(), kPresentationId, origin_, kFrameTreeNodeId, - kRouteTimeout, /* incognito */ false, + kRouteTimeout, base::BindOnce( &CastMediaRouteProviderTest::ExpectCreateRouteSuccessAndSetRoute, base::Unretained(this))); @@ -247,7 +246,7 @@ })); provider_->CreateRoute( kCastSource, sink.sink().id(), kPresentationId, origin_, kFrameTreeNodeId, - kRouteTimeout, /* incognito */ false, + kRouteTimeout, base::BindOnce( &CastMediaRouteProviderTest::ExpectCreateRouteSuccessAndSetRoute, base::Unretained(this)));
diff --git a/chrome/browser/media/router/providers/dial/dial_activity_manager.cc b/chrome/browser/media/router/providers/dial/dial_activity_manager.cc index d4b757b..7eb6ee8 100644 --- a/chrome/browser/media/router/providers/dial/dial_activity_manager.cc +++ b/chrome/browser/media/router/providers/dial/dial_activity_manager.cc
@@ -72,8 +72,7 @@ const std::string& presentation_id, const MediaSinkInternal& sink, const MediaSource::Id& source_id, - const url::Origin& client_origin, - bool off_the_record) { + const url::Origin& client_origin) { MediaSource source(source_id); GURL url = source.url(); if (!url.is_valid()) @@ -109,7 +108,6 @@ sink_id, app_name, /* is_local */ true); route.set_presentation_id(presentation_id); - route.set_off_the_record(off_the_record); return std::make_unique<DialActivity>(launch_info, route, sink, client_origin); } @@ -164,18 +162,15 @@ const DialActivity* DialActivityManager::GetActivityToJoin( const std::string& presentation_id, const MediaSource& media_source, - const url::Origin& client_origin, - bool off_the_record) const { + const url::Origin& client_origin) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto record_it = base::ranges::find_if( - records_, [&presentation_id, &media_source, &client_origin, - off_the_record](const auto& record) { + records_, + [&presentation_id, &media_source, &client_origin](const auto& record) { const auto& route = record.second->activity.route; const url::Origin& origin = record.second->activity.client_origin; return route.presentation_id() == presentation_id && - route.media_source() == media_source && - origin == client_origin && - route.is_off_the_record() == off_the_record; + route.media_source() == media_source && origin == client_origin; }); return record_it != records_.end() ? &(record_it->second->activity) : nullptr; }
diff --git a/chrome/browser/media/router/providers/dial/dial_activity_manager.h b/chrome/browser/media/router/providers/dial/dial_activity_manager.h index 1bf628b5..5b05b46 100644 --- a/chrome/browser/media/router/providers/dial/dial_activity_manager.h +++ b/chrome/browser/media/router/providers/dial/dial_activity_manager.h
@@ -56,8 +56,7 @@ static std::unique_ptr<DialActivity> From(const std::string& presentation_id, const MediaSinkInternal& sink, const MediaSource::Id& source_id, - const url::Origin& client_origin, - bool off_the_record); + const url::Origin& client_origin); DialActivity(const DialLaunchInfo& launch_info, const MediaRoute& route, @@ -132,8 +131,7 @@ // properties, or a nullptr if there is no such activity. const DialActivity* GetActivityToJoin(const std::string& presentation_id, const MediaSource& media_source, - const url::Origin& client_origin, - bool off_the_record) const; + const url::Origin& client_origin) const; // Launches the app specified in the activity associated with |route_id|. // If |message.launch_parameter| is set, then it overrides the post data
diff --git a/chrome/browser/media/router/providers/dial/dial_activity_manager_unittest.cc b/chrome/browser/media/router/providers/dial/dial_activity_manager_unittest.cc index 64c5028..3611f6ad 100644 --- a/chrome/browser/media/router/providers/dial/dial_activity_manager_unittest.cc +++ b/chrome/browser/media/router/providers/dial/dial_activity_manager_unittest.cc
@@ -30,8 +30,7 @@ "cast-dial:YouTube?clientId=152127444812943594&dialPostData=foo"; url::Origin origin = url::Origin::Create(GURL("https://www.youtube.com/")); - auto activity = DialActivity::From(presentation_id, sink, source_id, origin, - /*off_the_record*/ true); + auto activity = DialActivity::From(presentation_id, sink, source_id, origin); ASSERT_TRUE(activity); GURL expected_app_launch_url(sink.dial_data().app_url.spec() + "/YouTube"); @@ -47,7 +46,6 @@ EXPECT_EQ(sink.sink().id(), route.media_sink_id()); EXPECT_EQ("YouTube", route.description()); EXPECT_TRUE(route.is_local()); - EXPECT_TRUE(route.is_off_the_record()); EXPECT_FALSE(route.is_local_presentation()); EXPECT_EQ(RouteControllerType::kNone, route.controller_type()); } @@ -117,8 +115,7 @@ std::unique_ptr<DialActivity> FailToStopApp() { auto activity = - DialActivity::From(presentation_id_, sink_, source_id_, origin_, - /*off_the_record*/ false); + DialActivity::From(presentation_id_, sink_, source_id_, origin_); CHECK(activity); manager_.AddActivity(*activity); @@ -152,8 +149,7 @@ TEST_F(DialActivityManagerTest, AddActivity) { auto activity = - DialActivity::From(presentation_id_, sink_, source_id_, origin_, - /*off_the_record*/ false); + DialActivity::From(presentation_id_, sink_, source_id_, origin_); ASSERT_TRUE(activity); EXPECT_TRUE(manager_.GetRoutes().empty()); @@ -166,34 +162,28 @@ } TEST_F(DialActivityManagerTest, GetActivityBySinkId) { - auto activity = DialActivity::From(presentation_id_, sink_, source_id_, - origin_, /*off_the_record*/ false); + auto activity = + DialActivity::From(presentation_id_, sink_, source_id_, origin_); manager_.AddActivity(*activity); EXPECT_TRUE(manager_.GetActivityBySinkId(sink_.id())); EXPECT_FALSE(manager_.GetActivityBySinkId("wrong-sink-id")); } TEST_F(DialActivityManagerTest, GetActivityToJoin) { - const bool off_the_record = false; - auto activity = DialActivity::From(presentation_id_, sink_, source_id_, - origin_, off_the_record); + auto activity = + DialActivity::From(presentation_id_, sink_, source_id_, origin_); manager_.AddActivity(*activity); - EXPECT_TRUE(manager_.GetActivityToJoin( - presentation_id_, MediaSource(source_id_), origin_, off_the_record)); - EXPECT_FALSE(manager_.GetActivityToJoin(presentation_id_, - MediaSource("wrong-source-id"), - origin_, off_the_record)); - EXPECT_FALSE(manager_.GetActivityToJoin("wrong-presentation-id", - MediaSource(source_id_), origin_, - off_the_record)); + EXPECT_TRUE(manager_.GetActivityToJoin(presentation_id_, + MediaSource(source_id_), origin_)); EXPECT_FALSE(manager_.GetActivityToJoin( - presentation_id_, MediaSource(source_id_), origin_, !off_the_record)); + presentation_id_, MediaSource("wrong-source-id"), origin_)); + EXPECT_FALSE(manager_.GetActivityToJoin("wrong-presentation-id", + MediaSource(source_id_), origin_)); } TEST_F(DialActivityManagerTest, LaunchApp) { auto activity = - DialActivity::From(presentation_id_, sink_, source_id_, origin_, - /*off_the_record*/ false); + DialActivity::From(presentation_id_, sink_, source_id_, origin_); ASSERT_TRUE(activity); manager_.AddActivity(*activity); @@ -204,8 +194,7 @@ TEST_F(DialActivityManagerTest, LaunchAppLaunchParameter) { auto activity = - DialActivity::From(presentation_id_, sink_, source_id_, origin_, - /*off_the_record*/ false); + DialActivity::From(presentation_id_, sink_, source_id_, origin_); ASSERT_TRUE(activity); manager_.AddActivity(*activity); @@ -216,8 +205,7 @@ TEST_F(DialActivityManagerTest, LaunchAppFails) { auto activity = - DialActivity::From(presentation_id_, sink_, source_id_, origin_, - /*off_the_record*/ false); + DialActivity::From(presentation_id_, sink_, source_id_, origin_); ASSERT_TRUE(activity); manager_.AddActivity(*activity); @@ -239,8 +227,7 @@ TEST_F(DialActivityManagerTest, StopApp) { auto activity = - DialActivity::From(presentation_id_, sink_, source_id_, origin_, - /*off_the_record*/ false); + DialActivity::From(presentation_id_, sink_, source_id_, origin_); ASSERT_TRUE(activity); manager_.AddActivity(*activity); @@ -270,8 +257,7 @@ TEST_F(DialActivityManagerTest, StopAppUseFallbackURL) { auto activity = - DialActivity::From(presentation_id_, sink_, source_id_, origin_, - /*off_the_record*/ false); + DialActivity::From(presentation_id_, sink_, source_id_, origin_); ASSERT_TRUE(activity); manager_.AddActivity(*activity);
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc index 08e217d..08cf7082 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc
@@ -81,9 +81,7 @@ const std::string& presentation_id, const url::Origin& origin, int32_t frame_tree_node_id, - base::TimeDelta timeout, - bool incognito, CreateRouteCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const MediaSinkInternal* sink = media_sink_service_->GetSinkById(sink_id); @@ -99,8 +97,8 @@ return; } - auto activity = DialActivity::From(presentation_id, *sink, media_source, - origin, incognito); + auto activity = + DialActivity::From(presentation_id, *sink, media_source, origin); if (!activity) { logger_->LogError(mojom::LogCategory::kRoute, kLoggerComponent, "Failed to create route. Unsupported source.", sink_id, @@ -162,10 +160,9 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback callback) { const DialActivity* activity = activity_manager_->GetActivityToJoin( - presentation_id, MediaSource(media_source), origin, incognito); + presentation_id, MediaSource(media_source), origin); if (activity) { std::move(callback).Run( activity->route, /*presentation_connection*/ nullptr,
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h index 79e4d3e..1508599 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
@@ -75,14 +75,12 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, CreateRouteCallback callback) override; void JoinRoute(const std::string& media_source, const std::string& presentation_id, const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback callback) override; void TerminateRoute(const std::string& route_id, TerminateRouteCallback callback) override;
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc index 7bb70273..4990421 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc
@@ -156,7 +156,6 @@ provider_->CreateRoute( source_id, sink_id, presentation_id, origin_, kFrameTreeNodeId, base::TimeDelta(), - /* off_the_record */ false, base::BindOnce(&DialMediaRouteProviderTest::ExpectRouteResult, base::Unretained(this), mojom::RouteRequestResultCode::OK)); @@ -168,7 +167,6 @@ CreateRoute(presentation_id); ASSERT_TRUE(route_); EXPECT_EQ(presentation_id, route_->presentation_id()); - EXPECT_FALSE(route_->is_off_the_record()); const MediaRoute::Id& route_id = route_->media_route_id(); std::vector<RouteMessagePtr> received_messages; @@ -193,8 +191,7 @@ mojom::RouteRequestResultCode expected_result, absl::optional<std::string> source_to_join = absl::nullopt, absl::optional<std::string> presentation_to_join = absl::nullopt, - absl::optional<url::Origin> client_origin = absl::nullopt, - absl::optional<bool> client_incognito = absl::nullopt) { + absl::optional<url::Origin> client_origin = absl::nullopt) { CreateRoute(); ASSERT_TRUE(route_); @@ -204,12 +201,8 @@ ? *presentation_to_join : route_->presentation_id(); const url::Origin& origin = client_origin ? *client_origin : origin_; - const bool incognito = - client_incognito ? *client_incognito : route_->is_off_the_record(); - provider_->JoinRoute( source, presentation, origin, kFrameTreeNodeId, base::TimeDelta(), - incognito, base::BindOnce(&DialMediaRouteProviderTest::ExpectRouteResult, base::Unretained(this), expected_result)); } @@ -649,11 +642,6 @@ url::Origin::Create(GURL("https://wrong-origin.com"))); } -TEST_F(DialMediaRouteProviderTest, JoinRouteFailsForIncognitoMismatch) { - TestJoinRoute(mojom::RouteRequestResultCode::ROUTE_NOT_FOUND, absl::nullopt, - absl::nullopt, absl::nullopt, true); -} - TEST_F(DialMediaRouteProviderTest, TerminateRoute) { TestCreateRoute(); TestSendClientConnectMessage(); @@ -708,7 +696,6 @@ provider_->CreateRoute( source_id, sink_id, presentation_id_2, origin_, kFrameTreeNodeId, base::TimeDelta(), - /* off_the_record */ false, base::BindOnce(&DialMediaRouteProviderTest::ExpectRouteResult, base::Unretained(this), mojom::RouteRequestResultCode::OK));
diff --git a/chrome/browser/media/router/providers/test/test_media_route_provider.cc b/chrome/browser/media/router/providers/test/test_media_route_provider.cc index 20701a7..6dd9ce0 100644 --- a/chrome/browser/media/router/providers/test/test_media_route_provider.cc +++ b/chrome/browser/media/router/providers/test/test_media_route_provider.cc
@@ -74,7 +74,6 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, CreateRouteCallback callback) { if (!route_error_message_.empty()) { std::move(callback).Run(absl::nullopt, nullptr, route_error_message_, @@ -92,7 +91,6 @@ std::string("Test Route"), true); route.set_presentation_id(presentation_id); route.set_controller_type(RouteControllerType::kGeneric); - route.set_off_the_record(incognito); if (Is1UAPresentationSource(media_source)) { route.set_local_presentation(true); } @@ -118,7 +116,6 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback callback) { if (!route_error_message_.empty()) { std::move(callback).Run(absl::nullopt, nullptr, route_error_message_, @@ -136,10 +133,6 @@ std::move(callback).Run(absl::nullopt, nullptr, std::string("Presentation does not exist."), mojom::RouteRequestResultCode::UNKNOWN_ERROR); - } else if (pos->second.is_off_the_record() != incognito) { - std::move(callback).Run(absl::nullopt, nullptr, - std::string("Off-the-record mismatch."), - mojom::RouteRequestResultCode::UNKNOWN_ERROR); } else { MediaRoute& existing_route = pos->second; std::move(callback).Run(existing_route, nullptr,
diff --git a/chrome/browser/media/router/providers/test/test_media_route_provider.h b/chrome/browser/media/router/providers/test/test_media_route_provider.h index 2df3a3a..fee1f81 100644 --- a/chrome/browser/media/router/providers/test/test_media_route_provider.h +++ b/chrome/browser/media/router/providers/test/test_media_route_provider.h
@@ -38,14 +38,12 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, CreateRouteCallback callback) override; void JoinRoute(const std::string& media_source, const std::string& presentation_id, const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback callback) override; void TerminateRoute(const std::string& route_id, TerminateRouteCallback callback) override;
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc index d54b96d..016a873 100644 --- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc +++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
@@ -99,7 +99,6 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool off_the_record, CreateRouteCallback callback) { DCHECK(!base::Contains(presentations_, presentation_id)); absl::optional<Display> display = GetDisplayBySinkId(sink_id); @@ -117,7 +116,6 @@ MediaRoute route(presentation_id, MediaSource(media_source), sink_id, GetRouteDescription(media_source), true); route.set_local_presentation(true); - route.set_off_the_record(profile_->IsOffTheRecord()); route.set_controller_type(RouteControllerType::kGeneric); Presentation& presentation = @@ -136,7 +134,6 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool off_the_record, JoinRouteCallback callback) { std::move(callback).Run( absl::nullopt, nullptr,
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h index 32ab7da..bb6fa8d 100644 --- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h +++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
@@ -63,14 +63,12 @@ const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool off_the_record, CreateRouteCallback callback) override; void JoinRoute(const std::string& media_source, const std::string& presentation_id, const url::Origin& origin, int32_t frame_tree_node_id, base::TimeDelta timeout, - bool off_the_record, JoinRouteCallback callback) override; void TerminateRoute(const std::string& route_id, TerminateRouteCallback callback) override;
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc index 92b02f7..629eaa6 100644 --- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
@@ -334,7 +334,7 @@ provider_remote_->CreateRoute( kPresentationSource, GetSinkId(secondary_display1_), presentation_id, url::Origin::Create(GURL(kPresentationSource)), kFrameTreeNodeId, - base::Seconds(100), false, + base::Seconds(100), base::BindOnce(&MockCallback::CreateRoute, base::Unretained(&callback))); base::RunLoop().RunUntilIdle(); @@ -370,7 +370,7 @@ provider_remote_->CreateRoute( kPresentationSource, GetSinkId(secondary_display1_), presentation_id, url::Origin::Create(GURL(kPresentationSource)), kFrameTreeNodeId, - base::Seconds(100), false, + base::Seconds(100), base::BindOnce(&MockCallback::CreateRoute, base::Unretained(&callback))); base::RunLoop().RunUntilIdle(); @@ -399,7 +399,7 @@ provider_remote_->CreateRoute( kPresentationSource, GetSinkId(secondary_display1_), "presentationId", url::Origin::Create(GURL(kPresentationSource)), kFrameTreeNodeId, - base::Seconds(100), false, + base::Seconds(100), base::BindOnce(&MockCallback::CreateRoute, base::Unretained(&callback))); base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.cc b/chrome/browser/media/router/test/media_router_mojo_test.cc index 7ffa401..df74e2c 100644 --- a/chrome/browser/media/router/test/media_router_mojo_test.cc +++ b/chrome/browser/media/router/test/media_router_mojo_test.cc
@@ -179,8 +179,8 @@ EXPECT_CALL(mock_cast_provider_, CreateRouteInternal(kSource, kSinkId, _, url::Origin::Create(GURL(kOrigin)), - kInvalidFrameTreeNodeId, _, _, _)) - .WillOnce(WithArg<7>( + kInvalidFrameTreeNodeId, _, _)) + .WillOnce(WithArg<6>( Invoke([](mojom::MediaRouteProvider::CreateRouteCallback& cb) { std::move(cb).Run(CreateMediaRoute(), nullptr, std::string(), mojom::RouteRequestResultCode::OK); @@ -193,7 +193,7 @@ nullptr, base::BindOnce(&RouteResponseCallbackHandler::Invoke, base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), false); + base::Milliseconds(kTimeoutMillis)); base::RunLoop().RunUntilIdle(); } @@ -219,8 +219,8 @@ JoinRouteInternal(kSource, presentation_id, url::Origin::Create(GURL(kOrigin)), kInvalidFrameTreeNodeId, - base::Milliseconds(kTimeoutMillis), _, _)) - .WillOnce(WithArg<6>( + base::Milliseconds(kTimeoutMillis), _)) + .WillOnce(WithArg<5>( Invoke([&route](mojom::MediaRouteProvider::JoinRouteCallback& cb) { std::move(cb).Run(route, nullptr, std::string(), mojom::RouteRequestResultCode::OK); @@ -233,7 +233,7 @@ url::Origin::Create(GURL(kOrigin)), nullptr, base::BindOnce(&RouteResponseCallbackHandler::Invoke, base::Unretained(&handler)), - base::Milliseconds(kTimeoutMillis), false); + base::Milliseconds(kTimeoutMillis)); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.h b/chrome/browser/media/router/test/media_router_mojo_test.h index 0835edd4..4482bbc4 100644 --- a/chrome/browser/media/router/test/media_router_mojo_test.h +++ b/chrome/browser/media/router/test/media_router_mojo_test.h
@@ -48,10 +48,9 @@ const url::Origin& origin, int frame_tree_node_id, base::TimeDelta timeout, - bool incognito, CreateRouteCallback callback) override { CreateRouteInternal(source_urn, sink_id, presentation_id, origin, - frame_tree_node_id, timeout, incognito, callback); + frame_tree_node_id, timeout, callback); } MOCK_METHOD(void, CreateRouteInternal, @@ -61,17 +60,15 @@ const url::Origin& origin, int frame_tree_node_id, base::TimeDelta timeout, - bool incognito, CreateRouteCallback& callback)); void JoinRoute(const std::string& source_urn, const std::string& presentation_id, const url::Origin& origin, int frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback callback) override { JoinRouteInternal(source_urn, presentation_id, origin, frame_tree_node_id, - timeout, incognito, callback); + timeout, callback); } MOCK_METHOD(void, JoinRouteInternal, @@ -80,7 +77,6 @@ const url::Origin& origin, int frame_tree_node_id, base::TimeDelta timeout, - bool incognito, JoinRouteCallback& callback)); MOCK_METHOD(void, DetachRoute, (const std::string& route_id)); void TerminateRoute(const std::string& route_id,
diff --git a/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm b/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm index 7e54df5f..016caca 100644 --- a/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm +++ b/chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
@@ -8,12 +8,17 @@ #import <ScreenCaptureKit/ScreenCaptureKit.h> #include <VideoToolbox/VideoToolbox.h> +#include <cmath> +#include <deque> + #include "base/apple/bridging.h" #include "base/apple/foundation_util.h" #include "base/apple/scoped_cftyperef.h" +#include "base/containers/adapters.h" #include "base/containers/contains.h" #include "base/containers/flat_map.h" #include "base/feature_list.h" +#include "base/functional/callback.h" #include "base/logging.h" #include "base/memory/raw_ptr.h" #include "base/metrics/field_trial_params.h" @@ -157,6 +162,31 @@ "refresh_timer_interval", base::Milliseconds(250)}; +// The capture mode controls how the thumbnails are captured. +enum class CaptureMode { + // Create an SCStream for each selected source. In this mode frames are pushed + // by the OS at the specified maximum frame rate. + kSCStream = 0, + // Use SCScreenshotManager to capture frames. In this mode a timer is used to + // periodically capture the selected windows in a pull-based fashion. Please + // note that this mode is only available in macOS 14.0 and later. + kSCScreenshotManager = 1 +}; +const base::FeatureParam<CaptureMode>::Option capture_mode_options[] = { + {CaptureMode::kSCStream, "sc_stream"}, + {CaptureMode::kSCScreenshotManager, "sc_screenshot_manager"}, +}; +const base::FeatureParam<CaptureMode> kThumbnailCapturerMacCaptureMode{ + &kThumbnailCapturerMac, "capture_mode", CaptureMode::kSCStream, + &capture_mode_options}; + +CaptureMode GetCaptureModeFeatureParam() { + if (@available(macOS 14.0, *)) { + return kThumbnailCapturerMacCaptureMode.Get(); + } + return CaptureMode::kSCStream; +} + // The sort mode controls the order of the source list that is returned from // GetSourceList(). enum class SortMode { @@ -181,6 +211,12 @@ const base::FeatureParam<int> kThumbnailCapturerMacMinWindowSize{ &kThumbnailCapturerMac, "min_window_size", 40}; +// Controls the maximum number of sources that are captured during each capture +// cycle if the capture mode is set to kSCScreenshotManager. By having a limit +// and cycling through what windows are captured we get a graceful degradation. +const base::FeatureParam<int> kThumbnailCapturerMacMaxSourcesPerCycles{ + &kThumbnailCapturerMac, "max_sources_per_cycles", 25}; + bool API_AVAILABLE(macos(12.3)) IsWindowFullscreen(SCWindow* window, NSArray<SCDisplay*>* displays) { for (SCDisplay* display : displays) { @@ -220,6 +256,168 @@ return window_id; } +class API_AVAILABLE(macos(12.3)) ScreenshotManagerCapturer { + public: + using GetShareableWindowCallback = + base::RepeatingCallback<SCWindow*(ThumbnailCapturer::SourceId source_id)>; + + ScreenshotManagerCapturer( + int max_frame_rate, + GetShareableWindowCallback get_shareable_window_callback, + SampleCallback sample_callback); + void SelectSources(const std::vector<ThumbnailCapturer::SourceId>& ids, + gfx::Size thumbnail_size); + + private: + void API_AVAILABLE(macos(14.0)) OnRecurrentCaptureTimer(); + void API_AVAILABLE(macos(14.0)) SCScreenshotCaptureWindow(SCWindow* window); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + // Callback to retrieve an SCWindow* based on windowID. + GetShareableWindowCallback get_shareable_window_callback_; + + // Callback that is used whenever a thumbnail is captured. + SampleCallback sample_callback_; + + // The maximum number of sources that can be captured in each capture cycle. + // We have a limit here to not spawn hundreds of capturers at the same time + // since this could degrade the system performance. + const size_t max_sources_per_cycle_; + + // The selected sources, this is used to determine if a selected source was + // not selected before and give priority to the source in this case. + std::vector<ThumbnailCapturer::SourceId> selected_sources_; + + // The capture queue is used to maintain a list of all selected sources and + // keep track of what source should be captured next in the case that too many + // sources are selected and we cannot capture all sources in each capture + // cycle. + std::deque<ThumbnailCapturer::SourceId> capture_queue_; + + gfx::Size thumbnail_size_ = kDefaultThumbnailSize; + + base::RepeatingTimer capture_frame_timer_; +}; + +ScreenshotManagerCapturer::ScreenshotManagerCapturer( + int max_frame_rate, + GetShareableWindowCallback get_shareable_window_callback, + SampleCallback sample_callback) + : task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()), + get_shareable_window_callback_(get_shareable_window_callback), + sample_callback_(sample_callback), + max_sources_per_cycle_(kThumbnailCapturerMacMaxSourcesPerCycles.Get()) { + if (@available(macOS 14.0, *)) { + capture_frame_timer_.Start( + FROM_HERE, base::Milliseconds(1000.0 / max_frame_rate), this, + &ScreenshotManagerCapturer::OnRecurrentCaptureTimer); + } +} + +void ScreenshotManagerCapturer::SelectSources( + const std::vector<ThumbnailCapturer::SourceId>& ids, + gfx::Size thumbnail_size) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + // The iteration is in reverse order so that the sources + // first in the list are captured first. This way we make sure that the first + // thumbnails in the view are captured first. + bool new_sources_added = false; + for (ThumbnailCapturer::SourceId source_id : base::Reversed(ids)) { + if (!base::Contains(selected_sources_, source_id)) { + capture_queue_.push_front(source_id); + new_sources_added = true; + } + } + + selected_sources_ = ids; + if (new_sources_added) { + // Run the capture code immediately to avoid a short period with empty + // thumbnails at the top of the list. This is especially useful in the first + // call to SelectSources(). + if (@available(macOS 14.0, *)) { + OnRecurrentCaptureTimer(); + capture_frame_timer_.Reset(); + } + } +} + +void ScreenshotManagerCapturer::OnRecurrentCaptureTimer() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + if (capture_queue_.empty()) { + return; + } + + // Take source ids from the top of the queue and capture the corresponding + // window if it is still selected and exists in the list of shareable windows. + // Finally put the source at the back of the queue to be captured again later. + size_t sources_to_capture = + std::min(capture_queue_.size(), max_sources_per_cycle_); + for (size_t i = 0; i < sources_to_capture; ++i) { + ThumbnailCapturer::SourceId source_id = capture_queue_.front(); + capture_queue_.pop_front(); + if (!base::Contains(selected_sources_, source_id)) { + continue; + } + + // Find the corresponding SCWindow in the list. + SCWindow* selected_window = get_shareable_window_callback_.Run(source_id); + if (!selected_window) { + continue; + } + + SCScreenshotCaptureWindow(selected_window); + + // We want to capture the source again eventually, so put it last in the + // queue. + capture_queue_.push_back(source_id); + } +} + +void API_AVAILABLE(macos(14.0)) + ScreenshotManagerCapturer::SCScreenshotCaptureWindow(SCWindow* window) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + // Create SCStreamConfiguration. + SCStreamConfiguration* config = [[SCStreamConfiguration alloc] init]; + config.scalesToFit = YES; + config.showsCursor = NO; + + // Avoid black regions in the captured frame by setting width and height to + // the same aspect ratio as the window. + float thumbnail_aspect_ratio = static_cast<float>(thumbnail_size_.width()) / + static_cast<float>(thumbnail_size_.height()); + float window_aspect_ratio = + window.frame.size.width / window.frame.size.height; + if (window_aspect_ratio > thumbnail_aspect_ratio) { + config.width = thumbnail_size_.width(); + config.height = std::round(thumbnail_size_.width() / window_aspect_ratio); + } else { + config.height = thumbnail_size_.height(); + config.width = std::round(thumbnail_size_.height() * window_aspect_ratio); + } + + SCContentFilter* filter = + [[SCContentFilter alloc] initWithDesktopIndependentWindow:window]; + + auto captured_frame_callback = + base::BindPostTask(task_runner_, sample_callback_); + + auto handler = ^(CGImageRef sampleBuffer, NSError* error) { + if (error) { + return; + } + base::apple::ScopedCFTypeRef<CGImageRef> scopedImage( + sampleBuffer, base::scoped_policy::RETAIN); + captured_frame_callback.Run(scopedImage, [window windowID]); + }; + + [SCScreenshotManager captureImageWithFilter:filter + configuration:config + completionHandler:handler]; +} + class API_AVAILABLE(macos(13.2)) ThumbnailCapturerMac : public ThumbnailCapturer { public: @@ -252,6 +450,7 @@ void OnRecurrentShareableContent(SCShareableContent* content); void UpdateShareableWindows(NSArray<SCWindow*>* content_windows); + SCWindow* GetShareableWindow(SourceId source_id) const; // Returns the supplied list of windows sorted to have the same order as // returned from CGWindowListCopyWindowInfo. @@ -270,6 +469,7 @@ SourceId source_id); scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + const CaptureMode capture_mode_; const SortMode sort_mode_; int max_frame_rate_; const int minimum_window_size_; @@ -285,11 +485,14 @@ base::flat_map<SourceId, StreamAndDelegate> streams_; base::RepeatingTimer refresh_timer_; + std::unique_ptr<ScreenshotManagerCapturer> screenshot_manager_capturer_; + base::WeakPtrFactory<ThumbnailCapturerMac> weak_factory_{this}; }; ThumbnailCapturerMac::ThumbnailCapturerMac() - : sort_mode_(kThumbnailCapturerMacSortMode.Get()), + : capture_mode_(GetCaptureModeFeatureParam()), + sort_mode_(kThumbnailCapturerMacSortMode.Get()), max_frame_rate_(kThumbnailCapturerMacMaxFrameRate.Get()), minimum_window_size_(kThumbnailCapturerMacMinWindowSize.Get()), shareable_windows_([[NSArray<SCWindow*> alloc] init]) {} @@ -302,6 +505,18 @@ refresh_timer_.Start(FROM_HERE, kThumbnailCapturerMacRefreshTimerInterval.Get(), this, &ThumbnailCapturerMac::UpdateWindowsList); + + if (capture_mode_ == CaptureMode::kSCScreenshotManager) { + CHECK(!screenshot_manager_capturer_); + // Unretained is safe because `screenshot_manager_capturer_ ` is owned by + // `this`, and hence has a shorter lifetime than `this`. + screenshot_manager_capturer_ = std::make_unique<ScreenshotManagerCapturer>( + max_frame_rate_, + base::BindRepeating(&ThumbnailCapturerMac::GetShareableWindow, + base::Unretained(this)), + base::BindRepeating(&ThumbnailCapturerMac::OnCapturedFrame, + weak_factory_.GetWeakPtr())); + } } void ThumbnailCapturerMac::SetMaxFrameRate(uint32_t max_frame_rate) { @@ -403,6 +618,10 @@ RemoveInactiveStreams(); } +SCWindow* ThumbnailCapturerMac::GetShareableWindow(SourceId source_id) const { + return FindWindow(shareable_windows_, source_id); +} + NSArray<SCWindow*>* ThumbnailCapturerMac::SortOrderByCGWindowList( NSArray<SCWindow*>* current_windows) const { CHECK_EQ(sort_mode_, SortMode::kCGWindowList); @@ -509,6 +728,12 @@ gfx::Size thumbnail_size) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); + if (capture_mode_ == CaptureMode::kSCScreenshotManager) { + CHECK(screenshot_manager_capturer_); + screenshot_manager_capturer_->SelectSources(ids, thumbnail_size); + return; + } + // Create SCStreamConfiguration. SCStreamConfiguration* config = [[SCStreamConfiguration alloc] init]; config.width = thumbnail_size.width();
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc index 114ef4a..955ca8d0 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc +++ b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.cc
@@ -26,9 +26,7 @@ std::make_unique< password_manager::PasswordSessionDurationsMetricsRecorder>( pref_service, - sync_service)), - download_metrics_recorder_( - std::make_unique<DownloadSessionDurationsMetricsRecorder>()) { + sync_service)) { session_duration_observation_.Observe(tracker); if (tracker->in_session()) { // The session was started before this service was created. Let's start @@ -52,7 +50,6 @@ password_metrics_recorder_.reset(); msbb_metrics_recorder_.reset(); sync_metrics_recorder_.reset(); - download_metrics_recorder_.reset(); } bool DesktopProfileSessionDurationsService::IsSignedIn() const { @@ -68,7 +65,6 @@ sync_metrics_recorder_->OnSessionStarted(session_start); msbb_metrics_recorder_->OnSessionStarted(session_start); password_metrics_recorder_->OnSessionStarted(session_start); - download_metrics_recorder_->OnSessionStarted(session_start); } void DesktopProfileSessionDurationsService::OnSessionEnded( @@ -77,7 +73,6 @@ sync_metrics_recorder_->OnSessionEnded(session_length); msbb_metrics_recorder_->OnSessionEnded(session_length); password_metrics_recorder_->OnSessionEnded(session_length); - download_metrics_recorder_->OnSessionEnded(session_end); } } // namespace metrics
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h index e946d3c..089c9da8 100644 --- a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h +++ b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service.h
@@ -6,7 +6,6 @@ #define CHROME_BROWSER_METRICS_DESKTOP_SESSION_DURATION_DESKTOP_PROFILE_SESSION_DURATIONS_SERVICE_H_ #include "base/scoped_observation.h" -#include "chrome/browser/download/download_session_durations_metrics_recorder.h" #include "chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.h" #include "components/keyed_service/core/keyed_service.h" #include "components/password_manager/core/browser/password_session_durations_metrics_recorder.h" @@ -61,8 +60,6 @@ msbb_metrics_recorder_; std::unique_ptr<password_manager::PasswordSessionDurationsMetricsRecorder> password_metrics_recorder_; - std::unique_ptr<DownloadSessionDurationsMetricsRecorder> - download_metrics_recorder_; base::ScopedObservation<DesktopSessionDurationTracker, DesktopSessionDurationTracker::Observer>
diff --git a/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service.cc b/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service.cc index c5369e4..50b8684c 100644 --- a/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service.cc +++ b/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service.cc
@@ -153,11 +153,23 @@ // Do additional filtering on clusters. history_clusters::CoalesceRelatedSearches(clusters); - // Cull clusters that do not have the minimum number of visits with and - // without images to be eligible for display. + // Maintain a list of observed cluster labels and discard any clusters + // associated with a duplicate label. + std::set<std::u16string> seen_cluster_labels = {}; NTPHistoryClustersIneligibleReason ineligible_reason = clusters.empty() ? kNoClusters : kNone; base::EraseIf(clusters, [&](auto& cluster) { + // Cull clusters that do not have a label. + if (!cluster.label.has_value()) { + return true; + } + + // Cull clusters with a label that has already been observed. + if (base::Contains(seen_cluster_labels, cluster.label.value())) { + return true; + } + seen_cluster_labels.insert(cluster.label.value()); + // Cull non prominent clusters. if (!cluster.should_show_on_prominent_ui_surfaces) { ineligible_reason = kNonProminent; @@ -207,6 +219,8 @@ .has_url_keyed_image && v.annotated_visit.visit_row.is_known_to_sync); }); + // Cull clusters that do not have the minimum number of visits with images + // to be eligible for display. if (visits_with_images < filter_params.min_visits_with_images) { ineligible_reason = kInsufficientImages; return true;
diff --git a/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service_unittest.cc b/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service_unittest.cc index c1beaf0..19d57ca 100644 --- a/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service_unittest.cc +++ b/chrome/browser/new_tab_page/modules/history_clusters/history_clusters_module_service_unittest.cc
@@ -159,6 +159,7 @@ } history::Cluster SampleCluster(int id, + const std::string& sample_label, int srp_visits, int non_srp_visits, const std::vector<std::string> related_searches = @@ -183,7 +184,6 @@ } visits.insert(visits.end(), non_srp_visits, sample_non_srp_visit); - std::string kSampleLabel = "LabelOne"; return history::Cluster(id, std::move(visits), {{u"apples", history::ClusterKeywordData()}, {u"Red Oranges", history::ClusterKeywordData()}}, @@ -191,14 +191,15 @@ /*label=*/ l10n_util::GetStringFUTF16( IDS_HISTORY_CLUSTERS_CLUSTER_LABEL_SEARCH_TERMS, - base::UTF8ToUTF16(kSampleLabel))); + base::UTF8ToUTF16(sample_label))); } history::Cluster SampleCluster(int srp_visits, int non_srp_visits, const std::vector<std::string> related_searches = {"fruits", "red fruits", "healthy fruits"}) { - return SampleCluster(1, srp_visits, non_srp_visits, related_searches); + return SampleCluster(1, "Fruits", srp_visits, non_srp_visits, + related_searches); } TEST_F(HistoryClustersModuleServiceTest, GetClustersJourneysNotEnabled) { @@ -216,7 +217,8 @@ std::vector<history::Cluster> sample_clusters; for (int i = 0; i < kSampleClusterCount; i++) { sample_clusters.push_back( - SampleCluster(i, /*srp_visits=*/1, /*non_srp_visits=*/2)); + SampleCluster(i, base::StringPrintf("Fruits %d", i), /*srp_visits=*/1, + /*non_srp_visits=*/2)); } test_history_clusters_service().SetClustersToReturnOnFirstCall( sample_clusters); @@ -246,12 +248,33 @@ "NewTabPage.HistoryClusters.NumRelatedSearches", 3, 1); } +TEST_F(HistoryClustersModuleServiceTest, GetClustersFiltersLabelDuplicates) { + base::HistogramTester histogram_tester; + + const std::string kSampleLabel = "Fruits"; + test_history_clusters_service().SetClustersToReturnForCalls( + {{SampleCluster(1, kSampleLabel, /*srp_visits=*/1, /*non_srp_visits=*/2)}, + {SampleCluster(2, kSampleLabel, /*srp_visits=*/1, + /*non_srp_visits=*/2)}}); + + std::vector<history::Cluster> clusters = GetClusters(); + ASSERT_EQ(1u, clusters.size()); + + histogram_tester.ExpectUniqueSample( + "NewTabPage.HistoryClusters.IneligibleReason", 0, 1); + histogram_tester.ExpectUniqueSample( + "NewTabPage.HistoryClusters.HasClusterToShow", true, 1); + histogram_tester.ExpectUniqueSample( + "NewTabPage.HistoryClusters.NumClusterCandidates", 1, 1); +} + TEST_F(HistoryClustersModuleServiceTest, GetClustersRefetchesUntilExhausted) { base::HistogramTester histogram_tester; test_history_clusters_service().SetClustersToReturnForCalls( - {{SampleCluster(1, /*srp_visits=*/1, /*non_srp_visits=*/2)}, - {SampleCluster(2, /*srp_visits=*/1, /*non_srp_visits=*/2)}}); + {{SampleCluster(1, "Fruits", /*srp_visits=*/1, /*non_srp_visits=*/2)}, + {SampleCluster(2, "Healthy Fruits", /*srp_visits=*/1, + /*non_srp_visits=*/2)}}); std::vector<history::Cluster> clusters = GetClusters(); ASSERT_EQ(2u, clusters.size()); @@ -415,7 +438,7 @@ base::HistogramTester histogram_tester; const history::Cluster kSampleCluster = SampleCluster( - /*id=*/1, /*srp_visits=*/1, /*non_srp_visits=*/2, + /*id=*/1, "Label", /*srp_visits=*/1, /*non_srp_visits=*/2, /*related_searches=*/{}); test_history_clusters_service().SetClustersToReturnOnFirstCall( {kSampleCluster}); @@ -541,12 +564,15 @@ std::vector<history::Cluster> first_fetch_sample_clusters; for (size_t i = 0; i < kFirstFetchSampleClusterCount; i++) { first_fetch_sample_clusters.push_back( - SampleCluster(i, /*srp_visits=*/1, /*non_srp_visits=*/2)); + SampleCluster(i, base::StringPrintf("Fruits %zu", i), /*srp_visits=*/1, + /*non_srp_visits=*/2)); } + const std::string kSampleLabel = "Fruits"; test_history_clusters_service().SetClustersToReturnForCalls( {first_fetch_sample_clusters, - {SampleCluster(3, /*srp_visits=*/1, /*non_srp_visits=*/2)}}); + {SampleCluster(3, kSampleLabel, /*srp_visits=*/1, + /*non_srp_visits=*/2)}}); std::vector<history::Cluster> clusters = GetClusters(); ASSERT_EQ(kFirstFetchSampleClusterCount, clusters.size());
diff --git a/chrome/browser/password_manager/android/credential_leak_controller_android_unittest.cc b/chrome/browser/password_manager/android/credential_leak_controller_android_unittest.cc index c5938c4..108d114 100644 --- a/chrome/browser/password_manager/android/credential_leak_controller_android_unittest.cc +++ b/chrome/browser/password_manager/android/credential_leak_controller_android_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include "base/android/build_info.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "chrome/browser/password_manager/android/mock_password_checkup_launcher_helper.h" @@ -75,6 +76,10 @@ } // namespace TEST(CredentialLeakControllerAndroidTest, ClickedCancel) { + if (base::android::BuildInfo::GetInstance()->is_automotive()) { + GTEST_SKIP() << "This test should not run on automotive."; + } + base::test::TaskEnvironment task_environment; base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -119,6 +124,9 @@ TEST(CredentialLeakControllerAndroidTest, ClickedCheckPasswordsLaunchesCheckup) { + if (base::android::BuildInfo::GetInstance()->is_automotive()) { + GTEST_SKIP() << "This test should not run on automotive."; + } base::test::TaskEnvironment task_environment; base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -145,6 +153,37 @@ LeakDialogDismissalReason::kClickedCheckPasswords); } +TEST(CredentialLeakControllerAndroidTest, + AutomotiveShowsOkButtonForSavedReusedSynced) { + if (!base::android::BuildInfo::GetInstance()->is_automotive()) { + GTEST_SKIP() << "This test should only run on automotive."; + } + base::test::TaskEnvironment task_environment; + base::HistogramTester histogram_tester; + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + std::unique_ptr<MockPasswordCheckupLauncherHelper> mock_launcher = + std::make_unique<MockPasswordCheckupLauncherHelper>(); + EXPECT_CALL( + *mock_launcher, + LaunchLocalCheckup( + _, _, password_manager::PasswordCheckReferrerAndroid::kLeakDialog)) + .Times(0); + MakeController(std::move(mock_launcher), IsSaved(true), IsReused(true), + IsSyncing(true)) + ->OnAcceptDialog(); + + histogram_tester.ExpectUniqueSample( + "PasswordManager.LeakDetection.DialogDismissalReason", + LeakDialogDismissalReason::kClickedOk, 1); + + histogram_tester.ExpectUniqueSample( + "PasswordManager.LeakDetection.DialogDismissalReason.Change", + LeakDialogDismissalReason::kClickedOk, 1); + + CheckUkmMetricsExpectations(test_ukm_recorder, LeakDialogType::kChange, + LeakDialogDismissalReason::kClickedOk); +} + TEST(CredentialLeakControllerAndroidTest, NoDirectInteraction) { base::test::TaskEnvironment task_environment; base::HistogramTester histogram_tester;
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl.cc b/chrome/browser/password_manager/android/password_accessory_controller_impl.cc index 171b4c9..8feacd6 100644 --- a/chrome/browser/password_manager/android/password_accessory_controller_impl.cc +++ b/chrome/browser/password_manager/android/password_accessory_controller_impl.cc
@@ -255,13 +255,13 @@ void PasswordAccessoryControllerImpl::OnFillingTriggered( autofill::FieldGlobalId focused_field_id, const AccessorySheetField& selection) { + authenticator_ = password_client_->GetDeviceAuthenticator(); if (!ShouldTriggerBiometricReauth(selection)) { + authenticator_.reset(); FillSelection(selection); return; } - authenticator_ = password_client_->GetDeviceAuthenticator(); - // |this| cancels the authentication when it is destroyed if one is ongoing, // which resets the callback, so it's safe to use base::Unretained(this) here. authenticator_->Authenticate( @@ -616,9 +616,7 @@ return false; } - std::unique_ptr<device_reauth::DeviceAuthenticator> authenticator = - password_client_->GetDeviceAuthenticator(); - return password_manager_util::CanUseBiometricAuth(authenticator.get(), + return password_manager_util::CanUseBiometricAuth(authenticator_.get(), password_client_); }
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc index ef4834ce2..bbd1ed3 100644 --- a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc +++ b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc
@@ -976,17 +976,11 @@ EXPECT_CALL(*mock_authenticator, CanAuthenticateWithBiometrics) .WillOnce(Return(true)); - - auto mock_authenticator2 = std::make_unique<MockDeviceAuthenticator>(); - - EXPECT_CALL(*mock_authenticator2.get(), + EXPECT_CALL(*mock_authenticator, Authenticate(DeviceAuthRequester::kFallbackSheet, _, /*use_last_valid_auth=*/true)) .WillOnce(RunOnceCallback<1>(/*auth_succeeded=*/true)); - // Expect calls for the same method need to be listed in reverse order. - EXPECT_CALL(*password_client(), GetDeviceAuthenticator) - .WillOnce(Return(testing::ByMove(std::move(mock_authenticator2)))); EXPECT_CALL(*password_client(), GetDeviceAuthenticator) .WillOnce(Return(testing::ByMove(std::move(mock_authenticator)))) .RetiresOnSaturation(); @@ -1022,17 +1016,11 @@ EXPECT_CALL(*mock_authenticator, CanAuthenticateWithBiometrics) .WillOnce(Return(true)); - - auto mock_authenticator2 = std::make_unique<MockDeviceAuthenticator>(); - - EXPECT_CALL(*mock_authenticator2.get(), + EXPECT_CALL(*mock_authenticator, Authenticate(DeviceAuthRequester::kFallbackSheet, _, /*use_last_valid_auth=*/true)) .WillOnce(RunOnceCallback<1>(/*auth_succeeded=*/false)); - // Expect calls for the same method need to be listed in reverse order. - EXPECT_CALL(*password_client(), GetDeviceAuthenticator) - .WillOnce(Return(testing::ByMove(std::move(mock_authenticator2)))); EXPECT_CALL(*password_client(), GetDeviceAuthenticator) .WillOnce(Return(testing::ByMove(std::move(mock_authenticator)))) .RetiresOnSaturation(); @@ -1066,20 +1054,14 @@ /*selectable=*/true); auto mock_authenticator = std::make_unique<MockDeviceAuthenticator>(); + auto* mock_authenticator_ptr = mock_authenticator.get(); - EXPECT_CALL(*mock_authenticator, CanAuthenticateWithBiometrics) + EXPECT_CALL(*mock_authenticator_ptr, CanAuthenticateWithBiometrics) .WillOnce(Return(true)); - - auto mock_authenticator2 = std::make_unique<MockDeviceAuthenticator>(); - auto* mock_authenticator_ptr2 = mock_authenticator2.get(); - - EXPECT_CALL(*mock_authenticator_ptr2, + EXPECT_CALL(*mock_authenticator_ptr, Authenticate(DeviceAuthRequester::kFallbackSheet, _, /*use_last_valid_auth=*/true)); - // Expect calls for the same method need to be listed in reverse order. - EXPECT_CALL(*password_client(), GetDeviceAuthenticator) - .WillOnce(Return(testing::ByMove(std::move(mock_authenticator2)))); EXPECT_CALL(*password_client(), GetDeviceAuthenticator) .WillOnce(Return(testing::ByMove(std::move(mock_authenticator)))) .RetiresOnSaturation(); @@ -1090,7 +1072,7 @@ .Times(0); controller()->OnFillingTriggered(autofill::FieldGlobalId(), selected_field); - EXPECT_CALL(*mock_authenticator_ptr2, + EXPECT_CALL(*mock_authenticator_ptr, Cancel(DeviceAuthRequester::kFallbackSheet)); }
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_monitor.cc b/chrome/browser/performance_manager/metrics/page_timeline_monitor.cc index df6d79f8d..83233be8 100644 --- a/chrome/browser/performance_manager/metrics/page_timeline_monitor.cc +++ b/chrome/browser/performance_manager/metrics/page_timeline_monitor.cc
@@ -22,6 +22,8 @@ #include "components/performance_manager/public/decorators/page_live_state_decorator.h" #include "components/performance_manager/public/features.h" #include "components/performance_manager/public/graph/page_node.h" +#include "components/performance_manager/public/resource_attribution/query_results.h" +#include "components/performance_manager/public/resource_attribution/resource_contexts.h" #include "services/metrics/public/cpp/metrics_utils.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" @@ -107,36 +109,79 @@ } void PageTimelineMonitor::CollectPageResourceUsage() { - const PageTimelineCPUMonitor::CPUUsageMap cpu_usage_map = - cpu_monitor_.UpdateCPUMeasurements(); + if (performance_manager::features::kUseResourceAttributionCPUMonitor.Get()) { + const std::map<resource_attribution::ResourceContext, + resource_attribution::CPUTimeResult> + cpu_usage_map = cpu_measurement_monitor_.UpdateAndGetCPUMeasurements(); - // Calculate the overall CPU usage. - double total_cpu_usage = 0; - std::vector<std::pair<const PageNode*, double>> page_cpu_usage; - page_cpu_usage.reserve(page_node_info_map_.size()); - for (const auto& [tab_handle, info_ptr] : page_node_info_map_) { - const PageNode* page_node = tab_handle->page_node(); - CheckPageState(page_node, *info_ptr); - double cpu_usage = - PageTimelineCPUMonitor::EstimatePageCPUUsage(page_node, cpu_usage_map); - page_cpu_usage.emplace_back(page_node, cpu_usage); - total_cpu_usage += cpu_usage; - } + auto get_cpu_usage = [&cpu_usage_map](const PageNode* page_node) -> double { + // CPUMeasurementMonitor collects results for all pages, but any with no + // CPU use won't appear in the map. + const auto it = cpu_usage_map.find(page_node->GetResourceContext()); + if (it == cpu_usage_map.end()) { + return 0; + } + const resource_attribution::CPUTimeResult& result = it->second; + return result.cumulative_cpu / + (result.metadata.measurement_time - result.start_time); + }; + // Calculate the overall CPU usage. + double total_cpu_usage = 0; + for (const auto& [tab_handle, info_ptr] : page_node_info_map_) { + const PageNode* page_node = tab_handle->page_node(); + CheckPageState(page_node, *info_ptr); + total_cpu_usage += get_cpu_usage(page_node); + } - const auto now = base::TimeTicks::Now(); - for (const auto& [page_node, cpu_usage] : page_cpu_usage) { - const ukm::SourceId source_id = page_node->GetUkmSourceID(); - ukm::builders::PerformanceManager_PageResourceUsage2(source_id) - .SetResidentSetSizeEstimate(page_node->EstimateResidentSetSize()) - .SetPrivateFootprintEstimate(page_node->EstimatePrivateFootprintSize()) - .SetRecentCPUUsage(kCPUUsageFactor * cpu_usage) - .SetTotalRecentCPUUsageAllPages(kCPUUsageFactor * total_cpu_usage) - .SetBackgroundState( - static_cast<int64_t>(GetBackgroundStateForMeasurementPeriod( - page_node, now - time_of_last_resource_usage_))) - .Record(ukm::UkmRecorder::Get()); + const auto now = base::TimeTicks::Now(); + for (const auto& [tab_handle, _] : page_node_info_map_) { + const PageNode* page_node = tab_handle->page_node(); + const ukm::SourceId source_id = page_node->GetUkmSourceID(); + ukm::builders::PerformanceManager_PageResourceUsage2(source_id) + .SetResidentSetSizeEstimate(page_node->EstimateResidentSetSize()) + .SetPrivateFootprintEstimate( + page_node->EstimatePrivateFootprintSize()) + .SetRecentCPUUsage(kCPUUsageFactor * get_cpu_usage(page_node)) + .SetTotalRecentCPUUsageAllPages(kCPUUsageFactor * total_cpu_usage) + .SetBackgroundState( + static_cast<int64_t>(GetBackgroundStateForMeasurementPeriod( + page_node, now - time_of_last_resource_usage_))) + .Record(ukm::UkmRecorder::Get()); + } + time_of_last_resource_usage_ = now; + } else { + const PageTimelineCPUMonitor::CPUUsageMap cpu_usage_map = + cpu_monitor_.UpdateCPUMeasurements(); + + // Calculate the overall CPU usage. + double total_cpu_usage = 0; + std::vector<std::pair<const PageNode*, double>> page_cpu_usage; + page_cpu_usage.reserve(page_node_info_map_.size()); + for (const auto& [tab_handle, info_ptr] : page_node_info_map_) { + const PageNode* page_node = tab_handle->page_node(); + CheckPageState(page_node, *info_ptr); + double cpu_usage = PageTimelineCPUMonitor::EstimatePageCPUUsage( + page_node, cpu_usage_map); + page_cpu_usage.emplace_back(page_node, cpu_usage); + total_cpu_usage += cpu_usage; + } + + const auto now = base::TimeTicks::Now(); + for (const auto& [page_node, cpu_usage] : page_cpu_usage) { + const ukm::SourceId source_id = page_node->GetUkmSourceID(); + ukm::builders::PerformanceManager_PageResourceUsage2(source_id) + .SetResidentSetSizeEstimate(page_node->EstimateResidentSetSize()) + .SetPrivateFootprintEstimate( + page_node->EstimatePrivateFootprintSize()) + .SetRecentCPUUsage(kCPUUsageFactor * cpu_usage) + .SetTotalRecentCPUUsageAllPages(kCPUUsageFactor * total_cpu_usage) + .SetBackgroundState( + static_cast<int64_t>(GetBackgroundStateForMeasurementPeriod( + page_node, now - time_of_last_resource_usage_))) + .Record(ukm::UkmRecorder::Get()); + } + time_of_last_resource_usage_ = now; } - time_of_last_resource_usage_ = now; } void PageTimelineMonitor::CollectSlice() { @@ -262,11 +307,20 @@ graph_->AddPageNodeObserver(this); graph_->RegisterObject(this); graph->GetRegisteredObjectAs<TabPageDecorator>()->AddObserver(this); - cpu_monitor_.StartMonitoring(graph_); + + if (performance_manager::features::kUseResourceAttributionCPUMonitor.Get()) { + cpu_measurement_monitor_.StartMonitoring(graph_); + } else { + cpu_monitor_.StartMonitoring(graph_); + } } void PageTimelineMonitor::OnTakenFromGraph(Graph* graph) { - cpu_monitor_.StopMonitoring(graph_); + if (performance_manager::features::kUseResourceAttributionCPUMonitor.Get()) { + cpu_measurement_monitor_.StopMonitoring(); + } else { + cpu_monitor_.StopMonitoring(graph_); + } // GraphOwned object destruction order is undefined, so only remove ourselves // as observers if the decorator still exists.
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_monitor.h b/chrome/browser/performance_manager/metrics/page_timeline_monitor.h index cbcee21..cd18f038 100644 --- a/chrome/browser/performance_manager/metrics/page_timeline_monitor.h +++ b/chrome/browser/performance_manager/metrics/page_timeline_monitor.h
@@ -18,6 +18,7 @@ #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/graph/graph_registered.h" #include "components/performance_manager/public/graph/page_node.h" +#include "components/performance_manager/public/resource_attribution/cpu_measurement_monitor.h" namespace performance_manager::metrics { @@ -165,7 +166,8 @@ bool battery_saver_enabled_ = false; - // Helper to take CPU measurements for the UKM. + // Helpers to take CPU measurements for the UKM. + resource_attribution::CPUMeasurementMonitor cpu_measurement_monitor_; PageTimelineCPUMonitor cpu_monitor_; // WeakPtrFactory for the RepeatingTimer to call a method on this object.
diff --git a/chrome/browser/preloading/preloading_features.cc b/chrome/browser/preloading/preloading_features.cc index db7cea3..b74afd3d 100644 --- a/chrome/browser/preloading/preloading_features.cc +++ b/chrome/browser/preloading/preloading_features.cc
@@ -8,6 +8,6 @@ BASE_FEATURE(kPerformanceSettingsPreloadingSubpage, "PerformanceSettingsPreloadingSubpage", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); } // namespace features
diff --git a/chrome/browser/printing/printer_query_oop.cc b/chrome/browser/printing/printer_query_oop.cc index 1aa03b27..d367311 100644 --- a/chrome/browser/printing/printer_query_oop.cc +++ b/chrome/browser/printing/printer_query_oop.cc
@@ -30,7 +30,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // TODO(crbug.com/1414968) Do extra setup on the worker as needed for // supporting OOP system print dialogs. - return CreatePrintJobWorker(print_job); + return CreatePrintJobWorkerOop(print_job); } #if BUILDFLAG(IS_WIN) @@ -357,7 +357,7 @@ } #endif // BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) -std::unique_ptr<PrintJobWorkerOop> PrinterQueryOop::CreatePrintJobWorker( +std::unique_ptr<PrintJobWorkerOop> PrinterQueryOop::CreatePrintJobWorkerOop( PrintJob* print_job) { return std::make_unique<PrintJobWorkerOop>( std::move(printing_context_delegate_), std::move(printing_context_),
diff --git a/chrome/browser/printing/printer_query_oop.h b/chrome/browser/printing/printer_query_oop.h index 5b276c43..1a51c54 100644 --- a/chrome/browser/printing/printer_query_oop.h +++ b/chrome/browser/printing/printer_query_oop.h
@@ -86,7 +86,7 @@ #endif // Used by `TransferContextToNewWorker()`. Virtual to support testing. - virtual std::unique_ptr<PrintJobWorkerOop> CreatePrintJobWorker( + virtual std::unique_ptr<PrintJobWorkerOop> CreatePrintJobWorkerOop( PrintJob* print_job); const absl::optional<PrintBackendServiceManager::ClientId>&
diff --git a/chrome/browser/printing/system_access_process_print_browsertest.cc b/chrome/browser/printing/system_access_process_print_browsertest.cc index 2ec564a..c5197364 100644 --- a/chrome/browser/printing/system_access_process_print_browsertest.cc +++ b/chrome/browser/printing/system_access_process_print_browsertest.cc
@@ -344,7 +344,7 @@ callbacks_->did_update_print_settings_callback.Run(result); } - std::unique_ptr<PrintJobWorkerOop> CreatePrintJobWorker( + std::unique_ptr<PrintJobWorkerOop> CreatePrintJobWorkerOop( PrintJob* print_job) override { return std::make_unique<TestPrintJobWorkerOop>( std::move(printing_context_delegate_), std::move(printing_context_),
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java index f2adc685..bc7d8a4b 100644 --- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java +++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java
@@ -17,11 +17,20 @@ private final Runnable mCloseBottomSheetCallback; private ObservableSupplierImpl<Boolean> mBackPressStateChangedSupplier = new ObservableSupplierImpl<>(); + private final float mHalfHeight; + private final float mFullHeight; PrivacyGuideBottomSheetView(View contentView, Runnable closeBottomSheetCallback) { + this(contentView, closeBottomSheetCallback, HeightMode.DEFAULT, HeightMode.WRAP_CONTENT); + } + + PrivacyGuideBottomSheetView(View contentView, Runnable closeBottomSheetCallback, + float halfHeight, float fullHeight) { mContentView = contentView; mCloseBottomSheetCallback = closeBottomSheetCallback; mBackPressStateChangedSupplier.set(true); + mHalfHeight = halfHeight; + mFullHeight = fullHeight; } @Override @@ -54,8 +63,13 @@ } @Override + public float getHalfHeightRatio() { + return mHalfHeight; + } + + @Override public float getFullHeightRatio() { - return BottomSheetContent.HeightMode.WRAP_CONTENT; + return mFullHeight; } @Override
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java index c419e1e..c17e57ad 100644 --- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java +++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/SafeBrowsingFragment.java
@@ -140,7 +140,16 @@ } private void displayBottomSheet(View sheetContent) { - mBottomSheetView = new PrivacyGuideBottomSheetView(sheetContent, this::closeBottomSheet); + if (ChromeFeatureList.isEnabled( + ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_ENHANCED_PROTECTION) + && ChromeFeatureList.isEnabled( + ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_STANDARD_PROTECTION)) { + mBottomSheetView = new PrivacyGuideBottomSheetView( + sheetContent, this::closeBottomSheet, 0.9f, 1.0f); + } else { + mBottomSheetView = + new PrivacyGuideBottomSheetView(sheetContent, this::closeBottomSheet); + } // TODO(crbug.com/1287979): Re-enable animation once bug is fixed if (mBottomSheetController != null) { mBottomSheetController.requestShowContent(mBottomSheetView, false);
diff --git a/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java b/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java index c98a399..c92ad08 100644 --- a/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java +++ b/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java
@@ -1234,6 +1234,7 @@ @Test @LargeTest @Feature({"PrivacyGuide"}) + @DisableFeatures(ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_ENHANCED_PROTECTION) @EnableFeatures(ChromeFeatureList.PRIVACY_GUIDE_POST_MVP) public void testSafeBrowsingCard_enhancedBottomSheetBackButtonBehaviour() { launchPrivacyGuide(); @@ -1658,7 +1659,8 @@ @Test @LargeTest @Feature({"PrivacyGuide"}) - public void testBottomSheetControllerOnRecreate() { + @DisableFeatures(ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_ENHANCED_PROTECTION) + public void testBottomSheetControllerOnRecreateOriginal() { launchPrivacyGuide(); goToCard(FragmentType.SAFE_BROWSING); mPrivacyGuideTestRule.recreateActivity(); @@ -1668,6 +1670,18 @@ @Test @LargeTest + @Feature({"PrivacyGuide"}) + @EnableFeatures(ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_ENHANCED_PROTECTION) + public void testBottomSheetControllerOnRecreate() { + launchPrivacyGuide(); + goToCard(FragmentType.SAFE_BROWSING); + mPrivacyGuideTestRule.recreateActivity(); + clickOnArrowNextToRadioButtonWithText(R.string.privacy_guide_safe_browsing_enhanced_title); + onViewWaiting(withId(R.id.sb_enhanced_sheet_updated)).check(matches(isDisplayed())); + } + + @Test + @LargeTest @EnableFeatures(ChromeFeatureList.PRIVACY_GUIDE) @DisableFeatures(ChromeFeatureList.PRIVACY_GUIDE_POST_MVP) public void testExitOnBackInWelcomeCard() {
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc index 3db58b6..f07c3a3 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc
@@ -4,15 +4,32 @@ #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h" +#include <memory> +#include <utility> + +#include "base/check.h" #include "base/feature_list.h" +#include "base/memory/scoped_refptr.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "build/buildflag.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" +#include "components/content_settings/core/browser/cookie_settings.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/metrics/metrics_pref_names.h" #include "components/prefs/pref_service.h" #include "components/privacy_sandbox/privacy_sandbox_features.h" #include "components/privacy_sandbox/privacy_sandbox_prefs.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/tribool.h" +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/android/webapps/webapp_registry.h" +#endif + namespace { signin::Tribool GetPrivacySandboxRestrictedByAccountCapability( @@ -26,7 +43,13 @@ } // namespace PrivacySandboxSettingsDelegate::PrivacySandboxSettingsDelegate(Profile* profile) - : profile_(profile) {} + : profile_(profile) +#if BUILDFLAG(IS_ANDROID) + , + webapp_registry_(std::make_unique<WebappRegistry>()) +#endif +{ +} PrivacySandboxSettingsDelegate::~PrivacySandboxSettingsDelegate() = default; @@ -132,3 +155,100 @@ .is_subject_to_chrome_privacy_sandbox_restricted_measurement_notice(); return capability == signin::Tribool::kTrue; } + +bool PrivacySandboxSettingsDelegate::IsCookieDeprecationExperimentEligible() + const { + // TODO(linnan): Returns the final client-level decision from + // `ExperimentManager`. + + PrefService* pref_service = profile_->GetPrefs(); + DCHECK(pref_service); + + // The 3PCD experiment eligibility is a one-time decision. + if (pref_service->HasPrefPath( + prefs::kPrivacySandboxCookieDeprecationExperimentEligible)) { + return pref_service->GetBoolean( + prefs::kPrivacySandboxCookieDeprecationExperimentEligible); + } + + bool is_eligible = IsCookieDeprecationExperimentCurrentlyEligible(); + pref_service->SetBoolean( + prefs::kPrivacySandboxCookieDeprecationExperimentEligible, is_eligible); + return is_eligible; +} + +bool PrivacySandboxSettingsDelegate:: + IsCookieDeprecationExperimentCurrentlyEligible() const { + // Whether third-party cookies are blocked. + scoped_refptr<content_settings::CookieSettings> cookie_settings = + CookieSettingsFactory::GetForProfile(profile_); + DCHECK(cookie_settings); + if (cookie_settings->ShouldBlockThirdPartyCookies() || + cookie_settings->GetDefaultCookieSetting() == + ContentSetting::CONTENT_SETTING_BLOCK) { + return false; + } + + // Whether the privacy sandbox Ads APIs notice has been seen. + // + // TODO(linnan): Consider checking whether the restricted notice has been + // acknowledged (`prefs::kPrivacySandboxM1RestrictedNoticeAcknowledged`) as + // well. + const bool row_notice_acknowledged = profile_->GetPrefs()->GetBoolean( + prefs::kPrivacySandboxM1RowNoticeAcknowledged); + const bool eaa_notice_acknowledged = profile_->GetPrefs()->GetBoolean( + prefs::kPrivacySandboxM1EEANoticeAcknowledged); + if (!row_notice_acknowledged && !eaa_notice_acknowledged) { + return false; + } + + // Whether it's a dasher account. + if (IsSubjectToEnterprisePolicies()) { + return false; + } + + // TODO(linnan): Consider moving the following client-level filtering to + // `ExperimentManager`. + + // Whether it's a new client. + base::Time install_date = base::Time::FromTimeT( + g_browser_process->local_state()->GetInt64(metrics::prefs::kInstallDate)); + if (install_date.is_null() || + base::Time::Now() - install_date < base::Days(30)) { + return false; + } + +// Whether PWA or TWA has been installed on Android. +#if BUILDFLAG(IS_ANDROID) + if (!webapp_registry_->GetOriginsWithInstalledApp().empty()) { + return false; + } +#endif + + return true; +} + +bool PrivacySandboxSettingsDelegate::IsSubjectToEnterprisePolicies() const { + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_); + if (!identity_manager || + !identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) { + // The user isn't signed in so we can't apply any capabilties-based + // restrictions. + return false; + } + + const AccountInfo account_info = + identity_manager->FindExtendedPrimaryAccountInfo( + signin::ConsentLevel::kSignin); + auto capability = + account_info.capabilities.is_subject_to_enterprise_policies(); + return capability == signin::Tribool::kTrue; +} + +#if BUILDFLAG(IS_ANDROID) +void PrivacySandboxSettingsDelegate::OverrideWebappRegistryForTesting( + std::unique_ptr<WebappRegistry> webapp_registry) { + DCHECK(webapp_registry); + webapp_registry_ = std::move(webapp_registry); +} +#endif
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h index d017b690..9272edc 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h
@@ -5,11 +5,19 @@ #ifndef CHROME_BROWSER_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_DELEGATE_H_ #define CHROME_BROWSER_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_DELEGATE_H_ +#include <memory> + #include "base/memory/raw_ptr.h" +#include "build/build_config.h" +#include "build/buildflag.h" #include "components/privacy_sandbox/privacy_sandbox_settings.h" class Profile; +#if BUILDFLAG(IS_ANDROID) +class WebappRegistry; +#endif + class PrivacySandboxSettingsDelegate : public privacy_sandbox::PrivacySandboxSettings::Delegate { public: @@ -22,10 +30,22 @@ bool IsIncognitoProfile() const override; bool HasAppropriateTopicsConsent() const override; bool IsSubjectToM1NoticeRestricted() const override; + bool IsCookieDeprecationExperimentEligible() const override; + bool IsCookieDeprecationExperimentCurrentlyEligible() const override; + +#if BUILDFLAG(IS_ANDROID) + void OverrideWebappRegistryForTesting( + std::unique_ptr<WebappRegistry> webapp_registry); +#endif private: bool PrivacySandboxRestrictedNoticeRequired() const; + bool IsSubjectToEnterprisePolicies() const; raw_ptr<Profile> profile_; + +#if BUILDFLAG(IS_ANDROID) + std::unique_ptr<WebappRegistry> webapp_registry_; +#endif }; #endif // CHROME_BROWSER_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_DELEGATE_H_
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc index 13d3e08..185489a5 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc
@@ -3,17 +3,37 @@ // found in the LICENSE file. #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h" + +#include <memory> +#include <string> +#include <vector> + #include "base/test/scoped_feature_list.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "build/buildflag.h" +#include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/browser/supervised_user/supervised_user_test_util.h" +#include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/browser/cookie_settings.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/pref_names.h" +#include "components/metrics/metrics_pref_names.h" #include "components/privacy_sandbox/privacy_sandbox_features.h" #include "components/privacy_sandbox/privacy_sandbox_prefs.h" #include "components/signin/public/identity_manager/account_capabilities_test_mutator.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/android/webapps/webapp_registry.h" +#endif namespace { @@ -233,3 +253,189 @@ EXPECT_TRUE(delegate()->IsPrivacySandboxRestricted()); EXPECT_FALSE(delegate()->IsPrivacySandboxCurrentlyUnrestricted()); } + +namespace { + +const base::Time kCurrentTime = base::Time::Now(); +const base::Time kValidInstallDate = kCurrentTime - base::Days(31); + +#if BUILDFLAG(IS_ANDROID) +class MockWebappRegistry : public WebappRegistry { + public: + // WebappRegistry: + MOCK_METHOD(std::vector<std::string>, + GetOriginsWithInstalledApp, + (), + (override)); +}; +#endif + +struct CookieDeprecationExperimentEligibilityTestCase { + absl::optional<bool> is_subject_to_enterprise_policies; + content_settings::CookieControlsMode cookie_controls_mode_pref = + content_settings::CookieControlsMode::kOff; + ContentSetting cookie_content_setting = ContentSetting::CONTENT_SETTING_ALLOW; + bool privacy_sandbox_eea_notice_acknowledged_pref = false; + bool privacy_sandbox_row_notice_acknowledged_pref = false; + absl::optional<bool> cookie_deprecation_eligible_pref; + absl::optional<base::Time> install_date = kValidInstallDate; +#if BUILDFLAG(IS_ANDROID) + std::vector<std::string> origins_with_installed_app; +#endif + bool expected_eligible; + bool expected_currently_eligible; +}; + +const CookieDeprecationExperimentEligibilityTestCase + kCookieDeprecationExperimentEligibilityTestCases[] = { + { + .expected_eligible = false, + .expected_currently_eligible = false, + }, + { + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .expected_eligible = true, + .expected_currently_eligible = true, + }, + { + .privacy_sandbox_row_notice_acknowledged_pref = true, + .expected_eligible = true, + .expected_currently_eligible = true, + }, + { + .cookie_controls_mode_pref = + content_settings::CookieControlsMode::kBlockThirdParty, + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .expected_eligible = false, + .expected_currently_eligible = false, + }, + { + .cookie_content_setting = ContentSetting::CONTENT_SETTING_BLOCK, + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .expected_eligible = false, + .expected_currently_eligible = false, + }, + { + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .install_date = absl::nullopt, + .expected_eligible = false, + .expected_currently_eligible = false, + }, + { + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .install_date = kCurrentTime - base::Days(29), + .expected_eligible = false, + .expected_currently_eligible = false, + }, + { + .cookie_deprecation_eligible_pref = true, + .expected_eligible = true, + .expected_currently_eligible = false, + }, + { + .is_subject_to_enterprise_policies = true, + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .expected_eligible = false, + .expected_currently_eligible = false, + }, + { + .is_subject_to_enterprise_policies = false, + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .expected_eligible = true, + .expected_currently_eligible = true, + }, +#if BUILDFLAG(IS_ANDROID) + { + .privacy_sandbox_eea_notice_acknowledged_pref = true, + .origins_with_installed_app = + std::vector<std::string>({"https://a.test"}), + .expected_eligible = false, + .expected_currently_eligible = false, + }, +#endif +}; + +class CookieDeprecationExperimentEligibilityTest + : public PrivacySandboxSettingsDelegateTest, + public ::testing::WithParamInterface< + CookieDeprecationExperimentEligibilityTestCase> { + public: + CookieDeprecationExperimentEligibilityTest() + : local_state_(TestingBrowserProcess::GetGlobal()) { +#if BUILDFLAG(IS_ANDROID) + auto webapp_registry = std::make_unique<MockWebappRegistry>(); + webapp_registry_ = webapp_registry.get(); + delegate()->OverrideWebappRegistryForTesting(std::move(webapp_registry)); +#endif + } + + protected: + content_settings::CookieSettings* cookie_settings() { + return CookieSettingsFactory::GetForProfile(profile()).get(); + } + + void SetSubjectToEnterprisePoliciesCapability(const std::string& account, + bool enabled) { + auto account_info = identity_test_env() + ->identity_manager() + ->FindExtendedAccountInfoByEmailAddress(kTestEmail); + AccountCapabilitiesTestMutator mutator(&account_info.capabilities); + mutator.set_is_subject_to_enterprise_policies(enabled); + signin::UpdateAccountInfoForAccount(identity_test_env()->identity_manager(), + account_info); + } + + ScopedTestingLocalState local_state_; +#if BUILDFLAG(IS_ANDROID) + raw_ptr<MockWebappRegistry> webapp_registry_; +#endif +}; + +} // namespace + +TEST_P(CookieDeprecationExperimentEligibilityTest, IsEligible) { + const CookieDeprecationExperimentEligibilityTestCase& test_case = GetParam(); + + if (test_case.is_subject_to_enterprise_policies.has_value()) { + // Sign the user in. + identity_test_env()->MakePrimaryAccountAvailable( + kTestEmail, signin::ConsentLevel::kSignin); + SetSubjectToEnterprisePoliciesCapability( + kTestEmail, *test_case.is_subject_to_enterprise_policies); + } + + prefs()->SetInteger(prefs::kCookieControlsMode, + static_cast<int>(test_case.cookie_controls_mode_pref)); + prefs()->SetBoolean(prefs::kPrivacySandboxM1RowNoticeAcknowledged, + test_case.privacy_sandbox_row_notice_acknowledged_pref); + prefs()->SetBoolean(prefs::kPrivacySandboxM1EEANoticeAcknowledged, + test_case.privacy_sandbox_eea_notice_acknowledged_pref); + + cookie_settings()->SetDefaultCookieSetting(test_case.cookie_content_setting); + + if (test_case.install_date.has_value()) { + local_state_.Get()->SetInt64(metrics::prefs::kInstallDate, + test_case.install_date->ToTimeT()); + } + + if (test_case.cookie_deprecation_eligible_pref.has_value()) { + prefs()->SetBoolean( + prefs::kPrivacySandboxCookieDeprecationExperimentEligible, + *test_case.cookie_deprecation_eligible_pref); + } + +#if BUILDFLAG(IS_ANDROID) + ON_CALL(*webapp_registry_, GetOriginsWithInstalledApp) + .WillByDefault(testing::Return(test_case.origins_with_installed_app)); +#endif + + EXPECT_EQ(delegate()->IsCookieDeprecationExperimentCurrentlyEligible(), + test_case.expected_currently_eligible); + EXPECT_EQ(delegate()->IsCookieDeprecationExperimentEligible(), + test_case.expected_eligible); +} + +INSTANTIATE_TEST_SUITE_P( + CookieDeprecationExperimentEligibility, + CookieDeprecationExperimentEligibilityTest, + ::testing::ValuesIn(kCookieDeprecationExperimentEligibilityTestCases));
diff --git a/chrome/browser/profiles/delete_profile_helper.cc b/chrome/browser/profiles/delete_profile_helper.cc index a19d09b..e74daf7 100644 --- a/chrome/browser/profiles/delete_profile_helper.cc +++ b/chrome/browser/profiles/delete_profile_helper.cc
@@ -234,6 +234,9 @@ << profile_path->AsUTF8Unsafe(); SCOPED_CRASH_KEY_STRING256("DeleteProfileHelper", "profile_path", profile_path->AsUTF8Unsafe()); + SCOPED_CRASH_KEY_STRING256( + "DeleteProfileHelper", "user_data_dir", + profile_manager_->user_data_dir().AsUTF8Unsafe()); SCOPED_CRASH_KEY_BOOL( "DeleteProfileHelper", "allowed_path", profile_manager_->IsAllowedProfilePath(*profile_path));
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_button.html b/chrome/browser/resources/chromeos/login/components/gaia_button.html index fb62ba9..23ec25ed 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_button.html +++ b/chrome/browser/resources/chromeos/login/components/gaia_button.html
@@ -15,20 +15,18 @@ that looks more like a link. 'disabled' - button is disabled when the attribute is set. --> -<style> +<style include="cros-color-overrides"> :host { display: inline-block; } - :host([link]) cr-button { - background-color: transparent; - border: none; - border-radius: 0; - box-shadow: none; - color: var(--cros-link-color); - font-weight: 400; - margin: 0 -0.57em; - min-width: 0; + cr-button#button { + --cr-button-height: var(--oobe-button-height); + border-radius: var(--oobe-button-radius); + font-family: var(--oobe-button-font-family); + font-size: var(--oobe-button-font-size); + font-weight: var(--oobe-button-font-weight); + line-height: var(--oobe-button-line-height); } :host([link]) cr-button:focus { @@ -47,4 +45,3 @@ noink$="[[link]]"> <slot></slot> </cr-button> -
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_button.js b/chrome/browser/resources/chromeos/login/components/gaia_button.js index d791a47..7d18a1d 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_button.js +++ b/chrome/browser/resources/chromeos/login/components/gaia_button.js
@@ -6,6 +6,7 @@ * @fileoverview Polymer element wrapping gaia styled button for login/oobe. */ +import '//resources/cr_elements/chromeos/cros_color_overrides.css.js'; import '//resources/cr_elements/cr_button/cr_button.js'; import '//resources/polymer/v3_0/paper-styles/color.js';
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_dialog.html b/chrome/browser/resources/chromeos/login/components/gaia_dialog.html index 90eb022..a9324cd 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_dialog.html +++ b/chrome/browser/resources/chromeos/login/components/gaia_dialog.html
@@ -34,10 +34,6 @@ padding-inline-start: 10px; } - #saml-notice-message { - font-size: 13px; - } - #signin-frame { display: flex; overflow: hidden; @@ -82,7 +78,7 @@ } #sshWarning { - color: var(--google-red-600); + color: var(--cros-sys-error); text-align: center; }
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_header.html b/chrome/browser/resources/chromeos/login/components/gaia_header.html index 410ef7fdd..f3309c4 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_header.html +++ b/chrome/browser/resources/chromeos/login/components/gaia_header.html
@@ -24,10 +24,13 @@ } #email { - font-size: 20px; + font-family: var(--oobe-subheader-font-family); + font-size: var(--oobe-subheader-font-size); + font-weight: var(--oobe-subheader-font-weight); + line-height: var(--oobe-subheader-line-height); + margin-top: 5px; } </style> <img src="chrome://theme/IDR_LOGO_AVATAR_CIRCLE_BLUE_COLOR" alt class="self-start"> <div id="email"><span>[[email]]<span></div> -
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_input_form.html b/chrome/browser/resources/chromeos/login/components/gaia_input_form.html index 4c4c368..25f9ab7c 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_input_form.html +++ b/chrome/browser/resources/chromeos/login/components/gaia_input_form.html
@@ -4,10 +4,9 @@ found in the LICENSE file. --> -<style include="oobe-common-styles"> +<style include="oobe-common-styles cros-color-overrides"> :host { display: block; - font-size: 16px; } :host ::slotted(gaia-input) {
diff --git a/chrome/browser/resources/chromeos/login/components/gaia_input_form.js b/chrome/browser/resources/chromeos/login/components/gaia_input_form.js index ef29361..447e78c 100644 --- a/chrome/browser/resources/chromeos/login/components/gaia_input_form.js +++ b/chrome/browser/resources/chromeos/login/components/gaia_input_form.js
@@ -24,6 +24,7 @@ * */ +import '//resources/cr_elements/chromeos/cros_color_overrides.css.js'; import './common_styles/oobe_common_styles.css.js'; import './gaia_button.js';
diff --git a/chrome/browser/resources/chromeos/login/components/notification_card.html b/chrome/browser/resources/chromeos/login/components/notification_card.html index 7b77bb9c..62afefe 100644 --- a/chrome/browser/resources/chromeos/login/components/notification_card.html +++ b/chrome/browser/resources/chromeos/login/components/notification_card.html
@@ -31,15 +31,17 @@ } :host iron-icon { - color: var(--cros-icon-color-warning); + color: var(--cros-sys-warning); height: 28px; width: 28px; } #text-container { - /* TODO(https://crbug.com/1320715) Revise the color */ - color: var(--cros-text-color-primary); - line-height: 130%; + color: var(--oobe-text-color); + font-family: var(--oobe-default-font-family); + font-size: var(--oobe-default-font-size); + font-weight: var(--oobe-default-font-weight); + line-height: var(--oobe-default-line-height); max-width: 240px; text-align: center; }
diff --git a/chrome/browser/resources/chromeos/login/screens/common/sync_consent.html b/chrome/browser/resources/chromeos/login/screens/common/sync_consent.html index 27c44cd..8757d67 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/sync_consent.html +++ b/chrome/browser/resources/chromeos/login/screens/common/sync_consent.html
@@ -246,7 +246,7 @@ <iron-icon icon="oobe-illos:sync-consent-illo" class="illustration-jelly"> </iron-icon> </div> - <div class="bottom-buttons" slot="bottom-buttons" hidden="[[isMinorMode_]]"> + <div slot="bottom-buttons" hidden="[[isMinorMode_]]"> <oobe-text-button id="manageButtonRegularUser" on-click="onManageClicked_" label-for-aria="[[i18nDynamic(locale, 'syncConsentScreenManage')]]"> @@ -254,16 +254,14 @@ [[i18nDynamic(locale, 'syncConsentScreenManage')]] </div> </oobe-text-button> - <div id="rightButtons"> - <oobe-text-button class="focus-on-show" inverse - id="syncEverythingButton" - on-click="onSyncEverything_" - label-for-aria="[[i18nDynamic(locale, 'syncConsentTurnOnSync')]]"> - <div slot="text" consent-description consent-confirmation> - [[i18nDynamic(locale, 'syncConsentTurnOnSync')]] - </div> - </oobe-text-button> - </div> + <oobe-text-button class="focus-on-show" inverse + id="syncEverythingButton" + on-click="onSyncEverything_" + label-for-aria="[[i18nDynamic(locale, 'syncConsentTurnOnSync')]]"> + <div slot="text" consent-description consent-confirmation> + [[i18nDynamic(locale, 'syncConsentTurnOnSync')]] + </div> + </oobe-text-button> </div> <div class="bottom-buttons" slot="bottom-buttons" hidden="[[!isMinorMode_]]"> <oobe-text-button id="manageButtonMinorUser"
diff --git a/chrome/browser/resources/chromeos/login/screens/login/offline_login.html b/chrome/browser/resources/chromeos/login/screens/login/offline_login.html index bfa0854..f6253ec1 100644 --- a/chrome/browser/resources/chromeos/login/screens/login/offline_login.html +++ b/chrome/browser/resources/chromeos/login/screens/login/offline_login.html
@@ -45,8 +45,11 @@ } #forgotPasswordDlg::part(dialog) { - color: var(--primary-text-color); - font-size: 15px; + color: var(--oobe-text-color); + font-family: var(--oobe-default-font-family); + font-size: var(--oobe-default-font-size); + font-weight: var(--oobe-default-font-weight); + line-height: var(--oobe-default-line-height); width: 384px; } @@ -185,6 +188,14 @@ oobe-content-dialog[animation-in-progress] .section { display: block; } + + #forgotPasswordDlg cr-button.action-button { + border-radius: var(--oobe-button-radius); + font-family: var(--oobe-button-font-family); + font-size: var(--oobe-button-font-size); + font-weight: var(--oobe-button-font-weight); + line-height: var(--oobe-button-line-height); + } </style> <oobe-content-dialog role="dialog" selected$="[[activeSection]]" id="dialog" no-footer-padding
diff --git a/chrome/browser/resources/downloads/item.html b/chrome/browser/resources/downloads/item.html index 329e29b..4fda13f8e 100644 --- a/chrome/browser/resources/downloads/item.html +++ b/chrome/browser/resources/downloads/item.html
@@ -349,7 +349,7 @@ description-color$="[[iconAndDescriptionColor_(displayType_, improvedDownloadWarningsUx_)]]" hidden$="[[!computeDescriptionVisible_(data.*, displayType_, - updateDeepScanningUx_, improvedDownloadWarningsUx_)]"> + updateDeepScanningUx_, improvedDownloadWarningsUx_)]]"> [[computeDescription_( data.state, data.dangerType,
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/cart/cart_tile.html b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/cart/cart_tile.html index fbe37f6..7d7dc2e 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/cart/cart_tile.html +++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/cart/cart_tile.html
@@ -4,7 +4,7 @@ border-radius: var(--ntp-module-item-border-radius); display: inline-flex; height: 100%; - overflow: hidden; + min-width: 0; width: 100%; }
diff --git a/chrome/browser/resources/new_tab_page/realbox/realbox.html b/chrome/browser/resources/new_tab_page/realbox/realbox.html index fc3eab4..d0dccb9a 100644 --- a/chrome/browser/resources/new_tab_page/realbox/realbox.html +++ b/chrome/browser/resources/new_tab_page/realbox/realbox.html
@@ -211,11 +211,16 @@ top: 0; z-index: 99; } + + .truncate { + overflow: hidden; + text-overflow: ellipsis; + } </style> <div id="inputWrapper" on-focusout=onInputWrapperFocusout_ on-keydown="onInputWrapperKeydown_"> - <input id="input" type="search" autocomplete="off" spellcheck="false" - aria-live="[[inputAriaLive_]]" role="combobox" + <input id="input" class="truncate" type="search" autocomplete="off" + spellcheck="false" aria-live="[[inputAriaLive_]]" role="combobox" aria-expanded="[[dropdownIsVisible]]" aria-controls="matches" placeholder="$i18n{searchBoxHint}" on-copy="onInputCutCopy_" on-cut="onInputCutCopy_" on-focus="onInputFocus_"
diff --git a/chrome/browser/resources/settings/privacy_page/cookies_page.html b/chrome/browser/resources/settings/privacy_page/cookies_page.html index f0642f2..c0a87b5 100644 --- a/chrome/browser/resources/settings/privacy_page/cookies_page.html +++ b/chrome/browser/resources/settings/privacy_page/cookies_page.html
@@ -86,6 +86,11 @@ padding-bottom: 12px; } + #firstPartySetsToggle { + padding-inline-end: 0; + padding-inline-start: 0; + } + #toastText { align-items: center; display: flex; @@ -227,7 +232,9 @@ $i18n{thirdPartyCookiesPageBlockBulTwo} </div> </div> - <template is="dom-if" if="[[enableFirstPartySetsUI_]]"> + </div> + <template is="dom-if" if="[[enableFirstPartySetsUI_]]"> + <div slot="noSelectionCollapse"> <settings-toggle-button id="firstPartySetsToggle" pref="{{prefs.privacy_sandbox.first_party_sets_enabled}}" @@ -236,8 +243,8 @@ disabled="[[firstPartySetsToggleDisabled_( prefs.profile.cookie_controls_mode.value)]]"> </settings-toggle-button> - </template> - </div> + </div> + </template> </settings-collapse-radio-button> </settings-radio-group> </div> @@ -304,17 +311,19 @@ <iron-icon icon="settings:block"></iron-icon> <div class="secondary">$i18n{cookiePageBlockThirdBulTwo}</div> </div> - <template is="dom-if" if="[[enableFirstPartySetsUI_]]"> + </div> + <template is="dom-if" if="[[enableFirstPartySetsUI_]]"> + <div slot="noSelectionCollapse"> <settings-toggle-button id="firstPartySetsToggle" pref="{{prefs.privacy_sandbox.first_party_sets_enabled}}" label="$i18n{cookiePageFpsLabel}" sub-label="$i18n{cookiePageFpsSubLabel}" disabled="[[firstPartySetsToggleDisabled_( - prefs.generated.cookie_primary_setting.value)]]"> + prefs.profile.cookie_controls_mode.value)]]"> </settings-toggle-button> - </template> - </div> + </div> + </template> </settings-collapse-radio-button> <settings-collapse-radio-button id="blockAll" pref="[[blockAllPref_]]"
diff --git a/chrome/browser/resources/side_panel/read_anything/app.html b/chrome/browser/resources/side_panel/read_anything/app.html index 0b5060e..665402d 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.html +++ b/chrome/browser/resources/side_panel/read_anything/app.html
@@ -55,7 +55,7 @@ /* TODO(crbug.com/1474951): These are placeholder colors. Use the UX colors once they're finalized. Also, allow user selection for highlight color. */ .current-read-highlight { - background-color: var(--google-yellow-400); + background-color: var(--current-highlight-bg-color); } .previous-read-highlight { color: var(--google-grey-600);
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index 7a3c11c6..f981bb2 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -773,6 +773,15 @@ }); } + updateHighlight(show: boolean) { + // TODO(crbug.com/1474951): This is a placeholder color. Use the UX color + // once finalized. + this.updateStyles({ + '--current-highlight-bg-color': show ? 'var(--google-yellow-400)' : + 'transparent', + }); + } + // TODO(crbug.com/1465029): This method should be renamed to updateTheme() // and replace the one below once we've removed the Views toolbar. updateThemeFromWebUi(colorSuffix: string) {
diff --git a/chrome/browser/resources/side_panel/read_anything/icons.html b/chrome/browser/resources/side_panel/read_anything/icons.html index 791ade7..8acf6f3aa 100644 --- a/chrome/browser/resources/side_panel/read_anything/icons.html +++ b/chrome/browser/resources/side_panel/read_anything/icons.html
@@ -84,13 +84,12 @@ <g id="highlight-off" viewBox="0 0 14 12"> <path d="M8.13334 7.16669L6.63334 5.65002L3.41667 8.86669L4.93334 10.3834L8.13334 7.16669ZM7.50001 4.78336L9.00001 6.30002L12.2 3.10002L10.7 1.58336L7.50001 4.78336ZM6.21667 4.38336L9.41667 7.58336L5.78334 11.2167C5.5389 11.4389 5.25556 11.5611 4.93334 11.5834C4.62223 11.5945 4.35556 11.4889 4.13334 11.2667L3.80001 11.6H0.600006L2.53334 9.66669C2.30001 9.44447 2.18889 9.17225 2.20001 8.85003C2.21112 8.51669 2.3389 8.23891 2.58334 8.01669L6.21667 4.38336ZM6.21667 4.38336L9.85001 0.750024C10.0833 0.516691 10.3667 0.400024 10.7 0.400024C11.0333 0.400024 11.3167 0.516691 11.55 0.750024L13.05 2.25002C13.2722 2.49447 13.3833 2.7778 13.3833 3.10002C13.3833 3.42225 13.2722 3.70558 13.05 3.95002L9.41667 7.58336L6.21667 4.38336Z"></path> </g> - <g id="previous" viewBox="0 -960 960 960"> - <path d="M220-240v-480h80v480h-80Zm520 0L380-480l360-240v480Zm-80-240Zm0 90v-180l-136 90 136 90Z"></path> + <g id="previous" viewBox="0 0 16 16"> + <path d="M3.75 12.25V3.75H5.13333V12.25H3.75ZM12.25 11.85L6.26667 8L12.25 4.15V11.85ZM10.8667 9.3V6.7L8.81667 8L10.8667 9.3Z"></path> </g> - <g id="next" viewBox="0 -960 960 960"> - <path d="M660-240v-480h80v480h-80Zm-440 0v-480l360 240-360 240Zm80-240Zm0 90 136-90-136-90v180Z"></path> + <g id="next" viewBox="0 0 16 16"> + <path d="M10.8667 12.25V3.75H12.25V12.25H10.8667ZM3.75 11.85V4.15L9.73333 8L3.75 11.85ZM5.13333 9.3L7.18333 8L5.13333 6.7V9.3Z"></path> </g> - </defs> </svg> </iron-iconset-svg> <iron-iconset-svg name="read-anything-20" size="20">
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts index 0035cca..03987c7 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
@@ -36,6 +36,7 @@ // Current audio settings values. let speechRate: number; + let highlightGranularity: number; // Enum values for various visual theme changes. let standardLineSpacing: number; @@ -49,6 +50,7 @@ let darkTheme: number; let yellowTheme: number; let blueTheme: number; + let highlightOn: number; // Whether the WebUI toolbar feature flag is enabled. let isWebUIToolbarVisible: boolean; @@ -137,6 +139,10 @@ // Called when the speech rate is changed via the webui toolbar. function onSpeechRateChange(rate: number): void; + // Called when the highlight granularity is changed via the webui toolbar. + function turnedHighlightOn(): void; + function turnedHighlightOff(): void; + // Returns the actual spacing value to use based on the given lineSpacing // category. function getLineSpacingValue(lineSpacing: number): number;
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html index 70df320b..c6e6ca3 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html +++ b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html
@@ -21,6 +21,12 @@ :host-context([chrome-refresh-2023]) .dropdown-item:focus { background-color: var(--cr-hover-background-color); } + :host-context([chrome-refresh-2023]) #audio-controls { + background: var(--audio-controls-background); + border-radius: 18px; + padding: 8px 0px; + margin-left: 8px; + } .dropdown-item { display: block; } @@ -47,22 +53,22 @@ </style> <div class="toolbar-container"> <span id="read-aloud-container" hidden="[[!isReadAloudEnabled_]]"> - <cr-icon-button - id="play-pause" - iron-icon="read-anything-20:play" - on-click="onPlayPauseClick_"> - </cr-icon-button> - <!--TODO(crbug.com/1474951): Make the granularity container styled so it - matches the mocks. --> - <span id="granularity-container" hidden="[[isPaused_]]"> - <cr-icon-button id="previousGranularity" - iron-icon="read-anything:previous" + <span id="audio-controls"> + <cr-icon-button + id="play-pause" + iron-icon="read-anything-20:play" + on-click="onPlayPauseClick_"> + </cr-icon-button> + <span id="granularity-container" hidden="[[isPaused_]]"> + <cr-icon-button id="previousGranularity" + iron-icon="read-anything:previous" on-click="onPreviousGranularityClick_"> - </cr-icon-button> - <cr-icon-button id="nextGranularity" - iron-icon="read-anything:next" + </cr-icon-button> + <cr-icon-button id="nextGranularity" + iron-icon="read-anything:next" on-click="onNextGranularityClick_"> - </cr-icon-button> + </cr-icon-button> + </span> </span> <cr-icon-button id="rate"
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts index d79a843..05d93e8 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts
@@ -198,6 +198,10 @@ this.setRateIcon_(speechRate); this.setCheckMarkForMenu_( this.$.rateMenu, this.rateOptions_.indexOf(speechRate)); + + this.setHighlightState_( + chrome.readingMode.highlightGranularity === + chrome.readingMode.highlightOn); } this.setCheckMarkForMenu_( this.$.fontMenu, @@ -239,6 +243,10 @@ assert(button); button.setAttribute('iron-icon', 'read-anything-20:pause'); this.isPaused_ = false; + + this.updateStyles({ + '--audio-controls-background': 'var(--color-sys-tonal-container)', + }); } updateUiForPausing() { @@ -248,6 +256,10 @@ assert(button); button.setAttribute('iron-icon', 'read-anything-20:play'); this.isPaused_ = true; + + this.updateStyles({ + '--audio-controls-background': 'transparent', + }); } private closeMenus_() { @@ -312,13 +324,29 @@ const button = shadowRoot.getElementById('highlight'); assert(button); if (this.isHighlightOn_) { - this.isHighlightOn_ = false; - button.setAttribute('iron-icon', 'read-anything:highlight-off'); - button.setAttribute('title', loadTimeData.getString('turnHighlightOn')); + chrome.readingMode.turnedHighlightOff(); } else { - this.isHighlightOn_ = true; + chrome.readingMode.turnedHighlightOn(); + } + this.setHighlightState_(!this.isHighlightOn_); + } + + private setHighlightState_(turnOn: boolean) { + const shadowRoot = this.shadowRoot; + assert(shadowRoot); + const button = shadowRoot.getElementById('highlight'); + assert(button); + this.isHighlightOn_ = turnOn; + if (this.isHighlightOn_) { button.setAttribute('iron-icon', 'read-anything:highlight-on'); button.setAttribute('title', loadTimeData.getString('turnHighlightOff')); + } else { + button.setAttribute('iron-icon', 'read-anything:highlight-off'); + button.setAttribute('title', loadTimeData.getString('turnHighlightOn')); + } + + if (this.contentPage) { + this.contentPage.updateHighlight(this.isHighlightOn_); } }
diff --git a/chrome/browser/safe_browsing/android/javatests/src/org/chromium/chrome/browser/safe_browsing/settings/StandardProtectionSettingsFragmentTest.java b/chrome/browser/safe_browsing/android/javatests/src/org/chromium/chrome/browser/safe_browsing/settings/StandardProtectionSettingsFragmentTest.java index f0ac9c3..8be0bba8 100644 --- a/chrome/browser/safe_browsing/android/javatests/src/org/chromium/chrome/browser/safe_browsing/settings/StandardProtectionSettingsFragmentTest.java +++ b/chrome/browser/safe_browsing/android/javatests/src/org/chromium/chrome/browser/safe_browsing/settings/StandardProtectionSettingsFragmentTest.java
@@ -114,7 +114,8 @@ @Test @SmallTest @Feature({"SafeBrowsing"}) - public void testSwitchPasswordLeakDetectionPreference() { + @DisableFeatures(ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_STANDARD_PROTECTION) + public void testSwitchPasswordLeakDetectionPreferenceOriginal() { mBrowserTestRule.addTestAccountThenSigninAndEnableSync(); TestThreadUtils.runOnUiThreadBlocking(() -> { SafeBrowsingBridge.setSafeBrowsingState(SafeBrowsingState.STANDARD_PROTECTION); @@ -148,7 +149,46 @@ @Test @SmallTest @Feature({"SafeBrowsing"}) - public void testPasswordLeakDetectionPreferenceEnabledForSignedOutUsers() { + @EnableFeatures(ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_STANDARD_PROTECTION) + public void testSwitchPasswordLeakDetectionPreference() { + mBrowserTestRule.addTestAccountThenSigninAndEnableSync(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + SafeBrowsingBridge.setSafeBrowsingState(SafeBrowsingState.STANDARD_PROTECTION); + }); + launchSettingsActivity(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + StandardProtectionSettingsFragment fragment = mTestRule.getFragment(); + boolean is_password_leak_detection_enabled = + getPrefService().getBoolean(Pref.PASSWORD_LEAK_DETECTION_ENABLED); + String checked_state_error_message = + ASSERT_MESSAGE_PREFIX + LEAK_DETECTION + CHECKED_STATE; + String enabled_state_error_message = + ASSERT_MESSAGE_PREFIX + LEAK_DETECTION + ENABLED_STATE; + String password_leak_detection_summary = fragment.getContext().getString( + R.string.passwords_leak_detection_switch_summary); + Assert.assertEquals(checked_state_error_message, is_password_leak_detection_enabled, + mPasswordLeakDetectionPreference.isChecked()); + Assert.assertTrue( + enabled_state_error_message, mPasswordLeakDetectionPreference.isEnabled()); + Assert.assertEquals( + password_leak_detection_summary, mPasswordLeakDetectionPreference.getSummary()); + + mPasswordLeakDetectionPreference.performClick(); + + Assert.assertEquals(checked_state_error_message, !is_password_leak_detection_enabled, + mPasswordLeakDetectionPreference.isChecked()); + Assert.assertEquals(enabled_state_error_message + FROM_NATIVE, + !is_password_leak_detection_enabled, + getPrefService().getBoolean(Pref.PASSWORD_LEAK_DETECTION_ENABLED)); + }); + } + + @Test + @SmallTest + @Feature({"SafeBrowsing"}) + @DisableFeatures(ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_STANDARD_PROTECTION) + public void testPasswordLeakDetectionPreferenceEnabledForSignedOutUsersOriginal() { TestThreadUtils.runOnUiThreadBlocking(() -> { SafeBrowsingBridge.setSafeBrowsingState(SafeBrowsingState.STANDARD_PROTECTION); }); @@ -183,6 +223,43 @@ @Test @SmallTest @Feature({"SafeBrowsing"}) + @EnableFeatures(ChromeFeatureList.FRIENDLIER_SAFE_BROWSING_SETTINGS_STANDARD_PROTECTION) + public void testPasswordLeakDetectionPreferenceEnabledForSignedOutUsers() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + SafeBrowsingBridge.setSafeBrowsingState(SafeBrowsingState.STANDARD_PROTECTION); + }); + launchSettingsActivity(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + StandardProtectionSettingsFragment fragment = mTestRule.getFragment(); + boolean is_password_leak_detection_enabled = + getPrefService().getBoolean(Pref.PASSWORD_LEAK_DETECTION_ENABLED); + String checked_state_error_message = + ASSERT_MESSAGE_PREFIX + LEAK_DETECTION + CHECKED_STATE; + String enabled_state_error_message = + ASSERT_MESSAGE_PREFIX + LEAK_DETECTION + ENABLED_STATE; + String password_leak_detection_summary = fragment.getContext().getString( + R.string.passwords_leak_detection_switch_summary); + Assert.assertEquals(checked_state_error_message, is_password_leak_detection_enabled, + mPasswordLeakDetectionPreference.isChecked()); + Assert.assertTrue( + enabled_state_error_message, mPasswordLeakDetectionPreference.isEnabled()); + Assert.assertEquals( + password_leak_detection_summary, mPasswordLeakDetectionPreference.getSummary()); + + mPasswordLeakDetectionPreference.performClick(); + + Assert.assertEquals(checked_state_error_message, !is_password_leak_detection_enabled, + mPasswordLeakDetectionPreference.isChecked()); + Assert.assertEquals(enabled_state_error_message + FROM_NATIVE, + !is_password_leak_detection_enabled, + getPrefService().getBoolean(Pref.PASSWORD_LEAK_DETECTION_ENABLED)); + }); + } + + @Test + @SmallTest + @Feature({"SafeBrowsing"}) public void testPreferencesDisabledInEnhancedProtectionMode() { mBrowserTestRule.addTestAccountThenSigninAndEnableSync(); TestThreadUtils.runOnUiThreadBlocking(() -> {
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc index d189f12..9e5f6fd 100644 --- a/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc +++ b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc
@@ -239,6 +239,18 @@ std::vector<std::string>(1, kSearchUserModelLabelNone)); } +TEST_F(SegmentationPlatformServiceFactoryTest, TestShoppingUserModel) { + InitServiceAndCacheResults(kShoppingUserSegmentationKey); + + PredictionOptions prediction_options; + + ExpectGetClassificationResult( + kShoppingUserSegmentationKey, prediction_options, nullptr, + /*expected_status=*/PredictionStatus::kSucceeded, + /*expected_labels=*/ + std::vector<std::string>(1, kLegacyNegativeLabel)); +} + TEST_F(SegmentationPlatformServiceFactoryTest, TestDeviceSwitcherModel) { InitService();
diff --git a/chrome/browser/supervised_user/BUILD.gn b/chrome/browser/supervised_user/BUILD.gn index 0fb4ce3..8d36e27 100644 --- a/chrome/browser/supervised_user/BUILD.gn +++ b/chrome/browser/supervised_user/BUILD.gn
@@ -161,6 +161,8 @@ "//chrome/browser/supervised_user:supervised_user_metrics_java", "//chrome/browser/supervised_user:website_parent_approval_java", "//chrome/browser/tab:java", + "//chrome/browser/ui/android/appmenu:java", + "//chrome/browser/ui/android/appmenu/test:test_support_java", "//chrome/test/android:chrome_java_integration_test_support", "//chrome/test/android:pagecontroller_utils_java", "//components/browser_ui/bottomsheet/android:java",
diff --git a/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/SupervisedUserCriticalJourneysIntegrationTest.java b/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/SupervisedUserCriticalJourneysIntegrationTest.java index 33ce4ad..be449ae 100644 --- a/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/SupervisedUserCriticalJourneysIntegrationTest.java +++ b/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/SupervisedUserCriticalJourneysIntegrationTest.java
@@ -4,6 +4,16 @@ package org.chromium.chrome.browser.supervised_user; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.longClick; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isClickable; +import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static org.hamcrest.Matchers.not; + import androidx.test.filters.LargeTest; import org.junit.Assert; @@ -14,9 +24,11 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.ui.appmenu.AppMenuTestSupport; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.browser.signin.SigninTestRule; @@ -67,4 +79,22 @@ WebsiteParentApprovalTestUtils.checkLocalApprovalsButtonIsVisible(mWebContents); WebsiteParentApprovalTestUtils.checkRemoteApprovalsButtonIsVisible(mWebContents); } + + @Test + @LargeTest + public void incognitoModeIsUnavailableFromAppMenu() throws InterruptedException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false); + }); + onView(withText(R.string.menu_new_incognito_tab)).check(matches(not(isEnabled()))); + onView(withText(R.string.menu_new_incognito_tab)).check(matches(not(isClickable()))); + } + + @Test + @LargeTest + public void incognitoModeIsUnavailableFromTabSwitcherActionMenu() { + onView(withId(R.id.tab_switcher_button)).perform(longClick()); + onView(withText(R.string.menu_new_incognito_tab)).check(matches(not(isEnabled()))); + onView(withText(R.string.menu_new_incognito_tab)).check(matches(not(isClickable()))); + } }
diff --git a/chrome/browser/sync/test/integration/single_client_reading_list_sync_test.cc b/chrome/browser/sync/test/integration/single_client_reading_list_sync_test.cc index 90ca5d2c..a337c60 100644 --- a/chrome/browser/sync/test/integration/single_client_reading_list_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_reading_list_sync_test.cc
@@ -28,7 +28,8 @@ class ServerReadingListURLsEqualityChecker : public fake_server::FakeServerMatchStatusChecker { public: - explicit ServerReadingListURLsEqualityChecker(std::set<GURL> expected_urls) + explicit ServerReadingListURLsEqualityChecker( + const std::set<GURL>& expected_urls) : expected_urls_(std::move(expected_urls)) {} bool IsExitConditionSatisfied(std::ostream* os) override { @@ -60,6 +61,46 @@ const std::set<GURL> expected_urls_; }; +class LocalReadingListURLsEqualityChecker + : public StatusChangeChecker, + public testing::NiceMock<MockReadingListModelObserver> { + public: + LocalReadingListURLsEqualityChecker(ReadingListModel* model, + const base::flat_set<GURL>& expected_urls) + : model_(model), expected_urls_(std::move(expected_urls)) { + model_->AddObserver(this); + } + + LocalReadingListURLsEqualityChecker( + const LocalReadingListURLsEqualityChecker&) = delete; + LocalReadingListURLsEqualityChecker& operator=( + const LocalReadingListURLsEqualityChecker&) = delete; + + ~LocalReadingListURLsEqualityChecker() override { + model_->RemoveObserver(this); + } + + bool IsExitConditionSatisfied(std::ostream* os) override { + *os << "Waiting for local reading list URLs to match the expected URLs."; + + testing::StringMatchResultListener result_listener; + const bool matches = + ExplainMatchResult(testing::ContainerEq(expected_urls_), + model_->GetKeys(), &result_listener); + *os << result_listener.str(); + return matches; + } + + // ReadingListModelObserver implementation. + void ReadingListDidApplyChanges(ReadingListModel* model) override { + CheckExitCondition(); + } + + private: + const raw_ptr<ReadingListModel> model_; + const base::flat_set<GURL> expected_urls_; +}; + // Checker used to block until the reading set titles on the server match a // given set of expected reading list titles. class ServerReadingListTitlesEqualityChecker @@ -358,13 +399,171 @@ model()->MarkAllForUploadToSyncServerIfNeeded(); - EXPECT_TRUE(ServerReadingListURLsEqualityChecker({{kUrlA, kUrlB}}).Wait()); + EXPECT_TRUE(ServerReadingListURLsEqualityChecker({kUrlA, kUrlB}).Wait()); EXPECT_THAT(model()->size(), Eq(2ul)); GetClient(0)->SignOutPrimaryAccount(); EXPECT_THAT(model()->size(), Eq(0ul)); } +IN_PROC_BROWSER_TEST_F( + SingleClientReadingListSyncTest, + ShouldFilterEntriesWithEmptyUrlUponIncrementalRemoteCreation) { + ASSERT_TRUE(SetupClients()); + + ASSERT_THAT(model()->size(), Eq(0ul)); + + ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount()); + ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); + ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); + EXPECT_TRUE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::READING_LIST)); + + ASSERT_THAT(model()->size(), Eq(0ul)); + + std::unique_ptr<syncer::LoopbackServerEntity> kCorruptEntry = + CreateTestReadingListEntity(GURL("http://CorruptEntry.com/"), + "corrupt_entry_title"); + sync_pb::EntitySpecifics specifics = kCorruptEntry->GetSpecifics(); + // An empty URL makes it an invalid reading list specifics. + *specifics.mutable_reading_list()->mutable_url() = ""; + ASSERT_FALSE(ReadingListEntry::IsSpecificsValid(specifics.reading_list())); + kCorruptEntry->SetSpecifics(specifics); + fake_server_->InjectEntity(std::move(kCorruptEntry)); + + const GURL kUrl("http://url.com/"); + fake_server_->InjectEntity(CreateTestReadingListEntity(kUrl, "entry_title")); + + ASSERT_TRUE(ServerReadingListURLsEqualityChecker({kUrl, GURL("")}).Wait()); + EXPECT_TRUE(LocalReadingListURLsEqualityChecker(model(), {kUrl}).Wait()); + + EXPECT_THAT(model()->size(), Eq(1ul)); +} + +IN_PROC_BROWSER_TEST_F( + SingleClientReadingListSyncTest, + ShouldFilterEntriesWithInvalidUrlUponIncrementalRemoteCreation) { + ASSERT_TRUE(SetupClients()); + + ASSERT_THAT(model()->size(), Eq(0ul)); + + ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount()); + ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); + ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); + EXPECT_TRUE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::READING_LIST)); + + ASSERT_THAT(model()->size(), Eq(0ul)); + + std::unique_ptr<syncer::LoopbackServerEntity> kCorruptEntry = + CreateTestReadingListEntity(GURL("http://CorruptEntry.com/"), + "corrupt_entry_title"); + sync_pb::EntitySpecifics specifics = kCorruptEntry->GetSpecifics(); + // An invalid URL makes it an invalid reading list specifics. + *specifics.mutable_reading_list()->mutable_url() = "CorruptEntryURL"; + ASSERT_FALSE(ReadingListEntry::IsSpecificsValid(specifics.reading_list())); + kCorruptEntry->SetSpecifics(specifics); + fake_server_->InjectEntity(std::move(kCorruptEntry)); + + const GURL kUrl("http://url.com/"); + fake_server_->InjectEntity(CreateTestReadingListEntity(kUrl, "entry_title")); + + ASSERT_TRUE( + ServerReadingListURLsEqualityChecker({kUrl, GURL("CorruptEntryURL")}) + .Wait()); + EXPECT_TRUE(LocalReadingListURLsEqualityChecker(model(), {kUrl}).Wait()); + + EXPECT_THAT(model()->size(), Eq(1ul)); +} + +IN_PROC_BROWSER_TEST_F( + SingleClientReadingListSyncTest, + ShouldFilterEntriesWithEmptyUrlUponIncrementalRemoteUpdate) { + ASSERT_TRUE(SetupClients()); + + ASSERT_THAT(model()->size(), Eq(0ul)); + + const GURL kEntryWithCorruptRemoteUpdateUrl( + "http://EntryThatWillHaveCorruptRemoteUpdate.com/"); + fake_server_->InjectEntity(CreateTestReadingListEntity( + kEntryWithCorruptRemoteUpdateUrl, "entry_title")); + + ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount()); + ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); + ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); + EXPECT_TRUE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::READING_LIST)); + + ASSERT_THAT(model()->size(), Eq(1ul)); + + std::unique_ptr<syncer::LoopbackServerEntity> kCorruptRemoteUpdate = + CreateTestReadingListEntity(kEntryWithCorruptRemoteUpdateUrl, + "corrupt_entry_title"); + sync_pb::EntitySpecifics specifics = kCorruptRemoteUpdate->GetSpecifics(); + // An empty URL makes it an invalid reading list specifics. + *specifics.mutable_reading_list()->mutable_url() = ""; + ASSERT_FALSE(ReadingListEntry::IsSpecificsValid(specifics.reading_list())); + kCorruptRemoteUpdate->SetSpecifics(specifics); + fake_server_->InjectEntity(std::move(kCorruptRemoteUpdate)); + + const GURL kUrl("http://url.com/"); + fake_server_->InjectEntity(CreateTestReadingListEntity(kUrl, "entry_title")); + + ASSERT_TRUE(ServerReadingListURLsEqualityChecker({kUrl, GURL("")}).Wait()); + EXPECT_TRUE(LocalReadingListURLsEqualityChecker( + model(), {kUrl, kEntryWithCorruptRemoteUpdateUrl}) + .Wait()); + + EXPECT_THAT(model()->size(), Eq(2ul)); + EXPECT_THAT(model()->GetEntryByURL(kEntryWithCorruptRemoteUpdateUrl)->Title(), + Eq("entry_title")); +} + +IN_PROC_BROWSER_TEST_F( + SingleClientReadingListSyncTest, + ShouldFilterEntriesWithInvalidUrlUponIncrementalRemoteUpdate) { + ASSERT_TRUE(SetupClients()); + + ASSERT_THAT(model()->size(), Eq(0ul)); + + const GURL kEntryWithCorruptRemoteUpdateUrl( + "http://EntryThatWillHaveCorruptRemoteUpdate.com/"); + fake_server_->InjectEntity(CreateTestReadingListEntity( + kEntryWithCorruptRemoteUpdateUrl, "entry_title")); + + ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount()); + ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); + ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); + EXPECT_TRUE( + GetSyncService(0)->GetActiveDataTypes().Has(syncer::READING_LIST)); + + ASSERT_THAT(model()->size(), Eq(1ul)); + + std::unique_ptr<syncer::LoopbackServerEntity> kCorruptRemoteUpdate = + CreateTestReadingListEntity(kEntryWithCorruptRemoteUpdateUrl, + "corrupt_entry_title"); + sync_pb::EntitySpecifics specifics = kCorruptRemoteUpdate->GetSpecifics(); + // An invalid URL makes it an invalid reading list specifics. + *specifics.mutable_reading_list()->mutable_url() = "CorruptUpdateURL"; + ASSERT_FALSE(ReadingListEntry::IsSpecificsValid(specifics.reading_list())); + kCorruptRemoteUpdate->SetSpecifics(specifics); + fake_server_->InjectEntity(std::move(kCorruptRemoteUpdate)); + + const GURL kUrl("http://url.com/"); + fake_server_->InjectEntity(CreateTestReadingListEntity(kUrl, "entry_title")); + + ASSERT_TRUE( + ServerReadingListURLsEqualityChecker({kUrl, GURL("CorruptUpdateURL")}) + .Wait()); + EXPECT_TRUE(LocalReadingListURLsEqualityChecker( + model(), {kUrl, kEntryWithCorruptRemoteUpdateUrl}) + .Wait()); + + EXPECT_THAT(model()->size(), Eq(2ul)); + EXPECT_THAT(model()->GetEntryByURL(kEntryWithCorruptRemoteUpdateUrl)->Title(), + Eq("entry_title")); +} + #endif // !BUILDFLAG(IS_CHROMEOS_ASH) #endif // !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java index 81efd45..0a92f0c 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.tab.state; -import android.graphics.Color; import android.text.TextUtils; import androidx.annotation.Nullable; @@ -21,6 +20,7 @@ import org.chromium.build.annotations.DoNotClassMerge; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab.TabState; import org.chromium.chrome.browser.tab.TabUserAgent; import org.chromium.chrome.browser.tab.WebContentsState; import org.chromium.chrome.browser.tab.WebContentsStateBridge; @@ -47,7 +47,6 @@ private static final Class<CriticalPersistedTabData> USER_DATA_KEY = CriticalPersistedTabData.class; - private static final int UNSPECIFIED_THEME_COLOR = Color.TRANSPARENT; private static final String NULL_OPENER_APP_ID = " "; private static final PersistedTabDataMapper<SerializedCriticalPersistedTabData> sMapper = new PersistedTabDataMapper<SerializedCriticalPersistedTabData>() { @@ -112,7 +111,7 @@ private WebContentsState mWebContentsState; private int mContentStateVersion; private String mOpenerAppId; - private int mThemeColor; + /** * Saves how this tab was initially launched so that we can record metrics on how the * tab was created. This is different than {@link Tab#getLaunchType()}, since {@link @@ -140,22 +139,20 @@ * @param timestampMillis creation timestamp for the {@link Tab} * @param contentStateVersion content state version for the {@link Tab} * @param openerAppId identifier for app opener - * @param themeColor theme color * @param launchTypeAtCreation launch type at creation * @param userAgent user agent for the {@link Tab} */ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) CriticalPersistedTabData(Tab tab, String url, String title, int rootId, WebContentsState webContentsState, int contentStateVersion, String openerAppId, - int themeColor, @Nullable @TabLaunchType Integer launchTypeAtCreation, - @TabUserAgent int userAgent, long lastNavigationCommittedTimestampMillis) { + @Nullable @TabLaunchType Integer launchTypeAtCreation, @TabUserAgent int userAgent, + long lastNavigationCommittedTimestampMillis) { this(tab); mUrl = url == null || url.isEmpty() ? GURL.emptyGURL() : new GURL(url); mTitle = title; mWebContentsState = webContentsState; mContentStateVersion = contentStateVersion; mOpenerAppId = openerAppId; - mThemeColor = themeColor; mTabLaunchTypeAtCreation = launchTypeAtCreation; mUserAgent = userAgent; mLastNavigationCommittedTimestampMillis = lastNavigationCommittedTimestampMillis; @@ -187,8 +184,8 @@ public CriticalPersistedTabData(Tab tab, SerializedCriticalPersistedTabData serialized) { this(tab, serialized.getUrl(), serialized.getTitle(), serialized.getRootId(), serialized.getWebContentsState(), serialized.getWebContentsStateVersion(), - serialized.getOpenerAppId(), serialized.getThemeColor(), serialized.getLaunchType(), - serialized.getUserAgent(), serialized.getLastNavigationCommittedTimestampMillis()); + serialized.getOpenerAppId(), serialized.getLaunchType(), serialized.getUserAgent(), + serialized.getLastNavigationCommittedTimestampMillis()); } /** @@ -261,9 +258,8 @@ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) public static CriticalPersistedTabData build(Tab tab) { // CriticalPersistedTabData is initialized with default values - CriticalPersistedTabData criticalPersistedTabData = - new CriticalPersistedTabData(tab, "", "", tab.getId(), null, -1, "", - UNSPECIFIED_THEME_COLOR, null, TabUserAgent.DEFAULT, INVALID_TIMESTAMP); + CriticalPersistedTabData criticalPersistedTabData = new CriticalPersistedTabData(tab, "", + "", tab.getId(), null, -1, "", null, TabUserAgent.DEFAULT, INVALID_TIMESTAMP); criticalPersistedTabData.save(); return criticalPersistedTabData; } @@ -293,7 +289,6 @@ mOpenerAppId = NULL_OPENER_APP_ID.equals(deserialized.openerAppId()) ? null : deserialized.openerAppId(); - mThemeColor = deserialized.themeColor(); mTabLaunchTypeAtCreation = getLaunchType(deserialized.launchTypeAtCreation()); mUserAgent = getTabUserAgentType(deserialized.userAgent()); return true; @@ -497,7 +492,6 @@ private ByteBuffer mByteBufferSnapshot; private String mOpenerAppIdSnapshot; private int mWebContentsStateVersionSnapshot; - private int mThemeColorSnapshot; private int mLaunchTypeSnapshot; private int mUserAgentTypeSnapshot; private long mLastNavigationCommittedTimestampMillisSnapshot; @@ -535,7 +529,8 @@ CriticalPersistedTabDataFlatBuffer.addContentStateVersion( fbb, mWebContentsStateVersionSnapshot); CriticalPersistedTabDataFlatBuffer.addOpenerAppId(fbb, oaid); - CriticalPersistedTabDataFlatBuffer.addThemeColor(fbb, mThemeColorSnapshot); + CriticalPersistedTabDataFlatBuffer.addThemeColor( + fbb, TabState.UNSPECIFIED_THEME_COLOR); CriticalPersistedTabDataFlatBuffer.addLaunchTypeAtCreation( fbb, mLaunchTypeSnapshot); CriticalPersistedTabDataFlatBuffer.addUserAgent(fbb, mUserAgentTypeSnapshot); @@ -563,7 +558,6 @@ webContentsState == null ? null : webContentsState.buffer(); mOpenerAppIdSnapshot = mOpenerAppId; mWebContentsStateVersionSnapshot = mContentStateVersion; - mThemeColorSnapshot = mThemeColor; mLaunchTypeSnapshot = getLaunchType(mTabLaunchTypeAtCreation); mUserAgentTypeSnapshot = getUserAgentType(mUserAgent); mLastNavigationCommittedTimestampMillisSnapshot = @@ -717,13 +711,6 @@ } /** - * @return theme color - */ - public int getThemeColor() { - return mThemeColor; - } - - /** * @return launch type at creation */ public @Nullable @TabLaunchType Integer getTabLaunchTypeAtCreation() {
diff --git a/chrome/browser/tpcd/experiment/eligibility_service.cc b/chrome/browser/tpcd/experiment/eligibility_service.cc index 3a3c960..c9ec334 100644 --- a/chrome/browser/tpcd/experiment/eligibility_service.cc +++ b/chrome/browser/tpcd/experiment/eligibility_service.cc
@@ -7,16 +7,17 @@ #include "base/check.h" #include "base/functional/bind.h" #include "chrome/browser/tpcd/experiment/eligibility_service_factory.h" -#include "chrome/browser/tpcd/experiment/tpcd_experiment_features.h" #include "content/public/browser/cookie_deprecation_label_manager.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/content_features.h" #include "services/network/public/mojom/network_context.mojom.h" namespace tpcd::experiment { EligibilityService::EligibilityService(Profile* profile) : profile_(profile), pref_service_(profile->GetPrefs()) { - DCHECK(base::FeatureList::IsEnabled(k3PCDModeBExperiment)); + DCHECK(base::FeatureList::IsEnabled( + features::kCookieDeprecationFacilitatedTesting)); DCHECK(pref_service_); }
diff --git a/chrome/browser/tpcd/experiment/eligibility_service_browsertest.cc b/chrome/browser/tpcd/experiment/eligibility_service_browsertest.cc index f427007..8e46d17 100644 --- a/chrome/browser/tpcd/experiment/eligibility_service_browsertest.cc +++ b/chrome/browser/tpcd/experiment/eligibility_service_browsertest.cc
@@ -20,8 +20,8 @@ #include "components/privacy_sandbox/privacy_sandbox_settings.h" #include "components/privacy_sandbox/privacy_sandbox_test_util.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" -#include "net/base/features.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_status_code.h" #include "net/test/embedded_test_server/controllable_http_response.h" @@ -35,12 +35,9 @@ class EligiblityServiceBrowserTest : public InProcessBrowserTest { public: EligiblityServiceBrowserTest() { - feature_list_.InitWithFeaturesAndParameters( - /*enabled_features=*/ - {{net::features::kCookieDeprecationFacilitatedTestingLabels, - {{"label", "label_test"}}}, - {k3PCDModeBExperiment, {}}}, - /*disabled_features=*/{}); + feature_list_.InitAndEnableFeatureWithParameters( + features::kCookieDeprecationFacilitatedTesting, + {{"label", "label_test"}}); } ~EligiblityServiceBrowserTest() override = default; @@ -102,12 +99,12 @@ PrivacySandboxSettingsFactory::GetForProfile(browser()->profile()); auto privacy_sandbox_delegate = std::make_unique< privacy_sandbox_test_util::MockPrivacySandboxSettingsDelegate>(); - EXPECT_CALL(*privacy_sandbox_delegate, IsPrivacySandboxRestricted) + EXPECT_CALL(*privacy_sandbox_delegate, IsCookieDeprecationExperimentEligible) .Times(4) - .WillOnce(testing::Return(true)) - .WillOnce(testing::Return(true)) .WillOnce(testing::Return(false)) - .WillOnce(testing::Return(false)); + .WillOnce(testing::Return(false)) + .WillOnce(testing::Return(true)) + .WillOnce(testing::Return(true)); privacy_sandbox_settings->SetDelegateForTesting( std::move(privacy_sandbox_delegate));
diff --git a/chrome/browser/tpcd/experiment/tpcd_experiment_features.cc b/chrome/browser/tpcd/experiment/tpcd_experiment_features.cc index b66d139..03a9522 100644 --- a/chrome/browser/tpcd/experiment/tpcd_experiment_features.cc +++ b/chrome/browser/tpcd/experiment/tpcd_experiment_features.cc
@@ -4,31 +4,27 @@ #include "chrome/browser/tpcd/experiment/tpcd_experiment_features.h" -#include "base/feature_list.h" +#include <string> + #include "base/metrics/field_trial_params.h" +#include "content/public/common/content_features.h" namespace tpcd::experiment { -// Enables the Third Party Cookie Deprecation (TPCD) Mode B Experiment -// feature. -BASE_FEATURE(k3PCDModeBExperiment, - "3PCDModeBExperiment", - base::FEATURE_DISABLED_BY_DEFAULT); - -// Set which experiment cohort a user is assigned to ("modeb", "modebprime", -// "control", etc.). +// Set which experiment cohort a user is assigned to ("modea", "modeb", +// "modebprime", "control", etc.). const base::FeatureParam<std::string> kCohort{ - &k3PCDModeBExperiment, /*name=*/"cohort", /*default_value=*/""}; + &features::kCookieDeprecationFacilitatedTesting, /*name=*/"cohort", + /*default_value=*/""}; -const base::FeatureParam<bool> kDisable3PCookies{&k3PCDModeBExperiment, - /*name=*/"disable_3p_cookies", - /*default_value=*/false}; +const base::FeatureParam<bool> kDisable3PCookies{ + &features::kCookieDeprecationFacilitatedTesting, + /*name=*/"disable_3p_cookies", + /*default_value=*/false}; -const base::FeatureParam<bool> kDisableAdsAPIs{&k3PCDModeBExperiment, - /*name=*/"disable_ads_apis", - /*default_value=*/false}; - -const base::FeatureParam<bool> kLabelTraffic{ - &k3PCDModeBExperiment, /*name=*/"label_traffic", /*default_value=*/false}; +const base::FeatureParam<bool> kDisableAdsAPIs{ + &features::kCookieDeprecationFacilitatedTesting, + /*name=*/"disable_ads_apis", + /*default_value=*/false}; } // namespace tpcd::experiment
diff --git a/chrome/browser/tpcd/experiment/tpcd_experiment_features.h b/chrome/browser/tpcd/experiment/tpcd_experiment_features.h index 3fcdca16..6d28762 100644 --- a/chrome/browser/tpcd/experiment/tpcd_experiment_features.h +++ b/chrome/browser/tpcd/experiment/tpcd_experiment_features.h
@@ -5,17 +5,15 @@ #ifndef CHROME_BROWSER_TPCD_EXPERIMENT_TPCD_EXPERIMENT_FEATURES_H_ #define CHROME_BROWSER_TPCD_EXPERIMENT_TPCD_EXPERIMENT_FEATURES_H_ -#include "base/feature_list.h" +#include <string> + #include "base/metrics/field_trial_params.h" namespace tpcd::experiment { -BASE_DECLARE_FEATURE(k3PCDModeBExperiment); - extern const base::FeatureParam<std::string> kCohort; extern const base::FeatureParam<bool> kDisable3PCookies; extern const base::FeatureParam<bool> kDisableAdsAPIs; -extern const base::FeatureParam<bool> kLabelTraffic; } // namespace tpcd::experiment
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index fda41c2..949e4e4 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2886,8 +2886,12 @@ "webui/ash/emoji/gif_tenor_api_fetcher.h", "webui/ash/emoji/new_window_proxy.cc", "webui/ash/emoji/new_window_proxy.h", + "webui/ash/enterprise_reporting/enterprise_reporting_page_handler.cc", + "webui/ash/enterprise_reporting/enterprise_reporting_page_handler.h", "webui/ash/enterprise_reporting/enterprise_reporting_ui.cc", "webui/ash/enterprise_reporting/enterprise_reporting_ui.h", + "webui/ash/enterprise_reporting/history_converter.cc", + "webui/ash/enterprise_reporting/history_converter.h", "webui/ash/guest_os_installer/guest_os_installer_dialog.cc", "webui/ash/guest_os_installer/guest_os_installer_dialog.h", "webui/ash/healthd_internals/healthd_internals_ui.cc", @@ -3498,6 +3502,7 @@ "//chrome/browser/ui/webui/ash/borealis_installer:mojo_bindings", "//chrome/browser/ui/webui/ash/cloud_upload:mojo_bindings", "//chrome/browser/ui/webui/ash/crostini_upgrader:mojo_bindings", + "//chrome/browser/ui/webui/ash/enterprise_reporting:mojo_bindings", "//chrome/browser/ui/webui/ash/launcher_internals:mojo_bindings", "//chrome/browser/ui/webui/ash/manage_mirrorsync:mojo_bindings", "//chrome/browser/ui/webui/ash/office_fallback:mojo_bindings", @@ -3620,6 +3625,7 @@ "//components/exo", "//components/login", "//components/metrics/structured:structured_events", + "//components/reporting/proto:health_proto", "//components/services/app_service", "//components/services/app_service/public/cpp/shortcut", "//components/session_manager/core",
diff --git a/chrome/browser/ui/android/hats/BUILD.gn b/chrome/browser/ui/android/hats/BUILD.gn index 9dd8257..0b63107 100644 --- a/chrome/browser/ui/android/hats/BUILD.gn +++ b/chrome/browser/ui/android/hats/BUILD.gn
@@ -78,6 +78,7 @@ "//base:base_java_test_support", "//base:base_junit_test_support", "//chrome/browser/first_run/android:java", + "//chrome/browser/flags:java", "//chrome/browser/preferences:java", "//chrome/browser/tab:java", "//chrome/browser/tabmodel:java",
diff --git a/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/TestSurveyUtils.java b/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/TestSurveyUtils.java index 6696640..c18ac44 100644 --- a/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/TestSurveyUtils.java +++ b/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/TestSurveyUtils.java
@@ -46,6 +46,16 @@ public static final String TEST_TRIGGER_ID_FOO = "test_trigger_id_foo"; /** + * Assume a test SurveyConfig exists for trigger with given PSD. Use to bypass survey config + * parsing from native. + */ + public static void setTestSurveyConfigForTrigger( + String trigger, String[] psdBitFields, String[] psdStringFields) { + SurveyConfig.setSurveyConfigForTesting(new SurveyConfig( + trigger, TEST_TRIGGER_ID_FOO, 1.0f, false, psdBitFields, psdStringFields)); + } + + /** * Create a test-only survey component. In test environment: * - The survey throttler check will be ignored and always pass. * - Crash upload will be allowed all the time.
diff --git a/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyConfig.java b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyConfig.java index 0cb0829..b4c92bb 100644 --- a/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyConfig.java +++ b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyConfig.java
@@ -7,6 +7,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.base.ResettersForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; @@ -21,6 +22,7 @@ */ @JNINamespace("hats") public class SurveyConfig { + private static SurveyConfig sConfigForTesting; /** * Unique key associate with the config. */ @@ -55,9 +57,17 @@ */ @Nullable public static SurveyConfig get(String trigger) { + if (sConfigForTesting != null && sConfigForTesting.mTrigger.equals(trigger)) { + return sConfigForTesting; + } return Holder.getInstance().getSurveyConfig(trigger); } + static void setSurveyConfigForTesting(SurveyConfig config) { + sConfigForTesting = config; + ResettersForTesting.register(() -> sConfigForTesting = null); + } + /** Clear all the initialized configs. */ static void clearAll() { Holder.getInstance().destroy();
diff --git a/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java index a3cb2231e..176662b 100644 --- a/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java +++ b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java
@@ -11,8 +11,10 @@ import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.HistogramWatcher; import org.chromium.chrome.browser.firstrun.FirstRunStatus; +import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.ui.hats.SurveyThrottler.FilteringResult; @@ -160,6 +162,19 @@ mSharedPref.readInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, -1)); } + @Test + @CommandLineFlags.Add(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY) + public void testCommandLineForceEnableSurvey() { + RiggedSurveyThrottler throttler = + new RiggedSurveyThrottler(/*randomlySelected=*/false, /*dayOfYear=*/1); + try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher( + "Android.Survey.SurveyFilteringResults", + FilteringResult.FORCE_SURVEY_ON_COMMAND_PRESENT)) { + Assert.assertTrue( + "Survey should be enabled by commandline flag.", throttler.canShowSurvey()); + } + } + /** Test class used to test the rate limiting logic for {@link SurveyThrottler}. */ private class RiggedSurveyThrottler extends SurveyThrottler { private final boolean mRandomlySelected;
diff --git a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsActivator.java b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsActivator.java index f6b241d..95a596ff 100644 --- a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsActivator.java +++ b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsActivator.java
@@ -74,9 +74,9 @@ * @return a token to be used later to stop checking. */ public int start(Runnable callback) { - mSwaaChecker.start(); int token = mTokenHolder.acquireToken(); mCallbacks.put(token, callback); + mSwaaChecker.start(); return token; }
diff --git a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinator.java b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinator.java index 02a3839..ec7fbac 100644 --- a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinator.java +++ b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinator.java
@@ -53,13 +53,15 @@ * @param controlsStateProvider Provides the browser controls' state. * @param browserControlsSizer Bottom browser controls resizer. * @param isPageInsightsHubEnabled Supplier of the feature flag. + * @param firstLoadTimeMs Timestamp for the first page load completion. */ public PageInsightsCoordinator(Context context, ObservableSupplier<Tab> tabProvider, Supplier<ShareDelegate> shareDelegateSupplier, ManagedBottomSheetController bottomSheetController, BottomSheetController bottomUiController, ExpandedSheetHelper expandedSheetHelper, BrowserControlsStateProvider controlsStateProvider, - BrowserControlsSizer browserControlsSizer, BooleanSupplier isPageInsightsHubEnabled) { + BrowserControlsSizer browserControlsSizer, BooleanSupplier isPageInsightsHubEnabled, + long firstLoadTimeMs) { mContext = context; mTabProvider = tabProvider; mBottomSheetController = bottomSheetController; @@ -69,7 +71,8 @@ mBrowserControlsSizer = browserControlsSizer; mMediator = new PageInsightsMediator(mContext, mTabProvider, shareDelegateSupplier, mBottomSheetController, mBottomUiController, mExpandedSheetHelper, - mControlsStateProvider, mBrowserControlsSizer, isPageInsightsHubEnabled); + mControlsStateProvider, mBrowserControlsSizer, isPageInsightsHubEnabled, + firstLoadTimeMs); } /**
diff --git a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinatorTest.java b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinatorTest.java index 02315cc..71d199a 100644 --- a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinatorTest.java +++ b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsCoordinatorTest.java
@@ -33,12 +33,14 @@ import org.chromium.base.Callback; import org.chromium.base.ContextUtils; +import org.chromium.base.FeatureList; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.util.Batch; import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.page_insights.proto.PageInsights; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.tab.Tab; @@ -119,6 +121,8 @@ private GradientDrawable mBackgroundDrawable; + private FeatureList.TestValues mFeatureListValues; + @BeforeClass public static void setupSuite() { sTestRule.launchActivity(null); @@ -134,6 +138,10 @@ .when(mSurfaceRenderer) .render(any(), any()); doReturn(false).when(mIsPageInsightsHubEnabled).getAsBoolean(); + mFeatureListValues = new FeatureList.TestValues(); + FeatureList.setTestValues(mFeatureListValues); + mFeatureListValues.addFieldTrialParamOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, + PageInsightsMediator.PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END, String.valueOf(2000)); } private static Activity getActivity() { @@ -175,7 +183,7 @@ mPageInsightsCoordinator = new PageInsightsCoordinator(activity, mTabProvider, mShareDelegateSupplier, mPageInsightsController, mBottomUiController, mExpandedSheetHelper, mBrowserControlsStateProvider, mBrowserControlsSizer, - mIsPageInsightsHubEnabled); + mIsPageInsightsHubEnabled, 0); mTestSupport = new BottomSheetTestSupport(mPageInsightsController); waitForAnimationToFinish(); }
diff --git a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediator.java b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediator.java index 92efeee..7d6795e 100644 --- a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediator.java +++ b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediator.java
@@ -55,7 +55,7 @@ * </ul> */ public class PageInsightsMediator extends EmptyTabObserver implements BottomSheetObserver { - private static final int DEFAULT_TRIGGER_DELAY_MS = (int) DateUtils.MINUTE_IN_MILLIS; + static final int DEFAULT_TRIGGER_DELAY_MS = (int) DateUtils.MINUTE_IN_MILLIS; private static final float MINIMUM_CONFIDENCE = 0.5f; static final String PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END = "page_insights_can_autotrigger_after_end"; @@ -107,20 +107,35 @@ // when notified when the UI was closed. private boolean mShouldRestore; + // Amount of time to wait before triggering the sheet automatically. Can be overridden + // for testing. + private long mAutoTriggerDelayMs; + private Supplier<Long> mCurrentTime; + public PageInsightsMediator(Context context, ObservableSupplier<Tab> tabObservable, Supplier<ShareDelegate> shareDelegateSupplier, ManagedBottomSheetController bottomSheetController, BottomSheetController bottomUiController, ExpandedSheetHelper expandedSheetHelper, BrowserControlsStateProvider controlsStateProvider, - BrowserControlsSizer browserControlsSizer, BooleanSupplier isPageInsightsHubEnabled) { + BrowserControlsSizer browserControlsSizer, BooleanSupplier isPageInsightsHubEnabled, + long firstLoadTimeMs) { mContext = context; mSheetContent = new PageInsightsSheetContent(mContext); mSheetController = bottomSheetController; mBottomUiController = bottomUiController; + mCurrentTime = System::currentTimeMillis; tabObservable.addObserver(tab -> { - if (tab != null) { - tab.addObserver(this); + if (tab == null) return; + + // Handle autotrigger if tab loading has already finished, which can happen + // when PIH components creation is delayed due to sWAA bit being enabled + // later than tab loading process. + if (!tab.isLoading() && firstLoadTimeMs > 0) { + long triggerTimeMs = firstLoadTimeMs + mAutoTriggerDelayMs; + long delayMs = Math.max(0, triggerTimeMs - mCurrentTime.get()); + delayStartAutoTrigger(Math.min(mAutoTriggerDelayMs, delayMs)); } + tab.addObserver(this); }); mExpandedSheetHelper = expandedSheetHelper; mHandler = new Handler(Looper.getMainLooper()); @@ -149,6 +164,9 @@ mSurfaceRendererContextValues = PageInsightsActionHandlerImpl.createContextValues(new PageInsightsActionHandlerImpl( tabObservable, shareDelegateSupplier, this::changeToChildPage)); + mAutoTriggerDelayMs = ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END, + DEFAULT_TRIGGER_DELAY_MS); } void initView(View bottomSheetContainer) { @@ -211,10 +229,15 @@ // onPageLoadFinished is not suitable as it is not fired when going back to a cached page. if (!toDifferentDocument) return; resetAutoTriggerTimer(); - mHandler.postDelayed(mAutoTriggerRunnable, - ChromeFeatureList.getFieldTrialParamByFeatureAsInt( - ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, - PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END, DEFAULT_TRIGGER_DELAY_MS)); + delayStartAutoTrigger(mAutoTriggerDelayMs); + } + + private void delayStartAutoTrigger(long delayMs) { + if (delayMs > 0) { + mHandler.postDelayed(mAutoTriggerRunnable, delayMs); + } else { + mAutoTriggerRunnable.run(); + } } private void maybeAutoTriggerPageInsights() { @@ -369,6 +392,10 @@ mAutoTriggerReady = true; } + boolean getAutoTriggerReadyForTesting() { + return mAutoTriggerReady; + } + void setPageInsightsDataLoaderForTesting(PageInsightsDataLoader pageInsightsDataLoader) { mPageInsightsDataLoader = pageInsightsDataLoader; } @@ -377,6 +404,10 @@ return mSheetContainer; } + void setElapsedRealtimeSupplierForTesting(Supplier<Long> currentTime) { + mCurrentTime = currentTime; + } + private PageInsightsSurfaceRenderer getSurfaceRenderer() { if (mSurfaceRenderer != null) { return mSurfaceRenderer;
diff --git a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediatorTest.java b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediatorTest.java index dde627a..b3034e8 100644 --- a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediatorTest.java +++ b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsMediatorTest.java
@@ -13,10 +13,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.chromium.chrome.browser.page_insights.PageInsightsMediator.DEFAULT_TRIGGER_DELAY_MS; import static org.chromium.chrome.browser.page_insights.PageInsightsMediator.PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END; import android.content.Context; import android.graphics.drawable.GradientDrawable; +import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -35,11 +37,13 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.LooperMode; import org.robolectric.annotation.LooperMode.Mode; import org.robolectric.shadows.ShadowLooper; +import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.FeatureList; import org.chromium.base.FeatureList.TestValues; @@ -82,6 +86,7 @@ private static final String TEST_CHILD_PAGE_TITLE = "People also View"; private static final byte[] TEST_FEED_ELEMENTS_OUTPUT = new byte[123]; private static final byte[] TEST_CHILD_ELEMENTS_OUTPUT = new byte[456]; + private static final int SHORT_TRIGGER_DELAY_MS = 2 * (int) DateUtils.SECOND_IN_MILLIS; @Rule public JniMocker jniMocker = new JniMocker(); @@ -125,6 +130,8 @@ private ArgumentCaptor<LoadUrlParams> mLoadUrlParams; @Captor private ArgumentCaptor<ShareParams> mShareParams; + @Captor + private ArgumentCaptor<Callback<Tab>> mTabObserver; private ShadowLooper mShadowLooper; @@ -133,7 +140,6 @@ @Before public void setUp() { MockitoAnnotations.initMocks(this); - Context mContext = ContextUtils.getApplicationContext(); mShadowLooper = ShadowLooper.shadowMainLooper(); jniMocker.mock(DomDistillerUrlUtilsJni.TEST_HOOKS, mDistillerUrlUtilsJniMock); when(mDistillerUrlUtilsJniMock.getOriginalUrlFromDistillerUrl(any(String.class))) @@ -149,9 +155,25 @@ when(mPageInsightsDataLoader.getData()).thenReturn(getPageInsightsMetadata()); when(mMockTabProvider.get()).thenReturn(mTab); when(mShareDelegateSupplier.get()).thenReturn(mShareDelegate); - mMediator = new PageInsightsMediator(mContext, mMockTabProvider, mShareDelegateSupplier, + } + + private void createMediator() { + createMediator(DEFAULT_TRIGGER_DELAY_MS); + } + + private void createMediator(int triggerDelayMs) { + createMediator(triggerDelayMs, 0); + } + + private void createMediator(int triggerDelayMs, long firstLoadTimeMs) { + TestValues testValues = new TestValues(); + testValues.addFieldTrialParamOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, + PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END, String.valueOf(triggerDelayMs)); + FeatureList.setTestValues(testValues); + Context context = ContextUtils.getApplicationContext(); + mMediator = new PageInsightsMediator(context, mMockTabProvider, mShareDelegateSupplier, mBottomSheetController, mBottomUiController, mExpandedSheetHelper, - mControlsStateProvider, mBrowserControlsSizer, () -> true); + mControlsStateProvider, mBrowserControlsSizer, () -> true, firstLoadTimeMs); mMediator.setPageInsightsDataLoaderForTesting(mPageInsightsDataLoader); verify(mControlsStateProvider).addObserver(mBrowserControlsStateProviderObserver.capture()); setBackgroundDrawable(); @@ -160,12 +182,7 @@ @Test @MediumTest public void testAutoTrigger_doesNotTriggerImmediately() throws Exception { - TestValues testValues = new TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, true); - testValues.addFieldTrialParamOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, - PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END, "2000"); - FeatureList.setTestValues(testValues); - + createMediator(SHORT_TRIGGER_DELAY_MS); mMediator.onLoadStopped(mTab, true); mBrowserControlsStateProviderObserver.getValue().onControlsOffsetChanged(0, 70, 0, 0, true); @@ -175,12 +192,7 @@ @Test @MediumTest public void testAutoTrigger_notEnoughDuration_doesNotTrigger() throws Exception { - TestValues testValues = new TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, true); - testValues.addFieldTrialParamOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, - PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END, "2000"); - FeatureList.setTestValues(testValues); - + createMediator(SHORT_TRIGGER_DELAY_MS); mMediator.onLoadStopped(mTab, true); mShadowLooper.idleFor(250, TimeUnit.MILLISECONDS); mBrowserControlsStateProviderObserver.getValue().onControlsOffsetChanged(0, 70, 0, 0, true); @@ -191,11 +203,7 @@ @Test @MediumTest public void testAutoTrigger_enoughDuration_showsBottomSheet() throws Exception { - TestValues testValues = new TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, true); - testValues.addFieldTrialParamOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, - PAGE_INSIGHTS_CAN_AUTOTRIGGER_AFTER_END, "2000"); - FeatureList.setTestValues(testValues); + createMediator(SHORT_TRIGGER_DELAY_MS); View feedView = new View(ContextUtils.getApplicationContext()); when(mSurfaceRenderer.render(eq(TEST_FEED_ELEMENTS_OUTPUT), any())).thenReturn(feedView); @@ -227,9 +235,7 @@ @Test @MediumTest public void testOpenInExpandedState_showsBottomSheet() throws Exception { - TestValues testValues = new TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, true); - FeatureList.setTestValues(testValues); + createMediator(); View feedView = new View(ContextUtils.getApplicationContext()); when(mSurfaceRenderer.render(eq(TEST_FEED_ELEMENTS_OUTPUT), any())).thenReturn(feedView); @@ -256,9 +262,7 @@ @Test @MediumTest public void actionHandler_navigateToPageInsightsPage_childPageOpened() throws Exception { - TestValues testValues = new TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, true); - FeatureList.setTestValues(testValues); + createMediator(); View childView = new View(ContextUtils.getApplicationContext()); when(mSurfaceRenderer.render( eq(TEST_FEED_ELEMENTS_OUTPUT), mSurfaceRendererContextValues.capture())) @@ -292,9 +296,7 @@ @Test @MediumTest public void actionHandler_openUrl_opensUrl() throws Exception { - TestValues testValues = new TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, true); - FeatureList.setTestValues(testValues); + createMediator(); when(mSurfaceRenderer.render( eq(TEST_FEED_ELEMENTS_OUTPUT), mSurfaceRendererContextValues.capture())) .thenReturn(new View(ContextUtils.getApplicationContext())); @@ -312,9 +314,7 @@ @Test @MediumTest public void actionHandler_share_shares() throws Exception { - TestValues testValues = new TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.CCT_PAGE_INSIGHTS_HUB, true); - FeatureList.setTestValues(testValues); + createMediator(); when(mSurfaceRenderer.render( eq(TEST_FEED_ELEMENTS_OUTPUT), mSurfaceRendererContextValues.capture())) .thenReturn(new View(ContextUtils.getApplicationContext())); @@ -331,6 +331,53 @@ assertEquals(title, mShareParams.getValue().getTitle()); } + @Test + @MediumTest + public void setupAutoTriggerForDelayedInstantation_beforeTabLoading() throws Exception { + createMediator(); + verify(mMockTabProvider).addObserver(mTabObserver.capture()); + + // Nothing happens for null tab. + mTabObserver.getValue().onResult(null); + verify(mTab, never()).addObserver(mMediator); + + // Tab is still loading -> autotrigger setup will be handled by Mediator#onLoadStopped + when(mTab.isLoading()).thenReturn(true); + mTabObserver.getValue().onResult(mTab); + verify(mTab).addObserver(mMediator); + mShadowLooper.idleFor(DEFAULT_TRIGGER_DELAY_MS + 1, TimeUnit.MILLISECONDS); + verify(mBottomSheetController, never()).requestShowContent(any(), anyBoolean()); + } + + @Test + @MediumTest + public void setupAutoTriggerForDelayedInstantation_afterTabLoading() throws Exception { + // PIH was instantiated 20 seconds after tab loading completes. + long timeAfterLoading = 20 * DateUtils.SECOND_IN_MILLIS; + Supplier<Long> fakeTimer = Mockito.mock(Supplier.class); + final long currentTime = 139583732; + when(fakeTimer.get()).thenReturn(currentTime); + + createMediator(DEFAULT_TRIGGER_DELAY_MS, currentTime - timeAfterLoading); + mMediator.setElapsedRealtimeSupplierForTesting(fakeTimer); + View feedView = new View(ContextUtils.getApplicationContext()); + when(mSurfaceRenderer.render(eq(TEST_FEED_ELEMENTS_OUTPUT), any())).thenReturn(feedView); + verify(mMockTabProvider).addObserver(mTabObserver.capture()); + + when(mTab.isLoading()).thenReturn(false); + mTabObserver.getValue().onResult(mTab); + verify(mTab).addObserver(mMediator); + + // Verify that the PIH was autotriggered in 40 seconds. + mShadowLooper.idleFor( + DEFAULT_TRIGGER_DELAY_MS - timeAfterLoading - 1, TimeUnit.MILLISECONDS); + verify(mBottomSheetController, never()).requestShowContent(any(), anyBoolean()); + + // + 2 == DEFAULT_TRIGGER_DELAY_MS - timeAfterLoading + 1 + mShadowLooper.idleFor(2, TimeUnit.MILLISECONDS); + verify(mBottomSheetController).requestShowContent(any(), anyBoolean()); + } + private PageInsightsMetadata getPageInsightsMetadata() { Page childPage = Page.newBuilder() .setId(Page.PageID.PEOPLE_ALSO_VIEW)
diff --git a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaChecker.java b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaChecker.java index 6cacc47..821b4f6 100644 --- a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaChecker.java +++ b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaChecker.java
@@ -9,7 +9,6 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.SystemClock; import android.text.format.DateUtils; import androidx.annotation.NonNull; @@ -34,6 +33,9 @@ @VisibleForTesting(otherwise = PRIVATE) static final long REFRESH_PERIOD_MS = DateUtils.MINUTE_IN_MILLIS * 5; + @VisibleForTesting(otherwise = PRIVATE) + static final long EXTRA_QUERY_INTERVAL_MS = DateUtils.SECOND_IN_MILLIS; + private static final long[] RETRY_PERIODS_MS = new long[] {5 * DateUtils.SECOND_IN_MILLIS, 10 * DateUtils.SECOND_IN_MILLIS, 30 * DateUtils.SECOND_IN_MILLIS}; @@ -51,7 +53,7 @@ private int mRetryCount; PageInsightsSwaaChecker(Profile profile, Runnable activateCallback) { - mElapsedRealtime = SystemClock::elapsedRealtime; + mElapsedRealtime = System::currentTimeMillis; mProfile = profile; mActivateCallback = activateCallback; mHandler = new Handler(Looper.getMainLooper()) { @@ -78,12 +80,20 @@ * Start periodic querying of supplemental Web and App Activity setting. */ void start() { - Optional<Boolean> swaaStatus = isSwaaEnabled(); - if (!swaaStatus.isPresent()) { + boolean swaaEnabled = isSwaaEnabled().orElse(false); + if (!swaaEnabled) { mHandler.sendEmptyMessage(MSG_REFRESH); - } else if (!isUpdateScheduled()) { - mHandler.sendEmptyMessageDelayed( - MSG_REFRESH, REFRESH_PERIOD_MS - timeSinceLastUpdateMs()); + // The very first sWAA query to the server often returns false. To get around it, + // Send another query in quick succession if not cached or the current state is false. + // TODO(crbug/1482474): Figure out why this happens and remove this extra query. + mHandler.sendEmptyMessageDelayed(MSG_REFRESH, EXTRA_QUERY_INTERVAL_MS); + } else { + // Invoke activate callback if sWAA bit is on. This speeds up the intantiation of PIH. + mActivateCallback.run(); + if (!isUpdateScheduled()) { + mHandler.sendEmptyMessageDelayed( + MSG_REFRESH, REFRESH_PERIOD_MS - timeSinceLastUpdateMs()); + } } } @@ -126,10 +136,10 @@ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) void onSwaaResponse(boolean enabled) { mHandler.removeMessages(MSG_RETRY); - if (enabled) mActivateCallback.run(); SharedPreferencesManager prefs = SharedPreferencesManager.getInstance(); prefs.writeLong(ChromePreferenceKeys.SWAA_TIMESTAMP, mElapsedRealtime.get()); prefs.writeBoolean(ChromePreferenceKeys.SWAA_STATUS, enabled); + if (enabled) mActivateCallback.run(); } /**
diff --git a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaCheckerUnitTest.java b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaCheckerUnitTest.java index 3a80444..692a226 100644 --- a/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaCheckerUnitTest.java +++ b/chrome/browser/ui/android/page_insights/java/src/org/chromium/chrome/browser/page_insights/PageInsightsSwaaCheckerUnitTest.java
@@ -15,6 +15,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.chromium.chrome.browser.page_insights.PageInsightsSwaaChecker.EXTRA_QUERY_INTERVAL_MS; import static org.chromium.chrome.browser.page_insights.PageInsightsSwaaChecker.MSG_REFRESH; import static org.chromium.chrome.browser.page_insights.PageInsightsSwaaChecker.MSG_RETRY; import static org.chromium.chrome.browser.page_insights.PageInsightsSwaaChecker.REFRESH_PERIOD_MS; @@ -131,11 +132,18 @@ assertFalse(mSwaaChecker.isSwaaEnabled().get()); assertTrue(mSwaaChecker.isUpdateScheduled()); + // Set the sWAA state to |true| for the next step. + mSwaaChecker.onSwaaResponse(true); + clearInvocations(mActivateCallback); + // The 2nd CCT instance picks up the cached value without sending a new query // if the cache is valid. Verify the handler has an update scheduled. long timeNow2 = timeNow + REFRESH_PERIOD_MS / 2; mSwaaChecker.setElapsedRealtimeSupplierForTesting(() -> timeNow2); mSwaaChecker.start(); + + // Verify the activation i.e. PIH instantion is attempted immediately. + verify(mActivateCallback).run(); verify(mHandler, never()).sendEmptyMessage(eq(MSG_REFRESH)); verify(mHandler, never()).sendEmptyMessageDelayed(eq(MSG_REFRESH), anyInt()); assertTrue(mSwaaChecker.isUpdateScheduled()); @@ -156,13 +164,19 @@ // On signing in, a new query is made to update the cache immediately. mSwaaChecker.onSignedIn(); - verifyRequestSent(); + verify(mHandler).sendEmptyMessage(eq(MSG_REFRESH)); } private void verifyRequestSent() { + // At the beginning when there is no cached data (or when sWAA is false), we send + // 2 successive requests to work around a problem that often receives |false| for + // the first request. verify(mHandler).sendEmptyMessage(eq(MSG_REFRESH)); - // sendEmptyMessage sends the request immediately. Simulate that. + verify(mHandler).sendEmptyMessageDelayed(eq(MSG_REFRESH), eq(EXTRA_QUERY_INTERVAL_MS)); + + // Simulate handling the message. handleMessage(MSG_REFRESH); + verify(mPageInsightsSwaaCheckerJni).queryStatus(any(), any()); assertTrue(mSwaaChecker.isUpdateScheduled()); clearInvocations(mHandler);
diff --git a/chrome/browser/ui/ash/cast_config_controller_media_router.cc b/chrome/browser/ui/ash/cast_config_controller_media_router.cc index 8158020..e26d622 100644 --- a/chrome/browser/ui/ash/cast_config_controller_media_router.cc +++ b/chrome/browser/ui/ash/cast_config_controller_media_router.cc
@@ -237,7 +237,7 @@ GetMediaRouter()->CreateRoute( media_router::MediaSource::ForUnchosenDesktop().id(), sink_id, url::Origin::Create(GURL("http://cros-cast-origin/")), nullptr, - base::DoNothing(), base::TimeDelta(), false); + base::DoNothing(), base::TimeDelta()); } }
diff --git a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc index 608970d..4ccb0ba 100644 --- a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc +++ b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc
@@ -10,7 +10,6 @@ #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/string_number_conversions.h" -#include "chrome/browser/feature_engagement/tracker_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -80,10 +79,6 @@ constexpr base::TimeDelta kDelayIconView = base::Seconds(1); -// The amount in currency micros that a product needs to be to always expand the -// price tracking chip (assuming price insights isn't expanded). -constexpr int64_t kAlwaysExpandChipPriceMicros = 100000000L; - bool ShouldDelayChipUpdate() { if (base::FeatureList::IsEnabled(commerce::kPriceInsights)) { return commerce::kPriceInsightsDelayChip.Get(); @@ -138,7 +133,6 @@ last_fetched_image_url_ = GURL(); is_cluster_id_tracked_by_user_ = false; cluster_id_for_page_.reset(); - product_info_for_page_.reset(); pending_tracking_state_.reset(); is_first_load_for_nav_finished_ = false; price_insights_info_.reset(); @@ -190,9 +184,8 @@ if (!ShouldDelayChipUpdate()) { if (shopping_service_->IsPriceInsightsEligible()) { UpdatePriceInsightsIconView(); - } else { - UpdatePriceTrackingIconView(); } + UpdatePriceTrackingIconView(); } else { DelayUpdateForIconView(); } @@ -211,12 +204,8 @@ &ShoppingListUiTabHelper::UpdatePriceInsightsIconView, weak_ptr_factory_.GetWeakPtr()), kDelayIconView); - - } else { - if (last_fetched_image_.IsEmpty()) { - return; - } - + } + if (!last_fetched_image_.IsEmpty()) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) ->PostDelayedTask( FROM_HERE, @@ -301,7 +290,6 @@ if (shopping_service_->IsShoppingListEligible() && CanTrackPrice(info) && !info->image_url.is_empty()) { cluster_id_for_page_.emplace(info->product_cluster_id.value()); - product_info_for_page_.emplace(info.value()); UpdatePriceTrackingStateFromSubscriptions(); // TODO(1360850): Delay this fetch by possibly waiting until page load has @@ -520,56 +508,6 @@ ShoppingListUiTabHelper::GetPriceInsightsInfo() { return price_insights_info_; } - -absl::optional<PageActionIconType> -ShoppingListUiTabHelper::GetPageActionToExpand() { - if (!web_contents() || !web_contents()->GetBrowserContext()) { - return absl::nullopt; - } - - auto* tracker = feature_engagement::TrackerFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); - - if (!tracker) { - return absl::nullopt; - } - - if (tracker->ShouldTriggerHelpUI( - feature_engagement::kIPHPriceInsightsPageActionIconLabelFeature)) { - // Note that `Dismiss()` in these cases does not dismiss the UI. It's - // telling the FE backend that the promo is done so that other promos can - // run. Showing the label should not block other promos from displaying. - tracker->Dismissed( - feature_engagement::kIPHPriceInsightsPageActionIconLabelFeature); - return PageActionIconType::kPriceInsights; - } else if (tracker->ShouldTriggerHelpUI( - feature_engagement:: - kIPHPriceTrackingPageActionIconLabelFeature)) { - tracker->Dismissed( - feature_engagement::kIPHPriceTrackingPageActionIconLabelFeature); - return PageActionIconType::kPriceTracking; - } - - // If none of the above cases expanded a chip, expand the price tracking chip - // if the product price is > $100. - if (product_info_for_page_.has_value() && - product_info_for_page_->amount_micros > kAlwaysExpandChipPriceMicros && - product_info_for_page_->product_cluster_id.has_value()) { - CommerceSubscription sub( - SubscriptionType::kPriceTrack, IdentifierType::kProductClusterId, - base::NumberToString( - product_info_for_page_->product_cluster_id.value()), - ManagementType::kUserManaged); - - // Only expand the chip if the product isn't already tracked. - if (!shopping_service_->IsSubscribedFromCache(sub)) { - return PageActionIconType::kPriceTracking; - } - } - - return absl::nullopt; -} - WEB_CONTENTS_USER_DATA_KEY_IMPL(ShoppingListUiTabHelper); } // namespace commerce
diff --git a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h index dc2b970..15c8c35 100644 --- a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h +++ b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h
@@ -8,7 +8,6 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" -#include "chrome/browser/ui/page_action/page_action_icon_type.h" #include "components/commerce/core/shopping_service.h" #include "components/commerce/core/subscriptions/subscriptions_observer.h" #include "components/image_fetcher/core/request_metadata.h" @@ -98,10 +97,6 @@ // be made. virtual const absl::optional<PriceInsightsInfo>& GetPriceInsightsInfo(); - // Gets the ID of the omnibox page action icon that should expand for the tab - // this helper is for. If no icon should expand, absl::nullopt is returned. - virtual absl::optional<PageActionIconType> GetPageActionToExpand(); - protected: ShoppingListUiTabHelper(content::WebContents* contents, ShoppingService* shopping_service, @@ -176,9 +171,6 @@ // The cluster ID for the current page, if applicable. absl::optional<uint64_t> cluster_id_for_page_; - // The product info available for the current page if available. - absl::optional<ProductInfo> product_info_for_page_; - // A flag indicating whether the initial navigation has committed for the web // contents. This is used to ensure product info is fetched when a tab is // being restored.
diff --git a/chrome/browser/ui/media_router/media_route_starter.cc b/chrome/browser/ui/media_router/media_route_starter.cc index d6fc81c94..93c9bee1 100644 --- a/chrome/browser/ui/media_router/media_route_starter.cc +++ b/chrome/browser/ui/media_router/media_route_starter.cc
@@ -174,10 +174,6 @@ : url::Origin::Create(GURL()); params->timeout = GetRouteRequestTimeout(cast_mode); - params->off_the_record = - GetWebContents() && - GetWebContents()->GetBrowserContext()->IsOffTheRecord(); - return params; } @@ -214,7 +210,7 @@ base::BindOnce(&RunRouteResponseCallbacks, std::move(presentation_callback), std::move(params->route_result_callbacks)), - params->timeout, params->off_the_record); + params->timeout); } std::u16string MediaRouteStarter::GetPresentationRequestSourceName() const {
diff --git a/chrome/browser/ui/media_router/media_route_starter_unittest.cc b/chrome/browser/ui/media_router/media_route_starter_unittest.cc index 2c593c05..8547a05 100644 --- a/chrome/browser/ui/media_router/media_route_starter_unittest.cc +++ b/chrome/browser/ui/media_router/media_route_starter_unittest.cc
@@ -201,13 +201,13 @@ // Handler so MockMediaRouter will respond to requests to create a route. // Will construct a RouteRequestResult based on the set result code and // then call the handler's callback. - ON_CALL(*media_router(), CreateRouteInternal(_, _, _, _, _, _, _)) + ON_CALL(*media_router(), CreateRouteInternal(_, _, _, _, _, _)) .WillByDefault([this](const MediaSource::Id& source_id, const MediaSink::Id& sink_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback& callback, - base::TimeDelta timeout, bool incognito) { + base::TimeDelta timeout) { // This indicates the test did not properly set the expected result EXPECT_NE(mojom::RouteRequestResultCode::UNKNOWN_ERROR, result_code_); std::unique_ptr<RouteRequestResult> result; @@ -383,7 +383,7 @@ EXPECT_CALL(*media_router(), CreateRouteInternal(params->source_id, params->request->sink_id, params->origin, web_contents(), _, - params->timeout, params->off_the_record)); + params->timeout)); media_route_starter()->StartRoute(std::move(params)); } @@ -625,7 +625,6 @@ // route_result_callbacks should only be filled in by caller EXPECT_EQ(0ul, params->route_result_callbacks.size()); EXPECT_EQ(base::Seconds(120), params->timeout); - EXPECT_FALSE(params->off_the_record); } // Demonstrates that when tab mirroring is available and requested that the @@ -649,7 +648,6 @@ // route_result_callbacks should only be filled in by caller EXPECT_EQ(0ul, params->route_result_callbacks.size()); EXPECT_EQ(base::Seconds(60), params->timeout); - EXPECT_FALSE(params->off_the_record); } // Demonstrates that when presentation mode is available for the default @@ -677,7 +675,6 @@ // route_result_callbacks should only be filled in by caller EXPECT_EQ(0ul, params->route_result_callbacks.size()); EXPECT_EQ(base::Seconds(20), params->timeout); - EXPECT_FALSE(params->off_the_record); } // Demonstrates that when presentation mode is requested and a start @@ -707,7 +704,6 @@ // route_result_callbacks should only be filled in by caller EXPECT_EQ(0ul, params->route_result_callbacks.size()); EXPECT_EQ(base::Seconds(20), params->timeout); - EXPECT_FALSE(params->off_the_record); // This is to deal with the error callback in the d'tor that's not part of // this test. See the Dtor_* tests below where this case is actually
diff --git a/chrome/browser/ui/media_router/media_router_ui_helper.h b/chrome/browser/ui/media_router/media_router_ui_helper.h index 2d79df00..a6f0b3d 100644 --- a/chrome/browser/ui/media_router/media_router_ui_helper.h +++ b/chrome/browser/ui/media_router/media_router_ui_helper.h
@@ -116,9 +116,6 @@ // A timeout value, after which the request should be considered to have // failed. base::TimeDelta timeout; - - // Whether the route is for an off-the-record profile. - bool off_the_record; }; } // namespace media_router
diff --git a/chrome/browser/ui/media_router/media_router_ui_unittest.cc b/chrome/browser/ui/media_router/media_router_ui_unittest.cc index c78330f..fc060f3 100644 --- a/chrome/browser/ui/media_router/media_router_ui_unittest.cc +++ b/chrome/browser/ui/media_router/media_router_ui_unittest.cc
@@ -181,14 +181,13 @@ ui_->OnRoutesUpdated(routes); } - void StartTabCasting(bool is_incognito) { + void StartTabCasting() { MediaSource media_source = MediaSource::ForTab( sessions::SessionTabHelper::IdForTab(web_contents()).id()); MediaRouteResponseCallback callback; - EXPECT_CALL( - *mock_router_, - CreateRouteInternal(media_source.id(), kSinkId, _, web_contents(), _, - base::Seconds(60), is_incognito)) + EXPECT_CALL(*mock_router_, + CreateRouteInternal(media_source.id(), kSinkId, _, + web_contents(), _, base::Seconds(60))) .WillOnce(SaveArgWithMove<4>(&callback)); MediaSink sink{CreateCastSink(kSinkId, kSinkName)}; for (MediaSinksObserver* sinks_observer : media_sinks_observers_) @@ -216,9 +215,9 @@ MediaSink sink{CreateCastSink(kSinkId, kSinkName)}; ui_->OnSinksUpdated({{sink, {cast_mode}}}); MediaRouteResponseCallback callback; - EXPECT_CALL(*mock_router_, - CreateRouteInternal(_, _, _, _, _, - base::Seconds(timeout_seconds), false)) + EXPECT_CALL( + *mock_router_, + CreateRouteInternal(_, _, _, _, _, base::Seconds(timeout_seconds))) .WillOnce(SaveArgWithMove<4>(&callback)); for (MediaSinksObserver* sinks_observer : media_sinks_observers_) sinks_observer->OnSinksUpdated({sink}, std::vector<url::Origin>()); @@ -389,7 +388,7 @@ } TEST_F(MediaRouterViewsUITest, StartCasting) { - StartTabCasting(false); + StartTabCasting(); } TEST_F(MediaRouterViewsUITest, StopCasting) {
diff --git a/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc b/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc index 1626078..1322575 100644 --- a/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc +++ b/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc
@@ -132,6 +132,10 @@ return std::move(image_query_); } +bool CompanionTabHelper::HasImageQuery() { + return image_query_ != nullptr; +} + std::string CompanionTabHelper::GetTextQuery() { std::string copy = text_query_; text_query_.clear();
diff --git a/chrome/browser/ui/side_panel/companion/companion_tab_helper.h b/chrome/browser/ui/side_panel/companion/companion_tab_helper.h index 5374633..c15a7e9 100644 --- a/chrome/browser/ui/side_panel/companion/companion_tab_helper.h +++ b/chrome/browser/ui/side_panel/companion/companion_tab_helper.h
@@ -108,6 +108,7 @@ // Returns the latest image data saved to the helper and not passed to the // handler or an empty pointer if none. std::unique_ptr<side_panel::mojom::ImageQuery> GetImageQuery(); + bool HasImageQuery(); // Returns the most recently set start time for the text query entry point. std::unique_ptr<base::Time> GetTextQueryStartTime();
diff --git a/chrome/browser/ui/tabs/organization/tab_organization_request.cc b/chrome/browser/ui/tabs/organization/tab_organization_request.cc index f11a65d..d34a745 100644 --- a/chrome/browser/ui/tabs/organization/tab_organization_request.cc +++ b/chrome/browser/ui/tabs/organization/tab_organization_request.cc
@@ -15,7 +15,7 @@ std::vector<TabData::TabID> tabs_) : label(label_), tabs(tabs_) {} TabOrganizationResponse::Organization::Organization( - Organization& organization) = default; + const Organization& organization) = default; TabOrganizationResponse::Organization::~Organization() = default; TabOrganizationResponse::TabOrganizationResponse(
diff --git a/chrome/browser/ui/tabs/organization/tab_organization_request.h b/chrome/browser/ui/tabs/organization/tab_organization_request.h index 9e6444a..c539da64 100644 --- a/chrome/browser/ui/tabs/organization/tab_organization_request.h +++ b/chrome/browser/ui/tabs/organization/tab_organization_request.h
@@ -17,7 +17,7 @@ struct Organization { explicit Organization(std::u16string label_, std::vector<TabData::TabID> tabs_); - Organization(Organization& organization); + Organization(const Organization& organization); ~Organization(); const std::u16string label;
diff --git a/chrome/browser/ui/views/commerce/price_insights_icon_view.cc b/chrome/browser/ui/views/commerce/price_insights_icon_view.cc index 5f4dbae..8acceda 100644 --- a/chrome/browser/ui/views/commerce/price_insights_icon_view.cc +++ b/chrome/browser/ui/views/commerce/price_insights_icon_view.cc
@@ -6,6 +6,7 @@ #include "base/metrics/histogram_functions.h" #include "base/timer/timer.h" +#include "chrome/browser/feature_engagement/tracker_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h" @@ -87,17 +88,28 @@ } bool PriceInsightsIconView::MaybeShowPageActionLabel() { - auto* tab_helper = - commerce::ShoppingListUiTabHelper::FromWebContents(GetWebContents()); + if (!base::FeatureList::IsEnabled(commerce::kCommerceAllowChipExpansion)) { + return false; + } - if (!tab_helper || tab_helper->GetPageActionToExpand() != - PageActionIconType::kPriceInsights) { + auto* tracker = + feature_engagement::TrackerFactory::GetForBrowserContext(profile_); + + if (!tracker || + !tracker->ShouldTriggerHelpUI( + feature_engagement::kIPHPriceInsightsPageActionIconLabelFeature)) { return false; } should_extend_label_shown_duration_ = true; AnimateIn(absl::nullopt); + // Note that `Dismiss()` in this case does not dismiss the UI. It's telling + // the FE backend that the promo is done so that other promos can run. Showing + // the label should not block other promos from displaying. + tracker->Dismissed( + feature_engagement::kIPHPriceInsightsPageActionIconLabelFeature); + return true; }
diff --git a/chrome/browser/ui/views/commerce/price_insights_icon_view_browsertest.cc b/chrome/browser/ui/views/commerce/price_insights_icon_view_browsertest.cc index e235e59a..4bc69f8 100644 --- a/chrome/browser/ui/views/commerce/price_insights_icon_view_browsertest.cc +++ b/chrome/browser/ui/views/commerce/price_insights_icon_view_browsertest.cc
@@ -28,6 +28,11 @@ class PriceInsightsIconViewBrowserTest : public UiBrowserTest { public: + PriceInsightsIconViewBrowserTest() { + test_features_.InitWithFeatures( + {commerce::kPriceInsights, commerce::kCommerceAllowChipExpansion}, {}); + } + // UiBrowserTest: void PreShow() override { MockShoppingListUiTabHelper::CreateForWebContents( @@ -86,7 +91,7 @@ } private: - base::test::ScopedFeatureList test_features_{commerce::kPriceInsights}; + base::test::ScopedFeatureList test_features_; BrowserView* GetBrowserView() { return BrowserView::GetBrowserViewForBrowser(browser());
diff --git a/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc index b8db020..7719349 100644 --- a/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc
@@ -43,6 +43,11 @@ class PriceInsightsIconViewInteractiveTest : public InteractiveBrowserTest { public: + PriceInsightsIconViewInteractiveTest() { + test_features_.InitWithFeatures( + {commerce::kCommerceAllowChipExpansion, commerce::kPriceInsights}, {}); + } + void SetUp() override { set_open_about_blank_on_browser_launch(true); ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); @@ -91,7 +96,7 @@ bool is_browser_context_services_created{false}; private: - base::test::ScopedFeatureList test_features_{commerce::kPriceInsights}; + base::test::ScopedFeatureList test_features_; void SetUpTabHelperAndShoppingService() { EXPECT_TRUE(is_browser_context_services_created);
diff --git a/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc b/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc index c7d72fc9..76b6ce7e 100644 --- a/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc +++ b/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc
@@ -8,6 +8,7 @@ #include "base/timer/timer.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/commerce/shopping_service_factory.h" +#include "chrome/browser/feature_engagement/tracker_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/bookmarks/bookmark_utils.h" #include "chrome/browser/ui/browser.h" @@ -317,16 +318,26 @@ } void PriceTrackingIconView::MaybeShowPageActionLabel() { - auto* tab_helper = - commerce::ShoppingListUiTabHelper::FromWebContents(GetWebContents()); + if (!base::FeatureList::IsEnabled(commerce::kCommerceAllowChipExpansion)) { + return; + } - if (!tab_helper || tab_helper->GetPageActionToExpand() != - PageActionIconType::kPriceTracking) { + auto* tracker = + feature_engagement::TrackerFactory::GetForBrowserContext(profile_); + if (!tracker || + !tracker->ShouldTriggerHelpUI( + feature_engagement::kIPHPriceTrackingPageActionIconLabelFeature)) { return; } should_extend_label_shown_duration_ = true; AnimateIn(absl::nullopt); + + // Note that `Dismiss()` in this case does not dismiss the UI. It's telling + // the FE backend that the promo is done so that other promos can run. Showing + // the label should not block other promos from displaying. + tracker->Dismissed( + feature_engagement::kIPHPriceTrackingPageActionIconLabelFeature); } void PriceTrackingIconView::HidePageActionLabel() {
diff --git a/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc index e9eda81..9c81c8fa 100644 --- a/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc
@@ -60,7 +60,7 @@ public: PriceTrackingIconViewInteractiveTest() { test_features_.InitAndEnableFeatures( - {commerce::kShoppingList, + {commerce::kCommerceAllowChipExpansion, commerce::kShoppingList, feature_engagement::kIPHPriceTrackingInSidePanelFeature}, {commerce::kPriceInsights, commerce::kShoppingCollection}); }
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc index 7b42760d..d1e966d 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
@@ -6,7 +6,6 @@ #include "base/files/file_path.h" #include "base/functional/callback.h" -#include "base/metrics/histogram_functions.h" #include "base/time/time.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/app/vector_icons/vector_icons.h" @@ -725,7 +724,6 @@ DownloadItemWarningData::WarningAction::OPEN_SUBPAGE); navigation_handler_->OpenSecurityDialog(model_->GetContentId()); } else { - RecordDownloadOpenButtonPressed(model_->IsDone()); model_->OpenDownload(); } }
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index e289cb2..2b3b674 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -1180,7 +1180,6 @@ if (mode_ == download::DownloadItemMode::kNormal) { complete_animation_.End(); announce_accessible_alert_soon_ = true; - RecordDownloadOpenButtonPressed(model_->IsDone()); model_->OpenDownload(); // WARNING: |this| may be deleted! } else {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 662cdf5..bf1e1bf 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -322,7 +322,9 @@ // first so that they appear on the left side of the icon container. // TODO(crbug.com/1318890): Improve the ordering heuristics for page action // icons and determine a way to handle simultaneous icon animations. - params.types_enabled.push_back(PageActionIconType::kPriceInsights); + if (base::FeatureList::IsEnabled(commerce::kPriceInsights)) { + params.types_enabled.push_back(PageActionIconType::kPriceInsights); + } params.types_enabled.push_back(PageActionIconType::kPriceTracking); if (side_search::IsEnabledForBrowser(browser_)) {
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc index 2aea3a0..3c406347 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
@@ -445,6 +445,8 @@ if (request.method == net::test_server::HttpMethod::METHOD_POST) { net::GetValueForKeyInQuery(url, "sourcelang", &last_sourcelang_); net::GetValueForKeyInQuery(url, "targetlang", &last_targetlang_); + net::GetValueForKeyInQuery(url, "vpw", &last_viewport_width_param_); + net::GetValueForKeyInQuery(url, "vph", &last_viewport_height_param_); } return nullptr; } @@ -460,6 +462,26 @@ std::string GetLastTargetLang() { return last_targetlang_; } + int GetLastViewportWidthParam() { + if (last_viewport_width_param_.empty()) { + return 0; + } + + int viewport_width; + base::StringToInt(last_viewport_width_param_, &viewport_width); + return viewport_width; + } + + int GetLastViewportHeightParam() { + if (last_viewport_height_param_.empty()) { + return 0; + } + + int viewport_height; + base::StringToInt(last_viewport_height_param_, &viewport_height); + return viewport_height; + } + companion::proto::CompanionUrlParams DeserializeCompanionRequest( const std::string& companion_url_param) { std::string serialized_proto; @@ -653,6 +675,8 @@ size_t requests_received_on_server_ = 0; std::string last_sourcelang_; std::string last_targetlang_; + std::string last_viewport_width_param_; + std::string last_viewport_height_param_; bool enable_feature_side_panel_companion_ = true; bool enable_feature_visual_search_ = true; bool enable_feature_lens_standalone_ = true; @@ -1679,6 +1703,9 @@ // The language params should be unset when is_image_translate=false. EXPECT_EQ(GetLastSourceLang(), ""); EXPECT_EQ(GetLastTargetLang(), ""); + // The viewport dimension params should be set to a value + EXPECT_TRUE(GetLastViewportHeightParam() > 0); + EXPECT_TRUE(GetLastViewportWidthParam() > 0); histogram_tester_->ExpectBucketCount("Companion.SidePanel.ShowUiSuccess", true, 1); }
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc index 760ef00..afcb98b 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc
@@ -323,6 +323,24 @@ } } +void CompanionSidePanelController::FrameSizeChanged( + content::RenderFrameHost* render_frame_host, + const gfx::Size& frame_size) { + // We need to wait for the WebContents to have bounds before issuing the Lens + // request. This method gets notified once the WebContents has bounds, so we + // can issue the Lens request. + if (render_frame_host && !render_frame_host->GetParent()) { + auto* tab_helper = + companion::CompanionTabHelper::FromWebContents(web_contents_); + std::unique_ptr<side_panel::mojom::ImageQuery> image_query = + tab_helper->GetImageQuery(); + if (!image_query) { + return; + } + tab_helper->GetCompanionPageHandler()->OnImageQuery(*image_query); + } +} + void CompanionSidePanelController::NotifyLinkClick( GURL opened_url, side_panel::mojom::LinkOpenMetadataPtr metadata,
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h index a0ce38c..a426270 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h
@@ -81,6 +81,8 @@ ui::PageTransition transition, bool started_from_context_menu, bool renderer_initiated) override; + void FrameSizeChanged(content::RenderFrameHost* render_frame_host, + const gfx::Size& frame_size) override; void AddObserver(); void RemoveObserver();
diff --git a/chrome/browser/ui/views/toolbar/toolbar_controller.cc b/chrome/browser/ui/views/toolbar/toolbar_controller.cc index d2ac340..dfcbc38 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_controller.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_controller.cc
@@ -36,11 +36,9 @@ ->WithOrder(element_flex_order_start++); toolbar_element->SetProperty(views::kFlexBehaviorKey, flex_spec); } - - UpdateOverflowButtonVisibility(); } -void ToolbarController::UpdateOverflowButtonVisibility() { +bool ToolbarController::ShouldShowOverflowButton() { // Once at least one button has been dropped by layout manager show overflow // button. const views::FlexLayout* flex_layout = static_cast<views::FlexLayout*>( @@ -54,7 +52,7 @@ break; } } - overflow_button_->SetVisible(show_button); + return show_button; } const views::View* ToolbarController::FindToolbarElementWithId(
diff --git a/chrome/browser/ui/views/toolbar/toolbar_controller.h b/chrome/browser/ui/views/toolbar/toolbar_controller.h index 4e758eaf..19f54df 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_controller.h +++ b/chrome/browser/ui/views/toolbar/toolbar_controller.h
@@ -24,10 +24,16 @@ ToolbarController& operator=(const ToolbarController&) = delete; ~ToolbarController(); - void UpdateOverflowButtonVisibility(); + // Returns true if layout manager of `toolbar_container_view_` hides any + // toolbar elements. + bool ShouldShowOverflowButton(); + + void SetOverflowButtonVisible(bool should_show) { + overflow_button_->SetVisible(should_show); + } private: - FRIEND_TEST_ALL_PREFIXES(ToolbarControllerTest, FlexOrderCorrect); + friend class ToolbarControllerTest; // Searches for a toolbar element from `toolbar_container_view_` with `id`. views::View* FindToolbarElementWithId(ui::ElementIdentifier id) {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc index 1acb16d..7f70f87e 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc
@@ -14,31 +14,182 @@ #include "content/public/test/browser_test_utils.h" #include "ui/views/view_class_properties.h" +namespace { +constexpr int kBrowserContentAllowedMinimumWidth = + BrowserViewLayout::kMainBrowserContentsMinimumWidth; +} // namespace + class ToolbarControllerTest : public InteractiveBrowserTest { public: ToolbarControllerTest() { scoped_feature_list_.InitWithFeatures({features::kResponsiveToolbar}, {}); } + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + browser_view_ = BrowserView::GetBrowserViewForBrowser(browser()); + toolbar_controller_ = const_cast<ToolbarController*>( + browser_view_->toolbar()->toolbar_controller()); + toolbar_container_view_ = const_cast<views::View*>( + toolbar_controller_->toolbar_container_view_.get()); + overflow_button_ = toolbar_controller_->overflow_button_; + dummy_button_size_ = overflow_button_->GetPreferredSize(); + element_ids_ = toolbar_controller_->element_ids_; + element_flex_order_start_ = toolbar_controller_->element_flex_order_start_; + MaybeAddDummyButtonsToToolbarView(); + overflow_threshold_width_ = GetOverflowThresholdWidth(); + } + + void TearDownOnMainThread() override { + toolbar_container_view_ = nullptr; + overflow_button_ = nullptr; + toolbar_controller_ = nullptr; + browser_view_ = nullptr; + InProcessBrowserTest::TearDownOnMainThread(); + } + + // Returns the minimum width the toolbar view can be without any elements + // dropped out. + int GetOverflowThresholdWidth() { + int diff_sum = 0; + for (auto* element : toolbar_container_view_->children()) { + diff_sum += element->GetPreferredSize().width() - + element->GetMinimumSize().width(); + + // TODO(crbug.com/1479588): Ignore containers till issue addressed. + // This case only applies to containers. Now that containers are ignored + // their main items (i.e. extensions button, side panel button) width is + // excluded from the calculation too. So is the margin. + if (element->GetMinimumSize().width() == 0 && + element->GetPreferredSize().width() > 0) { + diff_sum += GetLayoutConstant(TOOLBAR_ICON_DEFAULT_MARGIN); + } + } + return toolbar_container_view_->GetPreferredSize().width() - diff_sum; + } + + // Because actual_browser_minimum_width == Max(toolbar_width, + // kBrowserContentAllowedMinimumWidth) So if `overflow_threshold_width_` < + // kBrowserContentAllowedMinimumWidth, then actual_browser_minimum_width == + // kBrowserContentAllowedMinimumWidth In this case we will never see any + // overflow so stuff toolbar with some fixed dummy buttons till it's + // guaranteed we can observe overflow with browser resized to its minimum + // width. + void MaybeAddDummyButtonsToToolbarView() { + while (GetOverflowThresholdWidth() <= kBrowserContentAllowedMinimumWidth) { + auto button = std::make_unique<ToolbarButton>(); + button->SetPreferredSize(dummy_button_size_); + button->SetMinSize(dummy_button_size_); + button->SetAccessibleName(u"dummybutton"); + button->SetVisible(true); + toolbar_container_view_->AddChildView(std::move(button)); + } + } + + void SetBrowserWithWidth(int width) { + browser_view_->SetSize({width, browser_view_->size().height()}); + } + + const views::View* FindToolbarElementWithId(ui::ElementIdentifier id) const { + return toolbar_controller_->FindToolbarElementWithId(id); + } + + const views::View* overflow_button() const { return overflow_button_; } + int element_flex_order_start() const { return element_flex_order_start_; } + const std::vector<ui::ElementIdentifier>& element_ids() const { + return element_ids_; + } + int overflow_threshold_width() const { return overflow_threshold_width_; } + private: base::test::ScopedFeatureList scoped_feature_list_; + raw_ptr<BrowserView> browser_view_; + raw_ptr<ToolbarController> toolbar_controller_; + raw_ptr<views::View> toolbar_container_view_; + raw_ptr<views::View> overflow_button_; + std::vector<ui::ElementIdentifier> element_ids_; + int element_flex_order_start_; + gfx::Size dummy_button_size_; + + // The minimum width the toolbar view can be without any elements dropped out. + int overflow_threshold_width_; }; IN_PROC_BROWSER_TEST_F(ToolbarControllerTest, FlexOrderCorrect) { - const ToolbarController* toolbar_controller = - BrowserView::GetBrowserViewForBrowser(browser()) - ->toolbar() - ->toolbar_controller(); - const std::vector<ui::ElementIdentifier> element_ids = - toolbar_controller->element_ids_; - int element_flex_order_start = toolbar_controller->element_flex_order_start_; - - for (ui::ElementIdentifier id : element_ids) { - const views::View* toolbar_element = - toolbar_controller->FindToolbarElementWithId(id); + int order_start = element_flex_order_start(); + for (ui::ElementIdentifier id : element_ids()) { + const views::View* toolbar_element = FindToolbarElementWithId(id); if (toolbar_element) { - EXPECT_EQ(element_flex_order_start++, + EXPECT_EQ(order_start++, toolbar_element->GetProperty(views::kFlexBehaviorKey)->order()); } } } + +IN_PROC_BROWSER_TEST_F(ToolbarControllerTest, StartBrowserWithThresholdWidth) { + // Start browser with threshold width. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width()); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser a bit wider. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width() + 1); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser back to threshold width. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width()); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser a bit narrower. Should see overflow. + SetBrowserWithWidth(overflow_threshold_width() - 1); + EXPECT_TRUE(overflow_button()->GetVisible()); + + // Resize browser back to threshold width. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width()); + EXPECT_FALSE(overflow_button()->GetVisible()); +} + +IN_PROC_BROWSER_TEST_F(ToolbarControllerTest, + StartBrowserWithWidthSmallerThanThreshold) { + // Start browser with a smaller width than threshold. Should see overflow. + SetBrowserWithWidth(overflow_threshold_width() - 1); + EXPECT_TRUE(overflow_button()->GetVisible()); + + // Resize browser wider to threshold width. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width()); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser a bit narrower. Should see overflow. + SetBrowserWithWidth(overflow_threshold_width() - 1); + EXPECT_TRUE(overflow_button()->GetVisible()); + + // Keep resizing browser narrower. Should see overflow. + SetBrowserWithWidth(overflow_threshold_width() - 2); + EXPECT_TRUE(overflow_button()->GetVisible()); + + // Resize browser a bit wider. Should still see overflow. + SetBrowserWithWidth(overflow_threshold_width() - 1); + EXPECT_TRUE(overflow_button()->GetVisible()); +} + +IN_PROC_BROWSER_TEST_F(ToolbarControllerTest, + StartBrowserWithWidthLargerThanThreshold) { + // Start browser with a larger width than threshold. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width() + 1); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser wider. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width() + 2); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser a bit narrower. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width() + 1); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser back to threshold width. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width()); + EXPECT_FALSE(overflow_button()->GetVisible()); + + // Resize browser a bit wider. Should not see overflow. + SetBrowserWithWidth(overflow_threshold_width() + 1); + EXPECT_FALSE(overflow_button()->GetVisible()); +}
diff --git a/chrome/browser/ui/views/toolbar/toolbar_controller_unittest.cc b/chrome/browser/ui/views/toolbar/toolbar_controller_unittest.cc index 058ed0b..e2f50ea 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_controller_unittest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_controller_unittest.cc
@@ -63,7 +63,7 @@ EXPECT_TRUE(button1.GetVisible()); EXPECT_TRUE(button2.GetVisible()); EXPECT_TRUE(button3.GetVisible()); - controller.UpdateOverflowButtonVisibility(); + controller.SetOverflowButtonVisible(controller.ShouldShowOverflowButton()); EXPECT_FALSE(overflow_button.GetVisible()); // One button overflows. @@ -73,6 +73,6 @@ EXPECT_FALSE(button3.GetVisible()); // Overflow button appears. - controller.UpdateOverflowButtonVisibility(); + controller.SetOverflowButtonVisible(controller.ShouldShowOverflowButton()); EXPECT_TRUE(overflow_button.GetVisible()); }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index 3f327f10..5ae06b7 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -785,13 +785,25 @@ } } + // Use two-pass layout solution to avoid overflow button being interfere with + // toolbar elements space allocation. The button itself should just be an + // indicator of overflow not the cause. (See crbug.com/1484294) + // In the first pass turn off overflow button right before each layout. + // TODO(pengchaocai): Explore possible optimizations. if (base::FeatureList::IsEnabled(features::kResponsiveToolbar)) { - toolbar_controller_->UpdateOverflowButtonVisibility(); + toolbar_controller_->SetOverflowButtonVisible(false); } // Call super implementation to ensure layout manager and child layouts // happen. AccessiblePaneView::Layout(); + + if (base::FeatureList::IsEnabled(features::kResponsiveToolbar) && + toolbar_controller_->ShouldShowOverflowButton()) { + // This is the second pass layout that shows overflow button if necessary. + toolbar_controller_->SetOverflowButtonVisible(true); + AccessiblePaneView::Layout(); + } } void ToolbarView::OnThemeChanged() { @@ -858,12 +870,18 @@ // TODO(dfried): rename this constant. const int location_bar_margin = GetLayoutConstant(TOOLBAR_STANDARD_SPACING); + // Shift previously flex-able elements' order by `kOrderOffset`. + // This will cause them to be the first ones to drop out or shrink to minimum. + // Order 1 - kOrderOffset will be assigned to new flex-able elements. + constexpr int kOrderOffset = 1000; + constexpr int kLocationBarFlexOrder = kOrderOffset + 1; + constexpr int kSidePanelFlexOrder = kOrderOffset + 2; + constexpr int kExtensionsFlexOrder = kOrderOffset + 3; + const views::FlexSpecification location_bar_flex_rule = views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum, views::MaximumFlexSizeRule::kUnbounded) - .WithOrder(1); - constexpr int kSidePanelFlexOrder = 2; - constexpr int kExtensionsFlexOrder = 3; + .WithOrder(kLocationBarFlexOrder); layout_manager_ = container_view_->SetLayoutManager(std::make_unique<views::FlexLayout>()); @@ -905,15 +923,14 @@ } if (base::FeatureList::IsEnabled(features::kResponsiveToolbar)) { - // Order 1 is reserved for omnibox and transient buttons. + // Order 1 is reserved for transient buttons. constexpr int kToolbarFlexOrderStart = 2; + // TODO(crbug.com/1479588): Ignore containers till issue addressed. toolbar_controller_ = std::make_unique<ToolbarController>( std::vector<ui::ElementIdentifier>{ kToolbarForwardButtonElementId, kToolbarAvatarButtonElementId, - kToolbarExtensionsContainerElementId, - kToolbarSidePanelContainerElementId, kToolbarHomeButtonElementId, - kToolbarChromeLabsButtonElementId}, + kToolbarHomeButtonElementId, kToolbarChromeLabsButtonElementId}, kToolbarFlexOrderStart, container_view_, overflow_button_); }
diff --git a/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler_unittest.cc b/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler_unittest.cc index 6b2200f..f4cb382b 100644 --- a/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler_unittest.cc +++ b/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler_unittest.cc
@@ -219,7 +219,7 @@ EXPECT_CALL(*router(), CreateRouteInternal(source.id(), cast_sink_1().sink().id(), _, - web_contents(), _, timeout, false)); + web_contents(), _, timeout)); handler()->CastToSink(mock_callback.Get()); } @@ -240,7 +240,7 @@ EXPECT_CALL(*router(), CreateRouteInternal(source.id(), cast_sink_1().sink().id(), request.frame_origin, web_contents(), _, - base::Seconds(20), false)); + base::Seconds(20))); handler()->CastToSink(mock_callback.Get()); } @@ -299,13 +299,13 @@ // Handler so MockMediaRouter will respond to requests to create a route. // Will construct a RouteRequestResult based on the set result code and // then call the handler's callback, which should call the page's callback. - ON_CALL(*router(), CreateRouteInternal(_, _, _, _, _, _, _)) + ON_CALL(*router(), CreateRouteInternal(_, _, _, _, _, _)) .WillByDefault([this](const MediaSource::Id& source_id, const MediaSink::Id& sink_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback& callback, - base::TimeDelta timeout, bool incognito) { + base::TimeDelta timeout) { std::unique_ptr<RouteRequestResult> result; if (result_code_ == mojom::RouteRequestResultCode::OK) { MediaSource source(source_id);
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/BUILD.gn b/chrome/browser/ui/webui/ash/enterprise_reporting/BUILD.gn new file mode 100644 index 0000000..bf440b3 --- /dev/null +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/BUILD.gn
@@ -0,0 +1,13 @@ +# Copyright 2023 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//mojo/public/tools/bindings/mojom.gni") + +assert(is_chromeos_ash, "Enterprise Reporting WebUI is ChromeOS Ash only.") + +mojom("mojo_bindings") { + sources = [ "enterprise_reporting.mojom" ] + webui_module_path = "/" + use_typescript_sources = true +}
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom new file mode 100644 index 0000000..94c9342 --- /dev/null +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom
@@ -0,0 +1,56 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module enterprise_reporting.mojom; + +// ErpHistoryData represents chunk of ERP history. +struct ErpHistoryData { + array<ErpHistoryEvent> events; +}; + +// ErpHistoryEvent represents the various events the ERP can record. +struct ErpHistoryEvent { + // Name of the call. + string call; + // Parameters passed to the call. + array<ErpHistoryEventParameter> parameters; + // Status of the call returned. + string status; + // Timestamp of when the call was made. + int64 time; +}; + +// HistoryEventParameter represents one parameter from a dbus call from missive. +struct ErpHistoryEventParameter { + // Name of the parameter. + string name; + // The value provided for the parameter. + string value; +}; + +// This interface can be used to update information displayed on the reporting +// page. +interface PageHandlerFactory { + // Creates a page handler to update and respond to requests. + CreatePageHandler(pending_remote<Page> page, + pending_receiver<PageHandler> handler); +}; + +// Called from TS side of chrome://enterprise-reporting (Renderer -> Browser) +interface PageHandler { + // Records debug state. + RecordDebugState(bool state); + + // Reads debug state. + GetDebugState() => (bool state); + + // Reads collected history. + GetErpHistoryData() => (ErpHistoryData history_data); +}; + +// Called from C++ side of chrome://enterprise-reporting. (Browser -> Renderer) +interface Page { + // Provide the reporting page with new DBus call history. + SetErpHistoryData(ErpHistoryData history_data); +};
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.cc b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.cc new file mode 100644 index 0000000..3726419 --- /dev/null +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.cc
@@ -0,0 +1,84 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.h" + +#include "base/memory/scoped_refptr.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.h" +#include "chromeos/dbus/missive/history_tracker.h" +#include "components/reporting/proto/synced/health.pb.h" +#include "components/reporting/proto/synced/status.pb.h" +#include "components/reporting/util/status.h" + +namespace ash::reporting { + +// static +std::unique_ptr<EnterpriseReportingPageHandler, base::OnTaskRunnerDeleter> +EnterpriseReportingPageHandler::Create( + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandler> receiver, + mojo::PendingRemote<enterprise_reporting::mojom::Page> page) { + // Ensure sequencing for `EnterpriseReportingPageHandler` in order to make it + // capable of using weak pointers. + return std::unique_ptr<EnterpriseReportingPageHandler, + base::OnTaskRunnerDeleter>( + new EnterpriseReportingPageHandler(std::move(receiver), std::move(page)), + base::OnTaskRunnerDeleter( + base::SequencedTaskRunner::GetCurrentDefault())); +} + +EnterpriseReportingPageHandler::EnterpriseReportingPageHandler( + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandler> receiver, + mojo::PendingRemote<enterprise_reporting::mojom::Page> page) + : enterprise_reporting::mojom::PageHandler(), + sequenced_task_runner_(base::SequencedTaskRunner::GetCurrentDefault()), + receiver_(this, std::move(receiver)), + page_(std::move(page)) { + ::reporting::HistoryTracker::Get()->AddObserver(this); +} + +EnterpriseReportingPageHandler::~EnterpriseReportingPageHandler() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ::reporting::HistoryTracker::Get()->RemoveObserver(this); +} + +void EnterpriseReportingPageHandler::RecordDebugState(bool state) { + ::reporting::HistoryTracker::Get()->set_debug_state(state); +} + +void EnterpriseReportingPageHandler::GetDebugState(GetDebugStateCallback cb) { + std::move(cb).Run(::reporting::HistoryTracker::Get()->debug_state()); +} + +void EnterpriseReportingPageHandler::GetErpHistoryData( + GetErpHistoryDataCallback cb) { + auto convert_cb = base::BindOnce( + [](GetErpHistoryDataCallback cb, const ::reporting::ERPHealthData& data) { + std::move(cb).Run(ConvertHistory(data)); + }, + std::move(cb)); + ::reporting::HistoryTracker::Get()->retrieve_data(std::move(convert_cb)); +} + +void EnterpriseReportingPageHandler::OnNewData( + const ::reporting::ERPHealthData& data) const { + // Call `page_->SetErpHistoryData` on the right runner, making conversion + // before that. + sequenced_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](base::WeakPtr<const EnterpriseReportingPageHandler> self, + mojo::StructPtr<enterprise_reporting::mojom::ErpHistoryData> + history_data) { + if (!self) { + return; + } + DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_); + self->page_->SetErpHistoryData(std::move(history_data)); + }, + weak_ptr_factory_.GetWeakPtr(), ConvertHistory(data))); +} +} // namespace ash::reporting
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.h b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.h new file mode 100644 index 0000000..c0d76f8e --- /dev/null +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.h
@@ -0,0 +1,63 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_ENTERPRISE_REPORTING_PAGE_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_ENTERPRISE_REPORTING_PAGE_HANDLER_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chromeos/dbus/missive/history_tracker.h" +#include "components/reporting/proto/synced/health.pb.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace ash::reporting { + +class EnterpriseReportingPageHandler + : public enterprise_reporting::mojom::PageHandler, + public ::reporting::HistoryTracker::Observer { + public: + // Create `EnterpriseReportingPageHandler` to be on-thread destructed, + // in order to make it capable of using weak pointers. + static std::unique_ptr<EnterpriseReportingPageHandler, + base::OnTaskRunnerDeleter> + Create( + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandler> receiver, + mojo::PendingRemote<enterprise_reporting::mojom::Page> page); + + EnterpriseReportingPageHandler(const EnterpriseReportingPageHandler&) = + delete; + EnterpriseReportingPageHandler& operator=( + const EnterpriseReportingPageHandler&) = delete; + + ~EnterpriseReportingPageHandler() override; + + // enterprise_reporting::mojom::PageHandler: + void RecordDebugState(bool state) override; + void GetDebugState(GetDebugStateCallback cb) override; + void GetErpHistoryData(GetErpHistoryDataCallback cb) override; + + // ::reporting::HistoryTracker::Observer: + void OnNewData(const ::reporting::ERPHealthData& data) const override; + + private: + // Constructor to be called by `Create` factory only. + EnterpriseReportingPageHandler( + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandler> receiver, + mojo::PendingRemote<enterprise_reporting::mojom::Page> page); + + SEQUENCE_CHECKER(sequence_checker_); + const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; + + const mojo::Receiver<enterprise_reporting::mojom::PageHandler> receiver_; + const mojo::Remote<enterprise_reporting::mojom::Page> page_; + + base::WeakPtrFactory<EnterpriseReportingPageHandler> weak_ptr_factory_{this}; +}; +} // namespace ash::reporting + +#endif // CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_ENTERPRISE_REPORTING_PAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.cc b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.cc index 5ae143dd..9c65c11 100644 --- a/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.cc +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.cc
@@ -6,6 +6,8 @@ #include "ash/constants/ash_features.h" #include "base/containers/span.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/enterprise_reporting_resources.h" @@ -14,11 +16,12 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#include "ui/webui/mojo_web_ui_controller.h" namespace ash::reporting { EnterpriseReportingUI::EnterpriseReportingUI(content::WebUI* web_ui) - : content::WebUIController(web_ui) { + : ui::MojoWebUIController(web_ui) { DCHECK(base::FeatureList::IsEnabled(ash::features::kEnterpriseReportingUI)); // Set up the chrome://enterprise-reporting source. content::WebUIDataSource* html_source = @@ -41,4 +44,24 @@ return base::FeatureList::IsEnabled(ash::features::kEnterpriseReportingUI); } +WEB_UI_CONTROLLER_TYPE_IMPL(EnterpriseReportingUI) + +void EnterpriseReportingUI::BindInterface( + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandlerFactory> + receiver) { + // Instantiates the implementor of the mojom::PageHandlerFactory mojo + // interface passing the pending receiver that will be internally bound. + page_factory_receiver_.reset(); + page_factory_receiver_.Bind(std::move(receiver)); +} + +void EnterpriseReportingUI::CreatePageHandler( + mojo::PendingRemote<enterprise_reporting::mojom::Page> page, + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandler> receiver) { + DCHECK(page); + // Ensure sequencing for `EnterpriseReportingPageHandler` in order to make it + // capable of using weak pointers. + page_handler_ = EnterpriseReportingPageHandler::Create(std::move(receiver), + std::move(page)); +} } // namespace ash::reporting
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.h b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.h index e343868..ea765b80 100644 --- a/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.h +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.h
@@ -6,9 +6,11 @@ #define CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_ENTERPRISE_REPORTING_UI_H_ #include "ash/webui/common/chrome_os_webui_config.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_page_handler.h" #include "chrome/common/webui_url_constants.h" -#include "content/public/browser/web_ui_controller.h" #include "content/public/common/url_constants.h" +#include "ui/webui/mojo_web_ui_controller.h" namespace ash::reporting { @@ -26,12 +28,32 @@ }; // The WebUI for chrome://enterprise-reporting -class EnterpriseReportingUI : public content::WebUIController { +class EnterpriseReportingUI + : public ui::MojoWebUIController, + public enterprise_reporting::mojom::PageHandlerFactory { public: explicit EnterpriseReportingUI(content::WebUI* web_ui); ~EnterpriseReportingUI() override; -}; + void BindInterface( + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandlerFactory> + receiver); + + private: + // enterprise_reporting::mojom::PageHandlerFactory: + void CreatePageHandler( + mojo::PendingRemote<enterprise_reporting::mojom::Page> page, + mojo::PendingReceiver<enterprise_reporting::mojom::PageHandler> receiver) + override; + + std::unique_ptr<EnterpriseReportingPageHandler, base::OnTaskRunnerDeleter> + page_handler_{nullptr, base::OnTaskRunnerDeleter(nullptr)}; + + mojo::Receiver<enterprise_reporting::mojom::PageHandlerFactory> + page_factory_receiver_{this}; + + WEB_UI_CONTROLLER_TYPE_DECL(); +}; } // namespace ash::reporting #endif // CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_ENTERPRISE_REPORTING_UI_H_
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.cc b/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.cc new file mode 100644 index 0000000..2702315 --- /dev/null +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.cc
@@ -0,0 +1,165 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.h" + +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chromeos/dbus/missive/history_tracker.h" +#include "components/reporting/proto/synced/health.pb.h" +#include "components/reporting/proto/synced/status.pb.h" +#include "components/reporting/util/status.h" + +namespace ash::reporting { +namespace { +std::string StatusFromProto(const ::reporting::StatusProto& source) { + ::reporting::Status status; + status.RestoreFrom(source); + return status.ToString(); +} + +void PopulateStorageQueueAction( + const ::reporting::StorageQueueAction& source, + enterprise_reporting::mojom::ErpHistoryEvent& dest) { + dest.call = "QueueAction"; + switch (source.action_case()) { + case ::reporting::StorageQueueAction::ActionCase::kStorageEnqueue: + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "EnqueueSeqId", + base::NumberToString(source.storage_enqueue().sequencing_id()))); + break; + case ::reporting::StorageQueueAction::ActionCase::kStorageDequeue: + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "DequeueSeqId", + base::NumberToString(source.storage_dequeue().sequencing_id()))); + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "DequeueCount", + base::NumberToString(source.storage_dequeue().records_count()))); + break; + default: + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "UnknownAction", "")); + } + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Priority", ::reporting::Priority_Name(source.priority()))); + dest.status = StatusFromProto(source.status()); +} + +void PopulateEnqueueRecord(const ::reporting::EnqueueRecordCall& source, + enterprise_reporting::mojom::ErpHistoryEvent& dest) { + dest.call = "Enqueue"; + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Priority", ::reporting::Priority_Name(source.priority()))); + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Destination", ::reporting::Destination_Name(source.destination()))); + dest.status = StatusFromProto(source.status()); +} + +void PopulateFlushRecord(const ::reporting::FlushPriorityCall& source, + enterprise_reporting::mojom::ErpHistoryEvent& dest) { + dest.call = "Flush"; + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Priority", ::reporting::Priority_Name(source.priority()))); + dest.status = StatusFromProto(source.status()); +} + +void PopulateConfirmRecord(const ::reporting::ConfirmRecordUploadCall& source, + enterprise_reporting::mojom::ErpHistoryEvent& dest) { + dest.call = "Confirm"; + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Sequencing_id", base::NumberToString(source.sequencing_id()))); + if (source.force_confirm()) { + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Force_confirm", "True")); + } + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Priority", ::reporting::Priority_Name(source.priority()))); + dest.status = StatusFromProto(source.status()); +} + +void PopulateUploadRecord(const ::reporting::UploadEncryptedRecordCall& source, + enterprise_reporting::mojom::ErpHistoryEvent& dest) { + dest.call = "Upload"; + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Reason", source.upload_reason())); + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Priority", ::reporting::Priority_Name(source.priority()))); + for (const auto& item : source.items()) { + switch (item.item_case()) { + case ::reporting::UploadItem::ItemCase::kRecord: + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Record", + base::StrCat({"seq=", base::NumberToString( + item.record().sequencing_id())}))); + break; + case ::reporting::UploadItem::ItemCase::kGap: + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Gap", + base::StrCat( + {"seq=", base::NumberToString(item.gap().sequencing_id()), + " count=", base::NumberToString(item.gap().count())}))); + break; + default: + dest.parameters.emplace_back( + enterprise_reporting::mojom::ErpHistoryEventParameter::New( + "Unknown", "")); + } + } + dest.status = StatusFromProto(source.status()); +} +} // namespace + +mojo::StructPtr<enterprise_reporting::mojom::ErpHistoryData> ConvertHistory( + const ::reporting::ERPHealthData& data) { + auto result = enterprise_reporting::mojom::ErpHistoryData::New(); + for (const auto& history : data.history()) { + result->events.emplace_back( + enterprise_reporting::mojom::ErpHistoryEvent::New()); + result->events.back()->time = history.timestamp_seconds(); + switch (history.record_case()) { + case ::reporting::HealthDataHistory::RecordCase::kEnqueueRecordCall: + PopulateEnqueueRecord(history.enqueue_record_call(), + *result->events.back()); + break; + case ::reporting::HealthDataHistory::RecordCase::kFlushPriorityCall: + PopulateFlushRecord(history.flush_priority_call(), + *result->events.back()); + break; + case ::reporting::HealthDataHistory::RecordCase:: + kUploadEncryptedRecordCall: + PopulateUploadRecord(history.upload_encrypted_record_call(), + *result->events.back()); + break; + case ::reporting::HealthDataHistory::RecordCase::kConfirmRecordUploadCall: + PopulateConfirmRecord(history.confirm_record_upload_call(), + *result->events.back()); + break; + case ::reporting::HealthDataHistory::RecordCase::kStorageQueueAction: + PopulateStorageQueueAction(history.storage_queue_action(), + *result->events.back()); + break; + default: + result->events.back()->call = "UNKNOWN"; + result->events.back()->status = "N/A"; + } + } + return result; +} +} // namespace ash::reporting
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.h b/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.h new file mode 100644 index 0000000..abb5ae99 --- /dev/null +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.h
@@ -0,0 +1,20 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_HISTORY_CONVERTER_H_ +#define CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_HISTORY_CONVERTER_H_ + +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chromeos/dbus/missive/history_tracker.h" +#include "components/reporting/proto/synced/health.pb.h" +#include "components/reporting/proto/synced/status.pb.h" + +namespace ash::reporting { + +mojo::StructPtr<enterprise_reporting::mojom::ErpHistoryData> ConvertHistory( + const ::reporting::ERPHealthData& data); + +} // namespace ash::reporting + +#endif // CHROME_BROWSER_UI_WEBUI_ASH_ENTERPRISE_REPORTING_HISTORY_CONVERTER_H_
diff --git a/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter_unittest.cc b/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter_unittest.cc new file mode 100644 index 0000000..14b7af53 --- /dev/null +++ b/chrome/browser/ui/webui/ash/enterprise_reporting/history_converter_unittest.cc
@@ -0,0 +1,363 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.h" + +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "components/reporting/proto/synced/health.pb.h" +#include "components/reporting/proto/synced/record_constants.pb.h" +#include "components/reporting/proto/synced/status.pb.h" +#include "components/reporting/util/status.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::AllOf; +using ::testing::ElementsAre; +using ::testing::Eq; +using ::testing::Field; +using ::testing::Pair; +using ::testing::Pointee; +using ::testing::SizeIs; +using ::testing::StrEq; +using ::testing::UnorderedElementsAre; + +using ::enterprise_reporting::mojom::ErpHistoryEvent; +using ::enterprise_reporting::mojom::ErpHistoryEventParameter; + +namespace ash::reporting { +namespace { + +TEST(HistoryConverterTest, StorageQueueEnqueueTest) { + ::reporting::ERPHealthData history_data; + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const storage_record = record->mutable_storage_queue_action(); + storage_record->set_priority(::reporting::FAST_BATCH); + ::reporting::Status::StatusOK().SaveTo(storage_record->mutable_status()); + auto* const enqueue_record = storage_record->mutable_storage_enqueue(); + enqueue_record->set_sequencing_id(123L); + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre(Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("QueueAction")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, + StrEq("EnqueueSeqId")), + Field(&ErpHistoryEventParameter::value, StrEq("123")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("FAST_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} + +TEST(HistoryConverterTest, StorageQueueDequeueTest) { + ::reporting::ERPHealthData history_data; + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const storage_record = record->mutable_storage_queue_action(); + storage_record->set_priority(::reporting::FAST_BATCH); + ::reporting::Status::StatusOK().SaveTo(storage_record->mutable_status()); + auto* const dequeue_record = storage_record->mutable_storage_dequeue(); + dequeue_record->set_sequencing_id(123L); + dequeue_record->set_records_count(5); + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre(Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("QueueAction")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, + StrEq("DequeueSeqId")), + Field(&ErpHistoryEventParameter::value, StrEq("123")))), + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, + StrEq("DequeueCount")), + Field(&ErpHistoryEventParameter::value, StrEq("5")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("FAST_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} + +TEST(HistoryConverterTest, EnqueueRecordCallTest) { + ::reporting::ERPHealthData history_data; + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const call_record = record->mutable_enqueue_record_call(); + call_record->set_destination(::reporting::TELEMETRY_METRIC); + call_record->set_priority(::reporting::MANUAL_BATCH); + ::reporting::Status::StatusOK().SaveTo(call_record->mutable_status()); + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre(Pointee( + AllOf(Field(&ErpHistoryEvent::call, StrEq("Enqueue")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Destination")), + Field(&ErpHistoryEventParameter::value, + StrEq("TELEMETRY_METRIC")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} + +TEST(HistoryConverterTest, FlushPriorityCallTest) { + ::reporting::ERPHealthData history_data; + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const flush_record = record->mutable_flush_priority_call(); + flush_record->set_priority(::reporting::MANUAL_BATCH); + ::reporting::Status::StatusOK().SaveTo(flush_record->mutable_status()); + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre(Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("Flush")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre(Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} + +TEST(HistoryConverterTest, UploadEncryptedRecordCallTest) { + ::reporting::ERPHealthData history_data; + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const upload_record = record->mutable_upload_encrypted_record_call(); + upload_record->set_upload_reason("MANUAL"); + upload_record->set_priority(::reporting::MANUAL_BATCH); + ::reporting::Status::StatusOK().SaveTo(upload_record->mutable_status()); + { + auto* const data_item = upload_record->add_items()->mutable_record(); + data_item->set_sequencing_id(123); + } + { + auto* const gap_item = upload_record->add_items()->mutable_gap(); + gap_item->set_sequencing_id(124); + gap_item->set_count(2); + } + { + auto* const data_item = upload_record->add_items()->mutable_record(); + data_item->set_sequencing_id(126); + } + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre(Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("Upload")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, StrEq("Reason")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))), + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, StrEq("Record")), + Field(&ErpHistoryEventParameter::value, + StrEq("seq=123")))), + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, StrEq("Gap")), + Field(&ErpHistoryEventParameter::value, + StrEq("seq=124 count=2")))), + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, StrEq("Record")), + Field(&ErpHistoryEventParameter::value, + StrEq("seq=126")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} + +TEST(HistoryConverterTest, ConfirmCallTest) { + ::reporting::ERPHealthData history_data; + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const confirm_record = record->mutable_confirm_record_upload_call(); + confirm_record->set_sequencing_id(123L); + confirm_record->set_priority(::reporting::MANUAL_BATCH); + ::reporting::Status::StatusOK().SaveTo(confirm_record->mutable_status()); + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre(Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("Confirm")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, + StrEq("Sequencing_id")), + Field(&ErpHistoryEventParameter::value, StrEq("123")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} + +TEST(HistoryConverterTest, ForceConfirmCallTest) { + ::reporting::ERPHealthData history_data; + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const confirm_record = record->mutable_confirm_record_upload_call(); + confirm_record->set_sequencing_id(123L); + confirm_record->set_priority(::reporting::MANUAL_BATCH); + confirm_record->set_force_confirm(true); + ::reporting::Status::StatusOK().SaveTo(confirm_record->mutable_status()); + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre(Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("Confirm")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf( + Field(&ErpHistoryEventParameter::name, + StrEq("Sequencing_id")), + Field(&ErpHistoryEventParameter::value, StrEq("123")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Force_confirm")), + Field(&ErpHistoryEventParameter::value, + StrEq("True")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} + +TEST(HistoryConverterTest, MultipleRecordsTest) { + ::reporting::ERPHealthData history_data; + + { + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const call_record = record->mutable_enqueue_record_call(); + call_record->set_destination(::reporting::TELEMETRY_METRIC); + call_record->set_priority(::reporting::MANUAL_BATCH); + ::reporting::Status::StatusOK().SaveTo(call_record->mutable_status()); + } + + { + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const storage_record = record->mutable_storage_queue_action(); + storage_record->set_priority(::reporting::MANUAL_BATCH); + ::reporting::Status::StatusOK().SaveTo(storage_record->mutable_status()); + auto* const enqueue_record = storage_record->mutable_storage_enqueue(); + enqueue_record->set_sequencing_id(123L); + } + + { + auto* const record = history_data.add_history(); + record->set_timestamp_seconds(9876L); + auto* const upload_record = record->mutable_upload_encrypted_record_call(); + upload_record->set_upload_reason("MANUAL"); + upload_record->set_priority(::reporting::MANUAL_BATCH); + ::reporting::Status::StatusOK().SaveTo(upload_record->mutable_status()); + { + auto* const data_item = upload_record->add_items()->mutable_record(); + data_item->set_sequencing_id(120); + } + { + auto* const gap_item = upload_record->add_items()->mutable_gap(); + gap_item->set_sequencing_id(121); + gap_item->set_count(2); + } + { + auto* const data_item = upload_record->add_items()->mutable_record(); + data_item->set_sequencing_id(123); + } + } + + const auto converted_history = ConvertHistory(history_data); + + EXPECT_THAT( + converted_history->events, + ElementsAre( + Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("Enqueue")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Destination")), + Field(&ErpHistoryEventParameter::value, + StrEq("TELEMETRY_METRIC")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))), + Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("QueueAction")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("EnqueueSeqId")), + Field(&ErpHistoryEventParameter::value, + StrEq("123")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))), + Pointee(AllOf( + Field(&ErpHistoryEvent::call, StrEq("Upload")), + Field(&ErpHistoryEvent::parameters, + UnorderedElementsAre( + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Reason")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Priority")), + Field(&ErpHistoryEventParameter::value, + StrEq("MANUAL_BATCH")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Record")), + Field(&ErpHistoryEventParameter::value, + StrEq("seq=120")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Gap")), + Field(&ErpHistoryEventParameter::value, + StrEq("seq=121 count=2")))), + Pointee(AllOf(Field(&ErpHistoryEventParameter::name, + StrEq("Record")), + Field(&ErpHistoryEventParameter::value, + StrEq("seq=123")))))), + Field(&ErpHistoryEvent::status, StrEq("OK")), + Field(&ErpHistoryEvent::time, Eq(9876)))))); +} +} // namespace +} // namespace ash::reporting
diff --git a/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc b/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc index 992236f3..c1d4578 100644 --- a/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc +++ b/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc
@@ -45,6 +45,7 @@ return section == mojom::Section::kDateAndTime || section == mojom::Section::kFiles || section == mojom::Section::kLanguagesAndInput || + section == mojom::Section::kPrinting || section == mojom::Section::kReset || section == mojom::Section::kSearchAndAssistant; };
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc index 20bf020..81e0020 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -512,7 +512,8 @@ IDS_NTP_MODULES_HISTORY_CLUSTERS_RESUME_BROWSING_FOR}, {"modulesThisTypeOfCardText", IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_TOAST_NAME}, - {"modulesJourneyDisable", IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_TEXT}, + {"modulesJourneyDisable", + IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_DROPDOWN_TEXT}, {"modulesJourneysDismissButton", IDS_NTP_MODULES_HISTORY_CLUSTERS_DISMISS_BUTTON}, {"modulesJourneysDoneButton", @@ -546,14 +547,6 @@ source->AddBoolean("wideModulesEnabled", base::FeatureList::IsEnabled( ntp_features::kNtpWideModules)); - if (base::FeatureList::IsEnabled(history_clusters::kRenameJourneys)) { - source->AddLocalizedString("modulesJourneysInfo", - IDS_NTP_MODULES_HISTORY_CLUSTERS_INFO2); - source->AddLocalizedString( - "modulesJourneyDisable", - IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_DROPDOWN_TEXT); - } - source->AddBoolean( "modulesHeaderIconEnabled", base::FeatureList::IsEnabled(ntp_features::kNtpModulesHeaderIcon));
diff --git a/chrome/browser/ui/webui/settings/ash/device_section.cc b/chrome/browser/ui/webui/settings/ash/device_section.cc index c048337..9a6e659 100644 --- a/chrome/browser/ui/webui/settings/ash/device_section.cc +++ b/chrome/browser/ui/webui/settings/ash/device_section.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/ui/webui/settings/ash/device_keyboard_handler.h" #include "chrome/browser/ui/webui/settings/ash/device_pointer_handler.h" #include "chrome/browser/ui/webui/settings/ash/device_stylus_handler.h" +#include "chrome/browser/ui/webui/settings/ash/printing_section.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" @@ -964,9 +965,16 @@ DeviceSection::DeviceSection(Profile* profile, SearchTagRegistry* search_tag_registry, + CupsPrintersManager* printers_manager, PrefService* pref_service) : OsSettingsSection(profile, search_tag_registry), power_subsection_(profile, search_tag_registry, pref_service), + printing_subsection_( + ash::features::IsOsSettingsRevampWayfindingEnabled() + ? absl::make_optional<PrintingSection>(profile, + search_tag_registry, + printers_manager) + : absl::nullopt), storage_subsection_(profile, search_tag_registry) { CHECK(profile); CHECK(search_tag_registry); @@ -1065,7 +1073,10 @@ AddDeviceDisplayStrings(html_source); AddDeviceAudioStrings(html_source); - if (!ash::features::IsOsSettingsRevampWayfindingEnabled()) { + if (ash::features::IsOsSettingsRevampWayfindingEnabled()) { + CHECK(printing_subsection_); + printing_subsection_->AddLoadTimeData(html_source); + } else { power_subsection_.AddLoadTimeData(html_source); storage_subsection_.AddLoadTimeData(html_source); } @@ -1077,7 +1088,10 @@ web_ui->AddMessageHandler(std::make_unique<PointerHandler>()); web_ui->AddMessageHandler(std::make_unique<StylusHandler>()); - if (!ash::features::IsOsSettingsRevampWayfindingEnabled()) { + if (ash::features::IsOsSettingsRevampWayfindingEnabled()) { + CHECK(printing_subsection_); + printing_subsection_->AddHandlers(web_ui); + } else { power_subsection_.AddHandlers(web_ui); storage_subsection_.AddHandlers(web_ui); } @@ -1290,7 +1304,11 @@ RegisterNestedSettingBulk(mojom::Subpage::kDisplay, kDisplaySettings, generator); - if (!ash::features::IsOsSettingsRevampWayfindingEnabled()) { + if (ash::features::IsOsSettingsRevampWayfindingEnabled()) { + // Printing. + CHECK(printing_subsection_); + printing_subsection_->RegisterHierarchy(generator); + } else { // Power. power_subsection_.RegisterHierarchy(generator);
diff --git a/chrome/browser/ui/webui/settings/ash/device_section.h b/chrome/browser/ui/webui/settings/ash/device_section.h index e652c99..e0ae389 100644 --- a/chrome/browser/ui/webui/settings/ash/device_section.h +++ b/chrome/browser/ui/webui/settings/ash/device_section.h
@@ -12,6 +12,7 @@ #include "chrome/browser/ash/system/pointer_device_observer.h" #include "chrome/browser/ui/webui/settings/ash/os_settings_section.h" #include "chrome/browser/ui/webui/settings/ash/power_section.h" +#include "chrome/browser/ui/webui/settings/ash/printing_section.h" #include "chrome/browser/ui/webui/settings/ash/storage_section.h" #include "chromeos/crosapi/mojom/cros_display_config.mojom.h" #include "mojo/public/cpp/bindings/associated_receiver.h" @@ -38,6 +39,7 @@ public: DeviceSection(Profile* profile, SearchTagRegistry* search_tag_registry, + CupsPrintersManager* printers_manager, PrefService* pref_service); ~DeviceSection() override; @@ -65,7 +67,7 @@ // NightLightController::Observer: void OnNightLightEnabledChanged(bool enabled) override; - // mojom::CrosDisplayConfigObserver + // mojom::CrosDisplayConfigObserver: void OnDisplayConfigChanged() override; void UpdateStylusSearchTags(); @@ -87,6 +89,7 @@ mojo::Remote<crosapi::mojom::CrosDisplayConfigController> cros_display_config_; PowerSection power_subsection_; + absl::optional<PrintingSection> printing_subsection_; StorageSection storage_subsection_; mojo::AssociatedReceiver<crosapi::mojom::CrosDisplayConfigObserver> cros_display_config_observer_receiver_{this};
diff --git a/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc b/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc index 01845278..4edf357 100644 --- a/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
@@ -7,6 +7,7 @@ #include "ash/constants/ash_features.h" #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/printing/fake_cups_printers_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/ash/os_settings_identifier.h" @@ -37,6 +38,14 @@ .subpage = mojom::Subpage::kPerDeviceKeyboard}; constexpr OsSettingsIdentifier kKeyboardBlockMetaFkeyRewritesOsSettingsId = { .setting = mojom::Setting::kKeyboardBlockMetaFkeyRewrites}; +constexpr OsSettingsIdentifier kAddPrinterId = { + .setting = mojom::Setting::kAddPrinter}; +constexpr OsSettingsIdentifier kPrintingDetailsId = { + .subpage = mojom::Subpage::kPrintingDetails}; +constexpr OsSettingsIdentifier kPrintJobsId = {.setting = + mojom::Setting::kPrintJobs}; +constexpr OsSettingsIdentifier kScanningAppId = { + .setting = mojom::Setting::kScanningApp}; // Provides a correctly formatted result_id based on `SearchConcept` // configuration in `device_section.cc`. Based on private static function in @@ -84,6 +93,7 @@ ash::settings::SearchTagRegistry* search_tag_registry() { return &search_tag_registry_; } + FakeCupsPrintersManager* printers_manager() { return &printers_manager_; } base::test::ScopedFeatureList feature_list_; std::unique_ptr<DeviceSection> device_section_; @@ -96,25 +106,49 @@ TestingPrefServiceSimple pref_service_; std::unique_ptr<TestingProfileManager> profile_manager_; raw_ptr<TestingProfile, ExperimentalAsh> profile_; + FakeCupsPrintersManager printers_manager_; }; // Verify registry updated with Audio search tags. TEST_F(DeviceSectionTest, SearchResultIncludeAudio) { feature_list_.Reset(); device_section_ = std::make_unique<DeviceSection>( - profile(), search_tag_registry(), pref_service()); + profile(), search_tag_registry(), printers_manager(), pref_service()); std::string result_id = GetSubpageSearchResultId( kAudioPageOsSettingsId, IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS); EXPECT_TRUE(search_tag_registry()->GetTagMetadata(result_id)); } +// Verify resgistry updated with Printing search tags. +TEST_F(DeviceSectionTest, SearchResultIncludePrinting) { + feature_list_.InitAndEnableFeature( + ash::features::kOsSettingsRevampWayfinding); + device_section_ = std::make_unique<DeviceSection>( + profile(), search_tag_registry(), printers_manager(), pref_service()); + + std::string add_printer_result_id = GetSettingsSearchResultId( + kAddPrinterId, IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER); + std::string printing_details_result_id = GetSubpageSearchResultId( + kPrintingDetailsId, IDS_OS_SETTINGS_TAG_PRINTING); + std::string print_jobs_result_id = GetSettingsSearchResultId( + kPrintJobsId, IDS_OS_SETTINGS_TAG_PRINT_MANAGEMENT); + std::string scanning_app_result_id = GetSettingsSearchResultId( + kScanningAppId, IDS_OS_SETTINGS_TAG_SCANNING_APP); + + EXPECT_TRUE(search_tag_registry()->GetTagMetadata(add_printer_result_id)); + EXPECT_TRUE( + search_tag_registry()->GetTagMetadata(printing_details_result_id)); + EXPECT_TRUE(search_tag_registry()->GetTagMetadata(print_jobs_result_id)); + EXPECT_TRUE(search_tag_registry()->GetTagMetadata(scanning_app_result_id)); +} + // Verify registry updated with per device settings search tags when flag is // enabled. TEST_F(DeviceSectionTest, SearchResultChangeToSettingsSplitWithFlag) { feature_list_.InitAndEnableFeature(ash::features::kInputDeviceSettingsSplit); device_section_ = std::make_unique<DeviceSection>( - profile(), search_tag_registry(), pref_service()); + profile(), search_tag_registry(), printers_manager(), pref_service()); std::string result_id = GetSubpageSearchResultId( kPerDeviceKeyboardOsSettingsId, IDS_OS_SETTINGS_TAG_KEYBOARD); @@ -130,7 +164,7 @@ TEST_F(DeviceSectionTest, SearchResultChangeBackWithoutFlag) { feature_list_.InitAndDisableFeature(features::kInputDeviceSettingsSplit); device_section_ = std::make_unique<DeviceSection>( - profile(), search_tag_registry(), pref_service()); + profile(), search_tag_registry(), printers_manager(), pref_service()); std::string result_id = GetSubpageSearchResultId( kKeyboardOsSettingsId, IDS_OS_SETTINGS_TAG_KEYBOARD);
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc b/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc index 8e505872..457192b 100644 --- a/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc +++ b/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc
@@ -69,8 +69,9 @@ std::make_unique<PeopleSection>(profile, search_tag_registry, identity_manager, prefs)); - AddSection(mojom::Section::kDevice, std::make_unique<DeviceSection>( - profile, search_tag_registry, prefs)); + AddSection(mojom::Section::kDevice, + std::make_unique<DeviceSection>(profile, search_tag_registry, + printers_manager, prefs)); AddSection(mojom::Section::kPersonalization, std::make_unique<PersonalizationSection>( @@ -88,10 +89,6 @@ mojom::Section::kPrivacyAndSecurity, std::make_unique<PrivacySection>(profile, search_tag_registry, prefs)); - AddSection(mojom::Section::kPrinting, - std::make_unique<PrintingSection>(profile, search_tag_registry, - printers_manager)); - AddSection(mojom::Section::kAccessibility, std::make_unique<AccessibilitySection>( profile, search_tag_registry, prefs)); @@ -123,6 +120,10 @@ std::make_unique<LanguagesSection>(profile, search_tag_registry, prefs)); + AddSection(mojom::Section::kPrinting, + std::make_unique<PrintingSection>(profile, search_tag_registry, + printers_manager)); + AddSection(mojom::Section::kReset, std::make_unique<ResetSection>(profile, search_tag_registry));
diff --git a/chrome/browser/ui/webui/settings/ash/printing_section.cc b/chrome/browser/ui/webui/settings/ash/printing_section.cc index e16da38..0dffe17 100644 --- a/chrome/browser/ui/webui/settings/ash/printing_section.cc +++ b/chrome/browser/ui/webui/settings/ash/printing_section.cc
@@ -21,6 +21,7 @@ namespace ash::settings { namespace mojom { +using ::chromeos::settings::mojom::kDeviceSectionPath; using ::chromeos::settings::mojom::kPrintingDetailsSubpagePath; using ::chromeos::settings::mojom::kPrintingSectionPath; using ::chromeos::settings::mojom::Section; @@ -79,10 +80,11 @@ return *tags; } -const std::vector<SearchConcept>& GetScanningAppSearchConcepts() { +const std::vector<SearchConcept>& GetScanningAppSearchConcepts( + const char* section_path) { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_SCANNING_APP, - mojom::kPrintingSectionPath, + section_path, mojom::SearchResultIcon::kPrinter, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSetting, @@ -101,7 +103,7 @@ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); updater.AddSearchTags(GetPrintingSearchConcepts()); updater.AddSearchTags(GetPrintingManagementSearchConcepts()); - updater.AddSearchTags(GetScanningAppSearchConcepts()); + updater.AddSearchTags(GetScanningAppSearchConcepts(GetSectionPath())); // Saved Printers search tags are added/removed dynamically. if (printers_manager_) { @@ -343,7 +345,9 @@ } mojom::Section PrintingSection::GetSection() const { - return mojom::Section::kPrinting; + return ash::features::IsOsSettingsRevampWayfindingEnabled() + ? mojom::Section::kDevice + : mojom::Section::kPrinting; } mojom::SearchResultIcon PrintingSection::GetSectionIcon() const { @@ -351,7 +355,9 @@ } const char* PrintingSection::GetSectionPath() const { - return mojom::kPrintingSectionPath; + return ash::features::IsOsSettingsRevampWayfindingEnabled() + ? mojom::kDeviceSectionPath + : mojom::kPrintingSectionPath; } bool PrintingSection::LogMetric(mojom::Setting setting,
diff --git a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc index 96ad9e7..b729e2ba 100644 --- a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc +++ b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc
@@ -41,6 +41,7 @@ #include "components/unified_consent/unified_consent_service.h" #include "components/unified_consent/url_keyed_data_collection_consent_helper.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "google_apis/gaia/google_service_auth_error.h" #include "net/base/url_util.h" @@ -281,10 +282,11 @@ return; } - std::unique_ptr<side_panel::mojom::ImageQuery> image_query = - helper->GetImageQuery(); - if (image_query) { - OnImageQuery(*image_query); + if (helper->HasImageQuery()) { + // If there is an image query to run, we need to wait until the side panel + // view has bounds in order for us to issue the request to Lens properly. + // This is called in the CompanionSidePanelController once it detects a + // change in the Companion's WebContents bounds. return; }
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_read_aloud_browsertest.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_read_aloud_browsertest.cc index cfe2e5a..351337c 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_read_aloud_browsertest.cc +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_read_aloud_browsertest.cc
@@ -102,3 +102,8 @@ ReadAloud_GranularityChangesUpdatesHighlight) { ASSERT_TRUE(RunTest("read_aloud_highlight_with_granularity_changes.js")); } + +IN_PROC_BROWSER_TEST_F(ReadAnythingAppReadAloudTest, + HighlightCallback_TogglesHighlight) { + ASSERT_TRUE(RunTest("highlight_callback_toggles_highlight.js")); +}
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_toolbar_browsertest.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_toolbar_browsertest.cc index 4f05293..7e02896 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_toolbar_browsertest.cc +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_toolbar_browsertest.cc
@@ -106,11 +106,6 @@ ASSERT_TRUE(RunTest("toolbar_visible_with_flag.js")); } -IN_PROC_BROWSER_TEST_F(ReadAnythingAppToolbarTest, - HighlightCallback_TogglesHighlight) { - ASSERT_TRUE(RunTest("highlight_callback_toggles_highlight.js")); -} - // TODO(crbug.com/1474951): Remove this test once Read Aloud flag is removed. IN_PROC_BROWSER_TEST_F(ReadAnythingAppToolbarTest, ReadAloud_Hidden) { ASSERT_TRUE(RunTest("toolbar_without_flag_hides_read_aloud.js"));
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc index febeb688..271717b3 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.cc
@@ -43,11 +43,13 @@ prefs::kAccessibilityReadAnythingSpeechRate, kReadAnythingDefaultSpeechRate, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); - // TODO(crbug.com/1474951): Update the default value for these integer - // prefs to be an enum value, like the ones above registry->RegisterIntegerPref( - prefs::kAccessibilityReadAnythingHighlightGranularity, 1, + prefs::kAccessibilityReadAnythingHighlightGranularity, + static_cast<int>( + read_anything::mojom::HighlightGranularity::kDefaultValue), user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + // TODO(crbug.com/1474951): Update the default value for this integer + // pref to be an enum value, like the ones above registry->RegisterIntegerPref( prefs::kAccessibilityReadAnythingHighlightColor, 0, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc index d5e2b1b..624a278 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc
@@ -68,6 +68,12 @@ features::IsReadAnythingReadAloudEnabled() ? prefs->GetDouble(prefs::kAccessibilityReadAnythingSpeechRate) : kReadAnythingDefaultSpeechRate; + read_anything::mojom::HighlightGranularity highlightGranularity = + features::IsReadAnythingReadAloudEnabled() + ? static_cast<read_anything::mojom::HighlightGranularity>( + prefs->GetDouble( + prefs::kAccessibilityReadAnythingHighlightGranularity)) + : read_anything::mojom::HighlightGranularity::kDefaultValue; page_->OnSettingsRestoredFromPrefs( static_cast<read_anything::mojom::LineSpacing>( prefs->GetInteger(prefs::kAccessibilityReadAnythingLineSpacing)), @@ -77,7 +83,7 @@ prefs->GetDouble(prefs::kAccessibilityReadAnythingFontScale), static_cast<read_anything::mojom::Colors>( prefs->GetInteger(prefs::kAccessibilityReadAnythingColorInfo)), - speechRate); + speechRate, highlightGranularity); } #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) @@ -161,6 +167,13 @@ prefs::kAccessibilityReadAnythingSpeechRate, rate); } +void ReadAnythingUntrustedPageHandler::OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity granularity) { + browser_->profile()->GetPrefs()->SetInteger( + prefs::kAccessibilityReadAnythingHighlightGranularity, + static_cast<size_t>(granularity)); +} + void ReadAnythingUntrustedPageHandler::OnLinkClicked( const ui::AXTreeID& target_tree_id, ui::AXNodeID target_node_id) {
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h index b28ce5b..fe46e9a 100644 --- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h +++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h
@@ -68,6 +68,8 @@ void OnFontSizeChange(double font_size) override; void OnColorChange(read_anything::mojom::Colors color) override; void OnSpeechRateChange(double rate) override; + void OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity granularity) override; void OnLinkClicked(const ui::AXTreeID& target_tree_id, ui::AXNodeID target_node_id) override; void OnSelectionChange(const ui::AXTreeID& target_tree_id,
diff --git a/chrome/browser/web_data_service_factory.cc b/chrome/browser/web_data_service_factory.cc index 2b75ef0..49bdba1 100644 --- a/chrome/browser/web_data_service_factory.cc +++ b/chrome/browser/web_data_service_factory.cc
@@ -152,9 +152,10 @@ return chrome::GetBrowserContextRedirectedInIncognito(context); } -KeyedService* WebDataServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +WebDataServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return BuildWebDataService(context).release(); + return BuildWebDataService(context); } bool WebDataServiceFactory::ServiceIsNULLWhileTesting() const {
diff --git a/chrome/browser/web_data_service_factory.h b/chrome/browser/web_data_service_factory.h index ad84d5e..faac2d4 100644 --- a/chrome/browser/web_data_service_factory.h +++ b/chrome/browser/web_data_service_factory.h
@@ -73,7 +73,7 @@ // |BrowserContextKeyedServiceFactory| methods: content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; bool ServiceIsNULLWhileTesting() const override; };
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 60833f4..522eb9a 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1695124764-ebb6c231514c8d11391fe6cb0b3000b894e1b592.profdata +chrome-android32-main-1695146254-874a70f0ed81430254a432d67fc7bb1dbe1c9fc6.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 125dfae..1d625d11 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1695124764-ae27dabeddfc411bc69aa1cdb8fca548c0ddbd5c.profdata +chrome-android64-main-1695146254-672a32869993ac26fd0965a58a38809eae5b4470.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 8d9b21b..66b32dc6 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1695102929-e8ac5284aad14fda3c49f104d4a83ed1e0aad1c6.profdata +chrome-linux-main-1695124764-b8bc62d1a1bb8493e3b1226eac028dd53544bee5.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index a73a12df..d6393a958 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1695124764-b2d1d5c275e79618dcfb031a08f45f24e1e6f43c.profdata +chrome-mac-arm-main-1695138714-010c65f556150f89111aac92b04bb49fd13aac22.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 616dbe11..8127995 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1695102929-3ae495654dd7255a0670d4563631be027fbff403.profdata +chrome-mac-main-1695124764-9b65fc72248c57df170dda400002b4d48f919755.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 1b677289..aa40ad1 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1695102929-6f56f44ef3ae0580414f8cd04afe242c8347e52b.profdata +chrome-win-arm64-main-1695124764-b95a52aa7b2b5eebaf22b04b73361d20e05341ac.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 73225bb..34a8f15 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1695113873-0ccd5cdd3dd7e6d01a3990c9c54f0ebf061d0ae4.profdata +chrome-win32-main-1695135599-944e76e4ffa4a7df551c1a8bf403d2c5653e0589.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index fd1951e..998fc92 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1695113873-71252456696cb47b33c5a37ca307c643bbd59a38.profdata +chrome-win64-main-1695135599-7a94a50c1a04035a10c4c1cde51c962534613870.profdata
diff --git a/chrome/common/accessibility/read_anything.mojom b/chrome/common/accessibility/read_anything.mojom index 87c5d69c..36ae008 100644 --- a/chrome/common/accessibility/read_anything.mojom +++ b/chrome/common/accessibility/read_anything.mojom
@@ -68,6 +68,13 @@ kVeryLoose = 3, }; +[Extensible, Stable, Uuid="b8c27619-fe28-44a6-bb89-f4eda846b0f8"] +// Granularity used for highlighting text as it's spoken. +enum HighlightGranularity { + [Default]kOn = 0, + kOff = 1, +}; + // Browser-side handler for requests from untrusted WebUI page. interface UntrustedPageHandler { // Informs the browser controller that a user tried to copy text from the @@ -105,6 +112,10 @@ // https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/rate OnSpeechRateChange(double rate); + // Informs the browser controller that the user updated the granularity of + // the highlight that follows along with speech via the webui toolbar. + OnHighlightGranularityChanged(read_anything.mojom.HighlightGranularity granularity); + // Informs the browser controller that a link was clicked in the WebUI. The // browser controller responds by performing a click action on the link in // the target tree, which is in the main frame of the currently active web @@ -164,7 +175,8 @@ string font, double font_size, read_anything.mojom.Colors color, - double speech_rate); + double speech_rate, + read_anything.mojom.HighlightGranularity granularity); // Notifies the WebUI that the ScreenAI service is ready on this device. [EnableIf=enable_screen_ai_service]
diff --git a/chrome/installer/mac/signing/driver_test.py b/chrome/installer/mac/signing/driver_test.py index 4cf97c9..8ee9534 100644 --- a/chrome/installer/mac/signing/driver_test.py +++ b/chrome/installer/mac/signing/driver_test.py
@@ -212,51 +212,3 @@ config = sign_all.call_args.args[1] self.assertEquals(model.NotarizeAndStapleLevel.STAPLE, config.notarize) self.assertEquals([], config.invoker.notarizer.notary_args) - - def test_notarize_legacy_args_user(self, sign_all, **kwargs): - driver.main([ - '--input', - '/input', - '--output', - '/output', - '--identity', - 'G', - '--notarize', - '--notary-user', - 'Notary-User', - ]) - self.assertEquals(1, sign_all.call_count) - config = sign_all.call_args.args[1] - self.assertEquals([], config.invoker.notarizer.notary_args) - - def test_notarize_legacy_args_password(self, sign_all, **kwargs): - driver.main([ - '--input', - '/input', - '--output', - '/output', - '--identity', - 'G', - '--notarize', - '--notary-password', - '@env:PASSWORD', - ]) - self.assertEquals(1, sign_all.call_count) - config = sign_all.call_args.args[1] - self.assertEquals([], config.invoker.notarizer.notary_args) - - def test_notarize_legacy_args_team_id(self, sign_all, **kwargs): - driver.main([ - '--input', - '/input', - '--output', - '/output', - '--identity', - 'G', - '--notarize', - '--notary-team-id', - 'TeamId', - ]) - self.assertEquals(1, sign_all.call_count) - config = sign_all.call_args.args[1] - self.assertEquals([], config.invoker.notarizer.notary_args)
diff --git a/chrome/installer/mac/signing/notarize.py b/chrome/installer/mac/signing/notarize.py index e4709b0..785d651 100644 --- a/chrome/installer/mac/signing/notarize.py +++ b/chrome/installer/mac/signing/notarize.py
@@ -38,24 +38,9 @@ 'notarization tool and are intended to specify authentication ' 'parameters.') - # Legacy arguments that will be removed in the future. - legacy_help = ('This argument is deprecated. ' - 'Please use --notary-arg instead.') - parser.add_argument('--notary-user', help=legacy_help) - parser.add_argument('--notary-password', help=legacy_help) - parser.add_argument('--notary-team-id', help=legacy_help) - def __init__(self, args, config): self._notary_args = args.notary_arg - if any([ - getattr(args, arg, None) - for arg in ('notary_user', 'notary_password', 'notary_team_id') - ]): - logger.warning( - 'Explicit notarization authentication arguments are deprecated. Use --notary-arg instead.' - ) - @property def notary_args(self): return self._notary_args
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything_app_controller.cc index 4901523..e61afdec 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller.cc
@@ -575,9 +575,11 @@ const std::string& font, double font_size, read_anything::mojom::Colors color, - double speech_rate) { + double speech_rate, + read_anything::mojom::HighlightGranularity granularity) { model_.OnSettingsRestoredFromPrefs(line_spacing, letter_spacing, font, - font_size, color, speech_rate); + font_size, color, speech_rate, + granularity); // TODO(abigailbklein): Use v8::Function rather than javascript. If possible, // replace this function call with firing an event. std::string script = "chrome.readingMode.restoreSettingsFromPrefs();"; @@ -620,6 +622,9 @@ .SetProperty("veryWideLetterSpacing", &ReadAnythingAppController::VeryWideLetterSpacing) .SetProperty("colorTheme", &ReadAnythingAppController::ColorTheme) + .SetProperty("highlightGranularity", + &ReadAnythingAppController::HighlightGranularity) + .SetProperty("highlightOn", &ReadAnythingAppController::HighlightOn) .SetProperty("defaultTheme", &ReadAnythingAppController::DefaultTheme) .SetProperty("lightTheme", &ReadAnythingAppController::LightTheme) .SetProperty("darkTheme", &ReadAnythingAppController::DarkTheme) @@ -669,6 +674,10 @@ .SetMethod("onFontChange", &ReadAnythingAppController::OnFontChange) .SetMethod("onSpeechRateChange", &ReadAnythingAppController::OnSpeechRateChange) + .SetMethod("turnedHighlightOn", + &ReadAnythingAppController::TurnedHighlightOn) + .SetMethod("turnedHighlightOff", + &ReadAnythingAppController::TurnedHighlightOff) .SetMethod("getLineSpacingValue", &ReadAnythingAppController::GetLineSpacingValue) .SetMethod("getLetterSpacingValue", @@ -743,6 +752,10 @@ return model_.speech_rate(); } +int ReadAnythingAppController::HighlightGranularity() const { + return model_.highlight_granularity(); +} + int ReadAnythingAppController::StandardLineSpacing() const { return static_cast<int>(read_anything::mojom::LineSpacing::kStandard); } @@ -787,6 +800,10 @@ return static_cast<int>(read_anything::mojom::Colors::kBlue); } +int ReadAnythingAppController::HighlightOn() const { + return static_cast<int>(read_anything::mojom::HighlightGranularity::kOn); +} + std::vector<ui::AXNodeID> ReadAnythingAppController::GetChildren( ui::AXNodeID ax_node_id) const { std::vector<ui::AXNodeID> child_ids; @@ -1017,6 +1034,16 @@ page_handler_->OnSpeechRateChange(rate); } +void ReadAnythingAppController::TurnedHighlightOn() { + page_handler_->OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity::kOn); +} + +void ReadAnythingAppController::TurnedHighlightOff() { + page_handler_->OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity::kOff); +} + double ReadAnythingAppController::GetLineSpacingValue(int line_spacing) const { if (line_spacing > static_cast<int>(read_anything::mojom::LineSpacing::kMaxValue)) {
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.h b/chrome/renderer/accessibility/read_anything_app_controller.h index 5bc292d..269fb823 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller.h +++ b/chrome/renderer/accessibility/read_anything_app_controller.h
@@ -98,7 +98,8 @@ const std::string& font, double font_size, read_anything::mojom::Colors color, - double speech_rate) override; + double speech_rate, + read_anything::mojom::HighlightGranularity granularity) override; void SetDefaultLanguageCode(const std::string& code) override; #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) void ScreenAIServiceReady() override; @@ -120,6 +121,8 @@ float LetterSpacing() const; float LineSpacing() const; int ColorTheme() const; + int HighlightGranularity() const; + int HighlightOn() const; int StandardLineSpacing() const; int LooseLineSpacing() const; int VeryLooseLineSpacing() const; @@ -164,6 +167,8 @@ void OnBlueTheme(); void OnFontChange(const std::string& font); void OnSpeechRateChange(double rate); + void TurnedHighlightOn(); + void TurnedHighlightOff(); double GetLineSpacingValue(int line_spacing) const; double GetLetterSpacingValue(int letter_spacing) const; std::vector<std::string> GetSupportedFonts() const;
diff --git a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc index 44ba31d..0c640f6 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
@@ -62,6 +62,10 @@ OnColorChange, (read_anything::mojom::Colors color), (override)); + MOCK_METHOD(void, + OnHighlightGranularityChanged, + (read_anything::mojom::HighlightGranularity color), + (override)); mojo::PendingRemote<read_anything::mojom::UntrustedPageHandler> BindNewPipeAndPassRemote() { @@ -224,6 +228,10 @@ void OnFontSizeReset() { controller_->OnFontSizeReset(); } + void TurnedHighlightOn() { controller_->TurnedHighlightOn(); } + + void TurnedHighlightOff() { controller_->TurnedHighlightOff(); } + std::vector<ui::AXNodeID> GetChildren(ui::AXNodeID ax_node_id) { return controller_->GetChildren(ax_node_id); } @@ -1467,6 +1475,30 @@ OnFontSizeReset(); } +TEST_F(ReadAnythingAppControllerTest, TurnedHighlightOn_SavesHighlightState) { + EXPECT_CALL(page_handler_, + OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity::kOn)) + .Times(1); + EXPECT_CALL(page_handler_, + OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity::kOff)) + .Times(0); + TurnedHighlightOn(); +} + +TEST_F(ReadAnythingAppControllerTest, TurnedHighlightOff_SavesHighlightState) { + EXPECT_CALL(page_handler_, + OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity::kOn)) + .Times(0); + EXPECT_CALL(page_handler_, + OnHighlightGranularityChanged( + read_anything::mojom::HighlightGranularity::kOff)) + .Times(1); + TurnedHighlightOff(); +} + TEST_F(ReadAnythingAppControllerTest, GetNextSentence_ReturnsCorrectIndex) { const std::u16string first_sentence = u"This is a normal sentence. "; const std::u16string second_sentence = u"This is a second sentence.";
diff --git a/chrome/renderer/accessibility/read_anything_app_model.cc b/chrome/renderer/accessibility/read_anything_app_model.cc index 5989836..9384f4a 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.cc +++ b/chrome/renderer/accessibility/read_anything_app_model.cc
@@ -45,13 +45,15 @@ const std::string& font, double font_size, read_anything::mojom::Colors color, - double speech_rate) { + double speech_rate, + read_anything::mojom::HighlightGranularity granularity) { line_spacing_ = GetLineSpacingValue(line_spacing); letter_spacing_ = GetLetterSpacingValue(letter_spacing); font_name_ = font; font_size_ = font_size; color_theme_ = static_cast<size_t>(color); speech_rate_ = speech_rate; + highlight_granularity_ = static_cast<size_t>(granularity); } void ReadAnythingAppModel::InsertDisplayNode(ui::AXNodeID node) {
diff --git a/chrome/renderer/accessibility/read_anything_app_model.h b/chrome/renderer/accessibility/read_anything_app_model.h index 6d90dd47..05ce0a4 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.h +++ b/chrome/renderer/accessibility/read_anything_app_model.h
@@ -59,6 +59,7 @@ float letter_spacing() const { return letter_spacing_; } float line_spacing() const { return line_spacing_; } int color_theme() const { return color_theme_; } + int highlight_granularity() const { return highlight_granularity_; } const SkColor& foreground_color() const { return foreground_color_; } const SkColor& background_color() const { return background_color_; } float speech_rate() const { return speech_rate_; } @@ -111,7 +112,8 @@ const std::string& font, double font_size, read_anything::mojom::Colors color, - double speech_rate); + double speech_rate, + read_anything::mojom::HighlightGranularity granularity); void OnScroll(bool on_selection, bool from_reading_mode) const; void Reset(const std::vector<ui::AXNodeID>& content_node_ids); @@ -237,6 +239,8 @@ SkColor foreground_color_ = (int)read_anything::mojom::Colors::kDefaultValue; int color_theme_ = (int)read_anything::mojom::Colors::kDefaultValue; float speech_rate_ = kReadAnythingDefaultSpeechRate; + int highlight_granularity_ = + (int)read_anything::mojom::HighlightGranularity::kDefaultValue; // Selection information. bool has_selection_ = false;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 9ce2f097..6fa69f23 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -668,6 +668,8 @@ "../browser/ui/views/frame/immersive_mode_tester.h", "base/chromeos/crosier/aura_window_title_observer.cc", "base/chromeos/crosier/aura_window_title_observer.h", + "base/chromeos/crosier/crosier_util.cc", + "base/chromeos/crosier/crosier_util.h", ] deps += [ "base/chromeos/crosier:proto", @@ -1010,6 +1012,8 @@ "base/chromeos/crosier/interactive_ash_test_uitest.cc", ] + deps += [ "//chrome/test/base/chromeos/crosier:proto" ] + data_deps = [ "//chrome/test/base/chromeos/crosier/helper", "//chrome/test/base/chromeos/crosier/helper:client", @@ -7110,6 +7114,7 @@ "../browser/android/signin/signin_manager_android_unittest.cc", "../browser/android/signin/web_signin_bridge_unittest.cc", "../browser/android/usage_stats/usage_stats_database_unittest.cc", + "../browser/android/webapk/webapk_database_unittest.cc", "../browser/android/webapk/webapk_helpers_unittest.cc", "../browser/android/webapk/webapk_installer_unittest.cc", "../browser/android/webapk/webapk_sync_bridge_unittest.cc", @@ -8152,6 +8157,7 @@ "../browser/ui/webui/ash/edu_account_login_handler_unittest.cc", "../browser/ui/webui/ash/emoji/emoji_ui_unittest.cc", "../browser/ui/webui/ash/emoji/gif_tenor_api_fetcher_unittest.cc", + "../browser/ui/webui/ash/enterprise_reporting/history_converter_unittest.cc", "../browser/ui/webui/ash/sync/os_sync_handler_unittest.cc", "../browser/ui/webui/help/version_updater_chromeos_unittest.cc", "../browser/ui/webui/signin/ash/user_cloud_signin_restriction_policy_fetcher_unittest.cc", @@ -8230,6 +8236,7 @@ "//chrome/browser/ui/quick_answers", "//chrome/browser/ui/views/editor_menu:utils", "//chrome/browser/ui/views/editor_menu:views", + "//chrome/browser/ui/webui/ash/enterprise_reporting:mojo_bindings", "//chrome/browser/ui/webui/nearby_share:mojom", "//chrome/services/printing:pdf_thumbnailer_test", "//chrome/services/sharing:unit_tests",
diff --git a/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.cc b/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.cc index 825a744..fed3b421 100644 --- a/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.cc +++ b/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.cc
@@ -5,7 +5,6 @@ #include "chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h" #include "base/command_line.h" -#include "base/test/gtest_tags.h" #include "build/chromeos_buildflags.h" #include "ui/compositor/compositor_switches.h" #include "ui/gl/gl_switches.h" @@ -22,26 +21,6 @@ ChromeOSIntegrationTestMixin::~ChromeOSIntegrationTestMixin() = default; -void ChromeOSIntegrationTestMixin::AddTestInfo( - const chrome_test_base_chromeos_crosier::TestInfo& info) { - for (int i = 0; i < info.contacts_size(); ++i) { - // This field name aligns with existing Tast test format. - base::AddTagToTestResult("contacts", info.contacts(i)); - } - if (info.has_team_email()) { - // This field name aligns with 'team_email' in DIR_METADATA. - base::AddTagToTestResult("team_email", info.team_email()); - } - if (info.has_buganizer()) { - // This field name aligns with 'buganizer' in DIR_METADATA. - base::AddTagToTestResult("buganizer", info.buganizer()); - } - if (info.has_buganizer_public()) { - // This field name aligns with 'buganizer_public' in DIR_METADATA. - base::AddTagToTestResult("buganizer_public", info.buganizer_public()); - } -} - void ChromeOSIntegrationTestMixin::SetUpCommandLine( base::CommandLine* command_line) { // One of the main reason for using ChromeOS integration test is it can
diff --git a/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h b/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h index 0b3a6d88..da6a8bc2 100644 --- a/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h +++ b/chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h
@@ -5,7 +5,6 @@ #ifndef CHROME_TEST_BASE_CHROMEOS_CROSIER_CHROMEOS_INTEGRATION_TEST_MIXIN_H_ #define CHROME_TEST_BASE_CHROMEOS_CROSIER_CHROMEOS_INTEGRATION_TEST_MIXIN_H_ -#include "chrome/test/base/chromeos/crosier/chromeos_test_definition.pb.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" namespace base { @@ -22,12 +21,6 @@ delete; ~ChromeOSIntegrationTestMixin() override; - // Add the test information. - // Call this at the beginning of the test body. Setting test info would help - // other folks to understand the test and have better ownership. - // See |chromeos_test_definition.proto| for more information. - void AddTestInfo(const chrome_test_base_chromeos_crosier::TestInfo& info); - // InProcessBrowserTestMixin: void SetUpCommandLine(base::CommandLine* command_line) override; bool SetUpUserDataDirectory() override;
diff --git a/chrome/test/base/chromeos/crosier/crosier_util.cc b/chrome/test/base/chromeos/crosier/crosier_util.cc new file mode 100644 index 0000000..d6bff3f --- /dev/null +++ b/chrome/test/base/chromeos/crosier/crosier_util.cc
@@ -0,0 +1,30 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/base/chromeos/crosier/crosier_util.h" + +#include "base/test/gtest_tags.h" + +namespace crosier_util { + +void AddTestInfo(const chrome_test_base_chromeos_crosier::TestInfo& info) { + for (int i = 0; i < info.contacts_size(); ++i) { + // This field name aligns with existing Tast test format. + base::AddTagToTestResult("contacts", info.contacts(i)); + } + if (info.has_team_email()) { + // This field name aligns with 'team_email' in DIR_METADATA. + base::AddTagToTestResult("team_email", info.team_email()); + } + if (info.has_buganizer()) { + // This field name aligns with 'buganizer' in DIR_METADATA. + base::AddTagToTestResult("buganizer", info.buganizer()); + } + if (info.has_buganizer_public()) { + // This field name aligns with 'buganizer_public' in DIR_METADATA. + base::AddTagToTestResult("buganizer_public", info.buganizer_public()); + } +} + +} // namespace crosier_util
diff --git a/chrome/test/base/chromeos/crosier/crosier_util.h b/chrome/test/base/chromeos/crosier/crosier_util.h new file mode 100644 index 0000000..b140b4d --- /dev/null +++ b/chrome/test/base/chromeos/crosier/crosier_util.h
@@ -0,0 +1,19 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_BASE_CHROMEOS_CROSIER_CROSIER_UTIL_H_ +#define CHROME_TEST_BASE_CHROMEOS_CROSIER_CROSIER_UTIL_H_ + +#include "chrome/test/base/chromeos/crosier/chromeos_test_definition.pb.h" + +namespace crosier_util { + +// Adds test information. Call this during test setup or at the beginning of the +// test body. Setting test info helps other engineers to understand the test and +// its ownership. See |chromeos_test_definition.proto| for more information. +void AddTestInfo(const chrome_test_base_chromeos_crosier::TestInfo& info); + +} // namespace crosier_util + +#endif // CHROME_TEST_BASE_CHROMEOS_CROSIER_CROSIER_UTIL_H_
diff --git a/chrome/test/base/chromeos/crosier/demo_integration_test.cc b/chrome/test/base/chromeos/crosier/demo_integration_test.cc index 7d1aa59..b7658fc6 100644 --- a/chrome/test/base/chromeos/crosier/demo_integration_test.cc +++ b/chrome/test/base/chromeos/crosier/demo_integration_test.cc
@@ -10,6 +10,7 @@ #include "build/chromeos_buildflags.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h" +#include "chrome/test/base/chromeos/crosier/crosier_util.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" #include "net/dns/mock_host_resolver.h" @@ -123,7 +124,7 @@ info.add_contacts("jamescook@chromium.org"); info.set_team_email("crosier-team@google.com"); info.set_buganizer("1394295"); - chromeos_integration_test_mixin_.AddTestInfo(info); + crosier_util::AddTestInfo(info); base::AddFeatureIdTagToTestResult( "screenplay-351d628b-e4a4-41c6-91e4-a4036ad12360");
diff --git a/chrome/test/data/autofill/captured_sites/artifacts b/chrome/test/data/autofill/captured_sites/artifacts index d6062d4..d880bea 160000 --- a/chrome/test/data/autofill/captured_sites/artifacts +++ b/chrome/test/data/autofill/captured_sites/artifacts
@@ -1 +1 @@ -Subproject commit d6062d44fe4e2216148d600e0ec195cfc4954ce1 +Subproject commit d880bea5e920cce2e74ff9eeb929a38ceaf5c1ba
diff --git a/chrome/test/data/webui/chromeos/scanning/action_toolbar_test.js b/chrome/test/data/webui/chromeos/scanning/action_toolbar_test.js index 63e48cf..6b2dac7f 100644 --- a/chrome/test/data/webui/chromeos/scanning/action_toolbar_test.js +++ b/chrome/test/data/webui/chromeos/scanning/action_toolbar_test.js
@@ -30,14 +30,23 @@ // changes. test('totalPageCountIncrements', () => { actionToolbar.pageIndex = 0; - assertEquals('', actionToolbar.$$('#pageNumbers').textContent.trim()); + assertEquals( + '', + actionToolbar.shadowRoot.querySelector('#pageNumbers') + .textContent.trim()); actionToolbar.numTotalPages = 3; - assertEquals('1 of 3', actionToolbar.$$('#pageNumbers').textContent.trim()); + assertEquals( + '1 of 3', + actionToolbar.shadowRoot.querySelector('#pageNumbers') + .textContent.trim()); actionToolbar.numTotalPages = 4; actionToolbar.pageIndex = 1; - assertEquals('2 of 4', actionToolbar.$$('#pageNumbers').textContent.trim()); + assertEquals( + '2 of 4', + actionToolbar.shadowRoot.querySelector('#pageNumbers') + .textContent.trim()); }); // Verify clicking the remove page button fires the 'show-remove-page-dialog' @@ -51,7 +60,7 @@ pageIndexFromEvent = e.detail; }); - actionToolbar.$$('#removePageIcon').click(); + actionToolbar.shadowRoot.querySelector('#removePageIcon').click(); return flushTasks().then(() => { assertEquals(expectedPageIndex, pageIndexFromEvent); }); @@ -68,7 +77,7 @@ pageIndexFromEvent = e.detail; }); - actionToolbar.$$('#rescanPageIcon').click(); + actionToolbar.shadowRoot.querySelector('#rescanPageIcon').click(); return flushTasks().then(() => { assertEquals(expectedPageIndex, pageIndexFromEvent); });
diff --git a/chrome/test/data/webui/chromeos/scanning/color_mode_select_test.js b/chrome/test/data/webui/chromeos/scanning/color_mode_select_test.js index ea1ed6b..4b1a2723 100644 --- a/chrome/test/data/webui/chromeos/scanning/color_mode_select_test.js +++ b/chrome/test/data/webui/chromeos/scanning/color_mode_select_test.js
@@ -32,7 +32,7 @@ // correct options. test('initializeColorModeSelect', () => { // Before options are added, the dropdown should be enabled and empty. - const select = colorModeSelect.$$('select'); + const select = colorModeSelect.shadowRoot.querySelector('select'); assertTrue(!!select); assertFalse(select.disabled); assertEquals(0, select.length); @@ -78,7 +78,8 @@ // and the options change. test('selectDefaultWhenOptionsChange', () => { const select = - /** @type {!HTMLSelectElement} */ (colorModeSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + colorModeSelect.shadowRoot.querySelector('select')); colorModeSelect.options = [ColorMode.kGrayscale, ColorMode.kBlackAndWhite, ColorMode.kColor]; flush();
diff --git a/chrome/test/data/webui/chromeos/scanning/file_type_select_test.js b/chrome/test/data/webui/chromeos/scanning/file_type_select_test.js index cd2cdc8..b34ffe5 100644 --- a/chrome/test/data/webui/chromeos/scanning/file_type_select_test.js +++ b/chrome/test/data/webui/chromeos/scanning/file_type_select_test.js
@@ -30,7 +30,8 @@ // default option should be PDF. test('initializeFileTypeSelect', () => { const select = - /** @type {!HTMLSelectElement} */ (fileTypeSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + fileTypeSelect.shadowRoot.querySelector('select')); assertTrue(!!select); assertFalse(select.disabled); assertEquals(3, select.length);
diff --git a/chrome/test/data/webui/chromeos/scanning/loading_page_test.js b/chrome/test/data/webui/chromeos/scanning/loading_page_test.js index df6b31c..2f72eca 100644 --- a/chrome/test/data/webui/chromeos/scanning/loading_page_test.js +++ b/chrome/test/data/webui/chromeos/scanning/loading_page_test.js
@@ -80,16 +80,18 @@ // Verify the loading page, then the no scanners page is shown when no // scanners are available. test('noScanners', () => { - assertTrue( - isVisible(/** @type {!HTMLElement} */ (loadingPage.$$('#loadingDiv')))); + assertTrue(isVisible(/** @type {!HTMLElement} */ ( + loadingPage.shadowRoot.querySelector('#loadingDiv')))); assertFalse(isVisible( - /** @type {!HTMLElement} */ (loadingPage.$$('#noScannersDiv')))); + /** @type {!HTMLElement} */ ( + loadingPage.shadowRoot.querySelector('#noScannersDiv')))); loadingPage.appState = AppState.NO_SCANNERS; - assertFalse( - isVisible(/** @type {!HTMLElement} */ (loadingPage.$$('#loadingDiv')))); + assertFalse(isVisible(/** @type {!HTMLElement} */ ( + loadingPage.shadowRoot.querySelector('#loadingDiv')))); assertTrue(isVisible( - /** @type {!HTMLElement} */ (loadingPage.$$('#noScannersDiv')))); + /** @type {!HTMLElement} */ ( + loadingPage.shadowRoot.querySelector('#noScannersDiv')))); }); // Verify clicking the retry button on the no scanners page fires the @@ -102,7 +104,7 @@ retryEventFired = true; }); - loadingPage.$$('#retryButton').click(); + loadingPage.shadowRoot.querySelector('#retryButton').click(); assertTrue(retryEventFired); }); @@ -116,7 +118,7 @@ learnMoreEventFired = true; }); - loadingPage.$$('#learnMoreButton').click(); + loadingPage.shadowRoot.querySelector('#learnMoreButton').click(); assertTrue(learnMoreEventFired); }); @@ -127,7 +129,7 @@ const lightModeSvg = `${scanningSrcBase}svg/no_scanners.svg`; const darkModeSvg = `${scanningSrcBase}svg/no_scanners_dark.svg`; const getNoScannersSvg = () => (/** @type {!HTMLImageElement} */ ( - loadingPage.$$('#noScannersDiv img'))); + loadingPage.shadowRoot.querySelector('#noScannersDiv img'))); // Setup UI to display no scanners div. loadingPage.appState = AppState.NO_SCANNERS; @@ -164,8 +166,8 @@ await setJellyEnabled(false); const lightModeSvg = `${scanningSrcBase}svg/scanners_loading.svg`; const darkModeSvg = `${scanningSrcBase}svg/scanners_loading_dark.svg`; - const getLoadingSvg = () => - (/** @type {!HTMLImageElement} */ (loadingPage.$$('#loadingDiv img'))); + const getLoadingSvg = () => (/** @type {!HTMLImageElement} */ ( + loadingPage.shadowRoot.querySelector('#loadingDiv img'))); // Setup UI to display no scanners div. loadingPage.appState = AppState.NO_SCANNERS;
diff --git a/chrome/test/data/webui/chromeos/scanning/multi_page_checkbox_test.js b/chrome/test/data/webui/chromeos/scanning/multi_page_checkbox_test.js index c9bf908..5cc88e0 100644 --- a/chrome/test/data/webui/chromeos/scanning/multi_page_checkbox_test.js +++ b/chrome/test/data/webui/chromeos/scanning/multi_page_checkbox_test.js
@@ -30,9 +30,9 @@ // both toggle the boolean. test('checkboxClicked', () => { assertFalse(multiPageCheckbox.multiPageScanChecked); - multiPageCheckbox.$$('cr-checkbox').click(); + multiPageCheckbox.shadowRoot.querySelector('cr-checkbox').click(); assertTrue(multiPageCheckbox.multiPageScanChecked); - multiPageCheckbox.$$('#checkboxText').click(); + multiPageCheckbox.shadowRoot.querySelector('#checkboxText').click(); assertFalse(multiPageCheckbox.multiPageScanChecked); }); });
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 8c2a0da..df191c9 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
@@ -46,14 +46,16 @@ .then(() => { assertEquals( 'Scan page 2', - multiPageScan.$$('#scanButton').textContent.trim()); + multiPageScan.shadowRoot.querySelector('#scanButton') + .textContent.trim()); multiPageScan.pageNumber = 2; return flushTasks(); }) .then(() => { assertEquals( 'Scan page 3', - multiPageScan.$$('#scanButton').textContent.trim()); + multiPageScan.shadowRoot.querySelector('#scanButton') + .textContent.trim()); }); }); @@ -64,7 +66,7 @@ scanNextPageEventFired = true; }); - multiPageScan.$$('#scanButton').click(); + multiPageScan.shadowRoot.querySelector('#scanButton').click(); assertTrue(scanNextPageEventFired); }); @@ -75,16 +77,18 @@ completeMultiPageScanEventFired = true; }); - multiPageScan.$$('#saveButton').click(); + multiPageScan.shadowRoot.querySelector('#saveButton').click(); assertTrue(completeMultiPageScanEventFired); }); // Verify the cancel button and progress text show while scanning. test('cancelButtonShowsWhileScanning', () => { const scanButton = - /** @type {!HTMLElement} */ (multiPageScan.$$('#scanButton')); + /** @type {!HTMLElement} */ ( + multiPageScan.shadowRoot.querySelector('#scanButton')); const cancelButton = - /** @type {!HTMLElement} */ (multiPageScan.$$('#cancelButton')); + /** @type {!HTMLElement} */ ( + multiPageScan.shadowRoot.querySelector('#cancelButton')); const pageNumber = 4; // Scan button should be visible. @@ -93,7 +97,8 @@ assertFalse(isVisible(cancelButton)); assertEquals( loadTimeData.getString('multiPageScanInstructionsText'), - multiPageScan.$$('#multiPageScanText').innerText.trim()); + multiPageScan.shadowRoot.querySelector('#multiPageScanText') + .innerText.trim()); // Cancel button should be visible while scanning. multiPageScan.pageNumber = pageNumber; @@ -102,14 +107,16 @@ assertTrue(isVisible(cancelButton)); assertEquals( loadTimeData.getStringF('multiPageScanProgressText', pageNumber), - multiPageScan.$$('#multiPageScanText').innerText.trim()); + multiPageScan.shadowRoot.querySelector('#multiPageScanText') + .innerText.trim()); }); // Verify the cancel button and canceling text are shown while canceling a // scan. test('cancelButtonShowsWhileCanceling', () => { const cancelButton = - /** @type {!HTMLElement} */ (multiPageScan.$$('#cancelButton')); + /** @type {!HTMLElement} */ ( + multiPageScan.shadowRoot.querySelector('#cancelButton')); // Cancel button should be visible and disabled. multiPageScan.appState = AppState.MULTI_PAGE_CANCELING; @@ -117,7 +124,8 @@ assertTrue(cancelButton.disabled); assertEquals( loadTimeData.getString('multiPageCancelingScanningText'), - multiPageScan.$$('#multiPageScanText').innerText.trim()); + multiPageScan.shadowRoot.querySelector('#multiPageScanText') + .innerText.trim()); }); // Verify clicking the cancel button fires the 'cancel-click' event. @@ -127,7 +135,7 @@ clickCancelEventFired = true; }); - multiPageScan.$$('#cancelButton').click(); + multiPageScan.shadowRoot.querySelector('#cancelButton').click(); assertTrue(clickCancelEventFired); }); });
diff --git a/chrome/test/data/webui/chromeos/scanning/page_size_select_test.js b/chrome/test/data/webui/chromeos/scanning/page_size_select_test.js index 68957d6..24eb06e 100644 --- a/chrome/test/data/webui/chromeos/scanning/page_size_select_test.js +++ b/chrome/test/data/webui/chromeos/scanning/page_size_select_test.js
@@ -34,7 +34,8 @@ test('initializePageSizeSelect', () => { // Before options are added, the dropdown should be enabled and empty. const select = - /** @type {!HTMLSelectElement} */ (pageSizeSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + pageSizeSelect.shadowRoot.querySelector('select')); assertTrue(!!select); assertFalse(select.disabled); assertEquals(0, select.length); @@ -99,7 +100,8 @@ // and the options change. test('selectDefaultWhenOptionsChange', () => { const select = - /** @type {!HTMLSelectElement} */ (pageSizeSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + pageSizeSelect.shadowRoot.querySelector('select')); pageSizeSelect.options = [PageSize.kNaLetter, PageSize.kMax, PageSize.kIsoA4]; flush();
diff --git a/chrome/test/data/webui/chromeos/scanning/resolution_select_test.js b/chrome/test/data/webui/chromeos/scanning/resolution_select_test.js index 45c1281..a8ac00f 100644 --- a/chrome/test/data/webui/chromeos/scanning/resolution_select_test.js +++ b/chrome/test/data/webui/chromeos/scanning/resolution_select_test.js
@@ -31,7 +31,8 @@ test('initializeResolutionSelect', () => { // Before options are added, the dropdown should be enabled and empty. const select = - /** @type {!HTMLSelectElement} */ (resolutionSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + resolutionSelect.shadowRoot.querySelector('select')); assertTrue(!!select); assertFalse(select.disabled); assertEquals(0, select.length); @@ -85,7 +86,8 @@ // and the options change. test('selectDefaultWhenOptionsChange', () => { const select = - /** @type {!HTMLSelectElement} */ (resolutionSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + resolutionSelect.shadowRoot.querySelector('select')); resolutionSelect.options = [600, 300, 150]; flush(); return changeSelect(select, /* value */ null, /* selectedIndex */ 0)
diff --git a/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js b/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js index e179200..ed53a56 100644 --- a/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js
@@ -40,7 +40,8 @@ // Verify the scan done section can be initialized. test('initializeScanDoneSection', () => { - assertTrue(!!scanDoneSection.$$('#doneButtonContainer')); + assertTrue( + !!scanDoneSection.shadowRoot.querySelector('#doneButtonContainer')); }); // Verify the file saved text updates correctly based on the number of files @@ -52,7 +53,8 @@ .then(() => { assertEquals( 'Your file has been successfully scanned and saved to My files.', - scanDoneSection.$$('#fileSavedText').textContent.trim()); + scanDoneSection.shadowRoot.querySelector('#fileSavedText') + .textContent.trim()); scanDoneSection.numFilesSaved = 2; return flushTasks(); }) @@ -60,7 +62,8 @@ assertEquals( 'Your files have been successfully scanned and saved to My ' + 'files.', - scanDoneSection.$$('#fileSavedText').textContent.trim()); + scanDoneSection.shadowRoot.querySelector('#fileSavedText') + .textContent.trim()); }); }); @@ -72,14 +75,16 @@ .then(() => { assertEquals( 'Your file has been successfully scanned and saved to Downloads.', - scanDoneSection.$$('#fileSavedText').textContent.trim()); + scanDoneSection.shadowRoot.querySelector('#fileSavedText') + .textContent.trim()); scanDoneSection.selectedFolder = 'My Drive'; return flushTasks(); }) .then(() => { assertEquals( 'Your file has been successfully scanned and saved to My Drive.', - scanDoneSection.$$('#fileSavedText').textContent.trim()); + scanDoneSection.shadowRoot.querySelector('#fileSavedText') + .textContent.trim()); }); }); @@ -96,7 +101,7 @@ scanDoneSection.scannedFilePaths = scannedFilePaths; scanDoneSection.numFilesSaved = 1; return flushTasks().then(() => { - scanDoneSection.$$('#folderLink').click(); + scanDoneSection.shadowRoot.querySelector('#folderLink').click(); return flushTasks().then(() => { assertEquals( 1, scanningBrowserProxy.getCallCount('showFileInLocation')); @@ -116,7 +121,7 @@ scanDoneSection.scannedFilePaths = [{'path': '/test/path/scan.jpg'}]; scanDoneSection.numFilesSaved = 1; return flushTasks().then(() => { - scanDoneSection.$$('#folderLink').click(); + scanDoneSection.shadowRoot.querySelector('#folderLink').click(); return flushTasks().then(() => { assertEquals( 1, scanningBrowserProxy.getCallCount('showFileInLocation')); @@ -132,7 +137,7 @@ doneEventFired = true; }); - scanDoneSection.$$('#doneButton').click(); + scanDoneSection.shadowRoot.querySelector('#doneButton').click(); assertTrue(doneEventFired); }); @@ -144,7 +149,7 @@ scanDoneSection.scannedFilePaths = scannedFilePaths; return flushTasks().then(() => { - scanDoneSection.$$('#showInFolderButton').click(); + scanDoneSection.shadowRoot.querySelector('#showInFolderButton').click(); return flushTasks().then(() => { assertEquals( 1, scanningBrowserProxy.getCallCount('showFileInLocation')); @@ -160,7 +165,7 @@ scanDoneSection.scannedFilePaths = scannedFilePaths; scanDoneSection.selectedFileType = FileType.kJpg.toString(); - scanDoneSection.$$('#editButton').click(); + scanDoneSection.shadowRoot.querySelector('#editButton').click(); const filePathsSentToMediaApp = /** @type {!Array<string>} */ ( scanningBrowserProxy.getArgs('openFilesInMediaApp')[0]); assertArrayEquals( @@ -172,7 +177,8 @@ // app doesn't support PDFs. test('editButtonHiddenForFileTypePdf', () => { const editButton = - /** @type {!HTMLElement} */ (scanDoneSection.$$('#editButton')); + /** @type {!HTMLElement} */ ( + scanDoneSection.shadowRoot.querySelector('#editButton')); scanDoneSection.selectedFileType = FileType.kPng.toString(); assertTrue(isVisible(editButton)); @@ -188,14 +194,16 @@ .then(() => { assertEquals( 'Edit file', - scanDoneSection.$$('#editButtonLabel').textContent.trim()); + scanDoneSection.shadowRoot.querySelector('#editButtonLabel') + .textContent.trim()); scanDoneSection.numFilesSaved = 2; return flushTasks(); }) .then(() => { assertEquals( 'Edit files', - scanDoneSection.$$('#editButtonLabel').textContent.trim()); + scanDoneSection.shadowRoot.querySelector('#editButtonLabel') + .textContent.trim()); }); }); });
diff --git a/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js b/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js index b429e175..dff4e04 100644 --- a/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scan_preview_test.js
@@ -121,15 +121,20 @@ document.body.appendChild(scanPreview); helpOrProgress = - /** @type {!HTMLElement} */ (scanPreview.$$('#helpOrProgress')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('#helpOrProgress')); helperText = - /** @type {!HTMLElement} */ (scanPreview.$$('#helperText')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('#helperText')); scanProgress = - /** @type {!HTMLElement} */ (scanPreview.$$('#scanProgress')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('#scanProgress')); scannedImages = - /** @type {!HTMLElement} */ (scanPreview.$$('#scannedImages')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('#scannedImages')); cancelingProgress = - /** @type {!HTMLElement} */ (scanPreview.$$('#cancelingProgress')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('#cancelingProgress')); }); teardown(() => { @@ -158,7 +163,7 @@ } test('initializeScanPreview', () => { - assertTrue(!!scanPreview.$$('.preview')); + assertTrue(!!scanPreview.shadowRoot.querySelector('.preview')); }); // Test that the progress text updates when the page number increases. @@ -167,11 +172,13 @@ scanPreview.pageNumber = 1; assertEquals( scanPreview.i18n('scanPreviewProgressText', 1), - scanPreview.$$('#progressText').textContent.trim()); + scanPreview.shadowRoot.querySelector('#progressText') + .textContent.trim()); scanPreview.pageNumber = 2; assertEquals( scanPreview.i18n('scanPreviewProgressText', 2), - scanPreview.$$('#progressText').textContent.trim()); + scanPreview.shadowRoot.querySelector('#progressText') + .textContent.trim()); }); // Tests that the correct element is showing in the preview pane depending on @@ -240,17 +247,19 @@ scanPreview.objectUrls = ['image']; scanPreview.appState = AppState.DONE; return flushTasks().then(() => { - assertTrue(scanPreview.$$('action-toolbar').hidden); + assertTrue(scanPreview.shadowRoot.querySelector('action-toolbar').hidden); scanPreview.appState = AppState.MULTI_PAGE_NEXT_ACTION; flush(); - assertFalse(scanPreview.$$('action-toolbar').hidden); + assertFalse( + scanPreview.shadowRoot.querySelector('action-toolbar').hidden); }); }); // Tests that the toolbar will get repositioned after subsequent scans. test('positionActionToolbarOnSubsequentScans', () => { const scannedImagesDiv = - /** @type {!HTMLElement} */ (scanPreview.$$('#scannedImages')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('#scannedImages')); scanPreview.objectUrls = []; scanPreview.isMultiPageScan = true; scanPreview.appState = AppState.MULTI_PAGE_SCANNING; @@ -311,26 +320,33 @@ scanPreview.objectUrls = [testSvgPath]; return flushTasks() .then(() => { - assertFalse(scanPreview.$$('#scanPreviewDialog').open); - scanPreview.$$('action-toolbar') + assertFalse( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); + scanPreview.shadowRoot.querySelector('action-toolbar') .dispatchEvent(new CustomEvent( 'show-remove-page-dialog', {detail: pageIndexToRemove})); return flushTasks(); }) .then(() => { - assertTrue(scanPreview.$$('#scanPreviewDialog').open); + assertTrue( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); assertEquals( 'Remove page?', - scanPreview.$$('#dialogTitle').textContent.trim()); + scanPreview.shadowRoot.querySelector('#dialogTitle') + .textContent.trim()); assertEquals( - 'Remove', scanPreview.$$('#actionButton').textContent.trim()); + 'Remove', + scanPreview.shadowRoot.querySelector('#actionButton') + .textContent.trim()); assertEquals( loadTimeData.getStringF( 'removePageConfirmationText', pageIndexToRemove + 1), - scanPreview.$$('#dialogConfirmationText').textContent.trim()); + scanPreview.shadowRoot.querySelector('#dialogConfirmationText') + .textContent.trim()); - scanPreview.$$('#actionButton').click(); - assertFalse(scanPreview.$$('#scanPreviewDialog').open); + scanPreview.shadowRoot.querySelector('#actionButton').click(); + assertFalse( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); assertEquals(pageIndexToRemove, pageIndexFromEvent); }); }); @@ -338,18 +354,21 @@ // Tests that clicking the cancel button closes the remove page dialog. test('cancelRemovePageDialog', () => { scanPreview.objectUrls = ['image']; - assertFalse(scanPreview.$$('#scanPreviewDialog').open); + assertFalse( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); return flushTasks() .then(() => { - scanPreview.$$('action-toolbar') + scanPreview.shadowRoot.querySelector('action-toolbar') .dispatchEvent(new CustomEvent('show-remove-page-dialog')); return flushTasks(); }) .then(() => { - assertTrue(scanPreview.$$('#scanPreviewDialog').open); + assertTrue( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); - scanPreview.$$('#cancelButton').click(); - assertFalse(scanPreview.$$('#scanPreviewDialog').open); + scanPreview.shadowRoot.querySelector('#cancelButton').click(); + assertFalse( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); }); }); @@ -357,22 +376,26 @@ test('rescanPageDialog', () => { const pageIndex = 6; scanPreview.objectUrls = ['image1', 'image2']; - assertFalse(scanPreview.$$('#scanPreviewDialog').open); + assertFalse( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); return flushTasks() .then(() => { - scanPreview.$$('action-toolbar') + scanPreview.shadowRoot.querySelector('action-toolbar') .dispatchEvent(new CustomEvent( 'show-rescan-page-dialog', {detail: pageIndex})); return flushTasks(); }) .then(() => { - assertTrue(scanPreview.$$('#scanPreviewDialog').open); + assertTrue( + scanPreview.shadowRoot.querySelector('#scanPreviewDialog').open); assertEquals( 'Rescan page ' + (pageIndex + 1) + '?', - scanPreview.$$('#dialogTitle').textContent.trim()); + scanPreview.shadowRoot.querySelector('#dialogTitle') + .textContent.trim()); assertEquals( loadTimeData.getStringF('rescanPageConfirmationText', pageIndex), - scanPreview.$$('#dialogConfirmationText').textContent.trim()); + scanPreview.shadowRoot.querySelector('#dialogConfirmationText') + .textContent.trim()); }); }); @@ -380,7 +403,8 @@ // repositioning of the action toolbar. test('resizingWindowRepositionsActionToolbar', () => { const scannedImagesDiv = - /** @type {!HTMLElement} */ (scanPreview.$$('#scannedImages')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('#scannedImages')); scanPreview.objectUrls = ['image']; scanPreview.isMultiPageScan = true; scanPreview.appState = AppState.MULTI_PAGE_SCANNING; @@ -447,7 +471,8 @@ scanPreview.appState = AppState.MULTI_PAGE_NEXT_ACTION; flush(); const actionToolbar = - /** @type {!HTMLElement} */ (scanPreview.$$('action-toolbar')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('action-toolbar')); assertEquals( 'hidden', getComputedStyle(actionToolbar).getPropertyValue('visibility')); @@ -457,7 +482,8 @@ }) .then(() => { const actionToolbar = - /** @type {!HTMLElement} */ (scanPreview.$$('action-toolbar')); + /** @type {!HTMLElement} */ ( + scanPreview.shadowRoot.querySelector('action-toolbar')); assertEquals( 'visible', getComputedStyle(actionToolbar).getPropertyValue('visibility')); @@ -471,8 +497,8 @@ const srcBase = 'chrome://scanning/'; const lightModeSvg = `${srcBase}svg/ready_to_scan.svg`; const darkModeSvg = `${srcBase}svg/ready_to_scan_dark.svg`; - const getReadyToScanSvg = () => - (/** @type {!HTMLImageElement} */ (scanPreview.$$('#readyToScanImg'))); + const getReadyToScanSvg = () => (/** @type {!HTMLImageElement} */ ( + scanPreview.shadowRoot.querySelector('#readyToScanImg'))); // Mock media query state for light mode. await setFakePrefersColorSchemeDark(false);
diff --git a/chrome/test/data/webui/chromeos/scanning/scan_to_select_test.js b/chrome/test/data/webui/chromeos/scanning/scan_to_select_test.js index 37531cad..35003cc 100644 --- a/chrome/test/data/webui/chromeos/scanning/scan_to_select_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scan_to_select_test.js
@@ -41,7 +41,7 @@ // Verifies the 'Scan To' dropdown is initialized enabled with the 'My files' // and 'Select folder' option. test('initializeScanToSelect', () => { - const select = scanToSelect.$$('select'); + const select = scanToSelect.shadowRoot.querySelector('select'); assertTrue(!!select); assertFalse(select.disabled); assertEquals(2, select.length); @@ -61,7 +61,8 @@ scanningBrowserProxy.setSelectedPath( {baseName: myDownloads, filePath: myDownloadsPath}); const select = - /** @type {!HTMLSelectElement} */ (scanToSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + scanToSelect.shadowRoot.querySelector('select')); return changeSelect(select, /* value */ null, /* selectedIndex */ 1) .then(() => { assertEquals(myDownloads, scanToSelect.selectedFolder); @@ -95,7 +96,8 @@ scanningBrowserProxy.setSelectedPath( {baseName: myDownloads, filePath: myDownloadsPath}); const select = - /** @type {!HTMLSelectElement} */ (scanToSelect.$$('select')); + /** @type {!HTMLSelectElement} */ ( + scanToSelect.shadowRoot.querySelector('select')); return changeSelect(select, /* value */ null, /* selectedIndex */ 1) .then(() => { assertEquals(myDownloads, scanToSelect.selectedFolder);
diff --git a/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js b/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js index 211db29..38d32b6 100644 --- a/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js
@@ -43,7 +43,7 @@ // Verify the scanner select is initialized enabled with two expected // scanners and the first scanner selected. test('initializeScannerSelect', () => { - const select = scannerSelect.$$('select'); + const select = scannerSelect.shadowRoot.querySelector('select'); assertTrue(!!select); const scannerArr = [ @@ -95,7 +95,9 @@ return waitAfterNextRender(scannerSelect).then(() => { assertEquals(secondScannerIdString, scannerSelect.selectedScannerId); - assertEquals(secondScannerIdString, scannerSelect.$$('select').value); + assertEquals( + secondScannerIdString, + scannerSelect.shadowRoot.querySelector('select').value); }); }); @@ -113,7 +115,9 @@ const firstScannerIdString = tokenToString(firstScannerId); return waitAfterNextRender(scannerSelect).then(() => { assertEquals(firstScannerIdString, scannerSelect.selectedScannerId); - assertEquals(firstScannerIdString, scannerSelect.$$('select').value); + assertEquals( + firstScannerIdString, + scannerSelect.shadowRoot.querySelector('select').value); }); }); });
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 c39c9027..4a12f15 100644 --- a/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
@@ -516,7 +516,8 @@ document.body.appendChild(scanningApp); assertTrue(!!scanningApp); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('loading-page')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('loading-page')))); return fakeScanService_.whenCalled('getScanners'); } @@ -526,7 +527,8 @@ */ function getMoreSettingsButton() { const button = - /** @type {!CrButtonElement} */ (scanningApp.$$('#moreSettingsButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#moreSettingsButton')); assertTrue(!!button); return button; } @@ -545,7 +547,8 @@ * @return {!Promise} */ function clickDoneButton() { - const button = scanningApp.$$('scan-done-section').$$('#doneButton'); + const button = scanningApp.shadowRoot.querySelector('scan-done-section') + .shadowRoot.querySelector('#doneButton'); assertTrue(!!button); button.click(); return flushTasks(); @@ -556,7 +559,7 @@ * @return {!Promise} */ function clickScanFailedDialogOkButton() { - const button = scanningApp.$$('#okButton'); + const button = scanningApp.shadowRoot.querySelector('#okButton'); assertTrue(!!button); button.click(); return flushTasks(); @@ -567,7 +570,7 @@ * @return {boolean} */ function isSettingsOpen() { - return scanningApp.$$('#collapse').opened; + return scanningApp.shadowRoot.querySelector('#collapse').opened; } /** @@ -618,24 +621,43 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { assertFalse(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('loading-page')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('loading-page')))); - scannerSelect = scanningApp.$$('#scannerSelect').$$('select'); - sourceSelect = scanningApp.$$('#sourceSelect').$$('select'); - scanToSelect = scanningApp.$$('#scanToSelect').$$('select'); - fileTypeSelect = scanningApp.$$('#fileTypeSelect').$$('select'); - colorModeSelect = scanningApp.$$('#colorModeSelect').$$('select'); - pageSizeSelect = scanningApp.$$('#pageSizeSelect').$$('select'); - resolutionSelect = scanningApp.$$('#resolutionSelect').$$('select'); + scannerSelect = scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select'); + sourceSelect = scanningApp.shadowRoot.querySelector('#sourceSelect') + .shadowRoot.querySelector('select'); + scanToSelect = scanningApp.shadowRoot.querySelector('#scanToSelect') + .shadowRoot.querySelector('select'); + fileTypeSelect = + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select'); + colorModeSelect = + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select'); + pageSizeSelect = + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select'); + resolutionSelect = + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select'); scanButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#scanButton')); cancelButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#cancelButton')); - helperText = scanningApp.$$('#scanPreview').$$('#helperText'); - scanProgress = scanningApp.$$('#scanPreview').$$('#scanProgress'); - progressText = scanningApp.$$('#scanPreview').$$('#progressText'); - progressBar = scanningApp.$$('#scanPreview').$$('paper-progress'); - scannedImages = scanningApp.$$('#scanPreview').$$('#scannedImages'); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#cancelButton')); + helperText = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#helperText'); + scanProgress = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scanProgress'); + progressText = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#progressText'); + progressBar = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('paper-progress'); + scannedImages = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scannedImages'); return getScannerCapabilities(); }) .then(() => { @@ -674,7 +696,7 @@ assertFalse(isVisible(/** @type {!HTMLElement} */ (scanProgress))); assertFalse(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('scan-done-section')))); + scanningApp.shadowRoot.querySelector('scan-done-section')))); // Click the Scan button and wait till the scan is started. scanButton.click(); @@ -699,7 +721,7 @@ assertTrue(isVisible(/** @type {!HTMLElement} */ (scanProgress))); assertFalse(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('scan-done-section')))); + scanningApp.shadowRoot.querySelector('scan-done-section')))); assertEquals('Scanning page 1', progressText.textContent.trim()); assertEquals(0, progressBar.value); @@ -742,10 +764,11 @@ assertEquals(2, scannedImages.querySelectorAll('img').length); assertTrue(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('scan-done-section')))); + scanningApp.shadowRoot.querySelector('scan-done-section')))); assertArrayEquals( scannedFilePaths, - scanningApp.$$('scan-done-section').scannedFilePaths); + scanningApp.shadowRoot.querySelector('scan-done-section') + .scannedFilePaths); // Click the Done button to return to READY state. return clickDoneButton(); @@ -768,7 +791,7 @@ assertFalse(isVisible(/** @type {!HTMLElement} */ (scanProgress))); assertFalse(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('scan-done-section')))); + scanningApp.shadowRoot.querySelector('scan-done-section')))); assertFalse(isVisible(/** @type {!HTMLElement} */ (scannedImages))); assertEquals(0, scannedImages.querySelectorAll('img').length); }); @@ -779,7 +802,8 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { scanButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#scanButton')); return getScannerCapabilities(); }) .then(() => { @@ -797,14 +821,16 @@ }) .then(() => { // The scan failed dialog should open. - assertTrue(scanningApp.$$('#scanFailedDialog').open); + assertTrue( + scanningApp.shadowRoot.querySelector('#scanFailedDialog').open); // Click the dialog's Ok button to return to READY state. return clickScanFailedDialogOkButton(); }) .then(() => { // After the dialog closes, the scan button should be enabled and // ready to start a new scan. - assertFalse(scanningApp.$$('#scanFailedDialog').open); + assertFalse( + scanningApp.shadowRoot.querySelector('#scanFailedDialog').open); assertFalse(scanButton.disabled); assertTrue(isVisible(/** @type {!CrButtonElement} */ (scanButton))); }); @@ -816,7 +842,8 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { scanButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#scanButton')); return getScannerCapabilities(); }) .then(() => { @@ -834,7 +861,8 @@ return fakeScanService_.simulateScanComplete(ScanResult.kIoError, []); }) .then(() => { - const scanFailedDialog = scanningApp.$$('#scanFailedDialog'); + const scanFailedDialog = + scanningApp.shadowRoot.querySelector('#scanFailedDialog'); // The scan failed dialog should open. assertTrue(scanFailedDialog.open); @@ -843,7 +871,8 @@ // dialog. scanFailedDialog.shadowRoot.querySelector('#dialog').dispatchEvent( new Event('cancel')); - assertFalse(scanningApp.$$('#scanFailedDialog').open); + assertFalse( + scanningApp.shadowRoot.querySelector('#scanFailedDialog').open); assertFalse(scanButton.disabled); assertTrue(isVisible(/** @type {!CrButtonElement} */ (scanButton))); }); @@ -868,7 +897,8 @@ scanningApp.multiPageScanChecked = true; }) .then(() => { - const scanButton = scanningApp.$$('#scanButton'); + const scanButton = + scanningApp.shadowRoot.querySelector('#scanButton'); assertEquals('Scan page 1', scanButton.textContent.trim()); scanButton.click(); return fakeScanService_.whenCalled('startMultiPageScan'); @@ -880,12 +910,15 @@ .then(() => { // The scanned images and multi-page scan page should be visible. assertTrue(isVisible(/** @type {!HTMLElement} */ ( - scanningApp.$$('#scanPreview').$$('#scannedImages')))); + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scannedImages')))); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('multi-page-scan')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('multi-page-scan')))); const scanNextPageButton = - scanningApp.$$('multi-page-scan').$$('#scanButton'); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton'); assertEquals('Scan page 2', scanNextPageButton.textContent.trim()); scanNextPageButton.click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); @@ -894,10 +927,12 @@ // Cancel button should be visible while scanning. assertFalse(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('multi-page-scan').$$('#scanButton')))); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton')))); assertTrue(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('multi-page-scan').$$('#cancelButton')))); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#cancelButton')))); return fakeScanService_.simulatePageComplete( /*pageNumber=*/ 1, newPageIndex++); @@ -906,15 +941,20 @@ // The scanned images and multi-page scan page should still be visible // after scanning the next page. assertTrue(isVisible(/** @type {!HTMLElement} */ ( - scanningApp.$$('#scanPreview').$$('#scannedImages')))); + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scannedImages')))); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('multi-page-scan')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('multi-page-scan')))); const scanNextPageButton = - scanningApp.$$('multi-page-scan').$$('#scanButton'); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton'); assertEquals('Scan page 3', scanNextPageButton.textContent.trim()); - scanningApp.$$('multi-page-scan').$$('#saveButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#saveButton') + .click(); return fakeMultiPageScanController_.whenCalled( 'completeMultiPageScan'); }) @@ -923,14 +963,16 @@ ScanResult.kSuccess, scannedFilePaths); }) .then(() => { - scannedImages = scanningApp.$$('#scanPreview').$$('#scannedImages'); + scannedImages = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scannedImages'); assertTrue(isVisible(/** @type {!HTMLElement} */ (scannedImages))); assertTrue(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('scan-done-section')))); + scanningApp.shadowRoot.querySelector('scan-done-section')))); assertArrayEquals( scannedFilePaths, - scanningApp.$$('scan-done-section').scannedFilePaths); + scanningApp.shadowRoot.querySelector('scan-done-section') + .scannedFilePaths); }); }); @@ -952,37 +994,41 @@ scanningApp.multiPageScanChecked = true; }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { assertEquals( 'Scanning page 1', - scanningApp.$$('#scanPreview') - .$$('#progressText') + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#progressText') .textContent.trim()); return fakeScanService_.simulatePageComplete( /*pageNumber=*/ 1, newPageIndex++); }) .then(() => { - scanningApp.$$('multi-page-scan').$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton') + .click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); }) .then(() => { assertEquals( 'Scanning page 2', - scanningApp.$$('#scanPreview') - .$$('#progressText') + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#progressText') .textContent.trim()); return fakeScanService_.simulateMultiPageScanFail( ScanResult.kFlatbedOpen); }) .then(() => { // The scan failed dialog should open. - assertTrue(scanningApp.$$('#scanFailedDialog').open); + assertTrue( + scanningApp.shadowRoot.querySelector('#scanFailedDialog').open); assertEquals( loadTimeData.getString('scanFailedDialogFlatbedOpenText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); // Click the dialog's Ok button to return to MULTI_PAGE_NEXT_ACTION // state. @@ -992,7 +1038,8 @@ // After the dialog closes, the scan next page button should still // say 'Scan Page 2'. const scanNextPageButton = - scanningApp.$$('multi-page-scan').$$('#scanButton'); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton'); assertEquals('Scan page 2', scanNextPageButton.textContent.trim()); scanNextPageButton.click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); @@ -1000,14 +1047,16 @@ .then(() => { assertEquals( 'Scanning page 2', - scanningApp.$$('#scanPreview') - .$$('#progressText') + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#progressText') .textContent.trim()); return fakeScanService_.simulatePageComplete( /*pageNumber=*/ 1, newPageIndex++); }) .then(() => { - scanningApp.$$('multi-page-scan').$$('#saveButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#saveButton') + .click(); return fakeMultiPageScanController_.whenCalled( 'completeMultiPageScan'); }) @@ -1016,7 +1065,8 @@ ScanResult.kSuccess, [{'path': '/test/path/scan1.pdf'}]); }) .then(() => { - scannedImages = scanningApp.$$('#scanPreview').$$('#scannedImages'); + scannedImages = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scannedImages'); // There should be 2 images from scanning once, failing once, then // scanning again successfully. @@ -1039,7 +1089,7 @@ }) .then(() => { scanningApp.multiPageScanChecked = true; - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { @@ -1047,18 +1097,23 @@ /*pageNumber=*/ 1, newPageIndex++); }) .then(() => { - scanningApp.$$('multi-page-scan').$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton') + .click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); }) .then(() => { // Click the Cancel button to cancel the scan. - scanningApp.$$('multi-page-scan').$$('#cancelButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#cancelButton') + .click(); return fakeScanService_.whenCalled('cancelScan'); }) .then(() => { // Cancel button should be disabled while canceling is in progress. - assertTrue( - scanningApp.$$('multi-page-scan').$$('#cancelButton').disabled); + assertTrue(scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#cancelButton') + .disabled); // Simulate cancel completing successfully. return fakeScanService_.simulateCancelComplete(true); @@ -1068,13 +1123,15 @@ // visible and showing the correct page number to scan. The cancel // button should be hidden. const scanNextPageButton = - scanningApp.$$('multi-page-scan').$$('#scanButton'); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton'); assertTrue( isVisible(/** @type {!CrButtonElement} */ (scanNextPageButton))); assertEquals('Scan page 2', scanNextPageButton.textContent.trim()); assertFalse(isVisible(/** @type {!CrButtonElement} */ ( - scanningApp.$$('multi-page-scan').$$('#cancelButton')))); - assertTrue(scanningApp.$$('#toast').open); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#cancelButton')))); + assertTrue(scanningApp.shadowRoot.querySelector('#toast').open); }); }); @@ -1098,7 +1155,7 @@ scanningApp.multiPageScanChecked = true; }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { @@ -1106,7 +1163,9 @@ /*pageNumber=*/ 1, newPageIndex++); }) .then(() => { - scanningApp.$$('multi-page-scan').$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton') + .click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); }) .then(() => { @@ -1114,7 +1173,9 @@ /*pageNumber=*/ 1, newPageIndex++); }) .then(() => { - scanningApp.$$('multi-page-scan').$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton') + .click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); }) .then(() => { @@ -1123,18 +1184,21 @@ }) .then(() => { // Save the current scanned images - expectedObjectUrls = scanningApp.$$('#scanPreview').objectUrls; + expectedObjectUrls = + scanningApp.shadowRoot.querySelector('#scanPreview').objectUrls; assertEquals(3, expectedObjectUrls.length); // Open the remove page dialog. - scanningApp.$$('#scanPreview') - .$$('action-toolbar') + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('action-toolbar') .dispatchEvent(new CustomEvent( 'show-remove-page-dialog', {detail: pageIndexToRemove})); return flushTasks(); }) .then(() => { - scanningApp.$$('#scanPreview').$$('#actionButton').click(); + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#actionButton') + .click(); return flushTasks(); }) .then(() => { @@ -1146,7 +1210,8 @@ // the correct image was removed from the actual scanned images. expectedObjectUrls.splice(pageIndexToRemove, 1); assertArrayEquals( - expectedObjectUrls, scanningApp.$$('#scanPreview').objectUrls); + expectedObjectUrls, + scanningApp.shadowRoot.querySelector('#scanPreview').objectUrls); }); }); @@ -1169,7 +1234,7 @@ scanningApp.multiPageScanChecked = true; }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { @@ -1178,22 +1243,26 @@ }) .then(() => { // Open the remove page dialog. - scanningApp.$$('#scanPreview') - .$$('action-toolbar') + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('action-toolbar') .dispatchEvent( new CustomEvent('show-remove-page-dialog', {detail: 0})); return flushTasks(); }) .then(() => { - scanningApp.$$('#scanPreview').$$('#actionButton').click(); + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#actionButton') + .click(); return flushTasks(); }) .then(() => { - assertArrayEquals([], scanningApp.$$('#scanPreview').objectUrls); + assertArrayEquals( + [], + scanningApp.shadowRoot.querySelector('#scanPreview').objectUrls); --newPageIndex; // Attempt a new multi-page scan from the scan settings page. - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { @@ -1203,12 +1272,15 @@ .then(() => { // The scanned images and multi-page scan page should be visible. assertTrue(isVisible(/** @type {!HTMLElement} */ ( - scanningApp.$$('#scanPreview').$$('#scannedImages')))); + scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scannedImages')))); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('multi-page-scan')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('multi-page-scan')))); const scanNextPageButton = - scanningApp.$$('multi-page-scan').$$('#scanButton'); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton'); assertEquals('Scan page 2', scanNextPageButton.textContent.trim()); }); }); @@ -1225,7 +1297,7 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { - scanPreview = scanningApp.$$('#scanPreview'); + scanPreview = scanningApp.shadowRoot.querySelector('#scanPreview'); return getScannerCapabilities(); }) .then(() => { @@ -1237,7 +1309,7 @@ scanningApp.multiPageScanChecked = true; }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { @@ -1250,7 +1322,7 @@ assertEquals(1, expectedObjectUrls.length); // Open the rescan page dialog. - scanPreview.$$('action-toolbar') + scanPreview.shadowRoot.querySelector('action-toolbar') .dispatchEvent(new CustomEvent( 'show-rescan-page-dialog', {detail: pageIndexToRescan})); return flushTasks(); @@ -1259,15 +1331,16 @@ // Verify the dialog shows we are rescanning the correct page number. assertEquals( 'Rescan page?', - scanPreview.$$('#dialogTitle').textContent.trim()); + scanPreview.shadowRoot.querySelector('#dialogTitle') + .textContent.trim()); - scanPreview.$$('#actionButton').click(); + scanPreview.shadowRoot.querySelector('#actionButton').click(); return fakeMultiPageScanController_.whenCalled('rescanPage'); }) .then(() => { // Verify the progress text shows we are attempting to rescan the // first page. - progressText = scanPreview.$$('#progressText'); + progressText = scanPreview.shadowRoot.querySelector('#progressText'); assertEquals('Scanning page 1', progressText.textContent.trim()); assertEquals( pageIndexToRescan, @@ -1283,7 +1356,9 @@ }) .then(() => { // Save the one page scan. - scanningApp.$$('multi-page-scan').$$('#saveButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#saveButton') + .click(); return fakeMultiPageScanController_.whenCalled( 'completeMultiPageScan'); }) @@ -1292,14 +1367,16 @@ ScanResult.kSuccess, scannedFilePaths); }) .then(() => { - scannedImages = scanningApp.$$('#scanPreview').$$('#scannedImages'); + scannedImages = scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scannedImages'); assertTrue(isVisible(/** @type {!HTMLElement} */ (scannedImages))); assertTrue(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('scan-done-section')))); + scanningApp.shadowRoot.querySelector('scan-done-section')))); assertArrayEquals( scannedFilePaths, - scanningApp.$$('scan-done-section').scannedFilePaths); + scanningApp.shadowRoot.querySelector('scan-done-section') + .scannedFilePaths); }); }); @@ -1315,7 +1392,7 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { - scanPreview = scanningApp.$$('#scanPreview'); + scanPreview = scanningApp.shadowRoot.querySelector('#scanPreview'); return getScannerCapabilities(); }) .then(() => { @@ -1327,7 +1404,7 @@ scanningApp.multiPageScanChecked = true; }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { @@ -1335,7 +1412,9 @@ /*pageNumber=*/ 1, newPageIndex++); }) .then(() => { - scanningApp.$$('multi-page-scan').$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton') + .click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); }) .then(() => { @@ -1348,7 +1427,7 @@ assertEquals(2, expectedObjectUrls.length); // Open the rescan page dialog. - scanPreview.$$('action-toolbar') + scanPreview.shadowRoot.querySelector('action-toolbar') .dispatchEvent(new CustomEvent( 'show-rescan-page-dialog', {detail: pageIndexToRescan})); return flushTasks(); @@ -1357,15 +1436,16 @@ // Verify the dialog shows we are rescanning the correct page number. assertEquals( 'Rescan page 1?', - scanPreview.$$('#dialogTitle').textContent.trim()); + scanPreview.shadowRoot.querySelector('#dialogTitle') + .textContent.trim()); - scanPreview.$$('#actionButton').click(); + scanPreview.shadowRoot.querySelector('#actionButton').click(); return fakeMultiPageScanController_.whenCalled('rescanPage'); }) .then(() => { // Verify the progress text shows we are attempting to rescan the // first page. - progressText = scanPreview.$$('#progressText'); + progressText = scanPreview.shadowRoot.querySelector('#progressText'); assertEquals('Scanning page 1', progressText.textContent.trim()); assertEquals( pageIndexToRescan, @@ -1385,7 +1465,8 @@ // Verify that after rescanning, the scan button shows the correct // next page number to scan. const scanButton = - scanningApp.$$('multi-page-scan').$$('#scanButton'); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton'); assertEquals('Scan page 3', scanButton.textContent.trim()); scanButton.click(); @@ -1411,7 +1492,7 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { - scanPreview = scanningApp.$$('#scanPreview'); + scanPreview = scanningApp.shadowRoot.querySelector('#scanPreview'); return getScannerCapabilities(); }) .then(() => { @@ -1423,7 +1504,7 @@ scanningApp.multiPageScanChecked = true; }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { @@ -1431,7 +1512,9 @@ /*pageNumber=*/ 1, newPageIndex++); }) .then(() => { - scanningApp.$$('multi-page-scan').$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton') + .click(); return fakeMultiPageScanController_.whenCalled('scanNextPage'); }) .then(() => { @@ -1444,13 +1527,13 @@ assertEquals(2, expectedObjectUrls.length); // Open the rescan page dialog. - scanPreview.$$('action-toolbar') + scanPreview.shadowRoot.querySelector('action-toolbar') .dispatchEvent(new CustomEvent( 'show-rescan-page-dialog', {detail: pageIndexToRescan})); return flushTasks(); }) .then(() => { - scanPreview.$$('#actionButton').click(); + scanPreview.shadowRoot.querySelector('#actionButton').click(); return fakeMultiPageScanController_.whenCalled('rescanPage'); }) .then(() => { @@ -1459,10 +1542,12 @@ }) .then(() => { // The scan failed dialog should open. - assertTrue(scanningApp.$$('#scanFailedDialog').open); + assertTrue( + scanningApp.shadowRoot.querySelector('#scanFailedDialog').open); assertEquals( loadTimeData.getString('scanFailedDialogFlatbedOpenText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); // Click the dialog's Ok button to return to MULTI_PAGE_NEXT_ACTION // state. @@ -1477,8 +1562,8 @@ // Verify the scan button shows the correct next page number to scan. assertEquals( 'Scan page 3', - scanningApp.$$('multi-page-scan') - .$$('#scanButton') + scanningApp.shadowRoot.querySelector('multi-page-scan') + .shadowRoot.querySelector('#scanButton') .textContent.trim()); }); }); @@ -1488,7 +1573,8 @@ test('SourceChangeUpdatesDropdowns', () => { return initializeScanningApp(expectedScanners.slice(1), capabilities) .then(() => { - sourceSelect = scanningApp.$$('#sourceSelect').$$('select'); + sourceSelect = scanningApp.shadowRoot.querySelector('#sourceSelect') + .shadowRoot.querySelector('select'); return getScannerCapabilities(); }) .then(() => { @@ -1498,9 +1584,15 @@ /* value=*/ null, /* selectedIndex=*/ 0); }) .then(() => { - colorModeSelect = scanningApp.$$('#colorModeSelect').$$('select'); - pageSizeSelect = scanningApp.$$('#pageSizeSelect').$$('select'); - resolutionSelect = scanningApp.$$('#resolutionSelect').$$('select'); + colorModeSelect = + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select'); + pageSizeSelect = + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select'); + resolutionSelect = + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select'); assertEquals(2, colorModeSelect.length); assertEquals( @@ -1555,7 +1647,8 @@ }) .then(() => { scanButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#scanButton')); scanButton.click(); return fakeScanService_.whenCalled('startScan'); }) @@ -1566,7 +1659,8 @@ .then(() => { assertEquals( loadTimeData.getString('scanFailedDialogUnknownErrorText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); return clickScanFailedDialogOkButton(); }) .then(() => { @@ -1580,7 +1674,8 @@ .then(() => { assertEquals( loadTimeData.getString('scanFailedDialogDeviceBusyText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); return clickScanFailedDialogOkButton(); }) .then(() => { @@ -1594,7 +1689,8 @@ .then(() => { assertEquals( loadTimeData.getString('scanFailedDialogAdfJammedText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); return clickScanFailedDialogOkButton(); }) .then(() => { @@ -1608,7 +1704,8 @@ .then(() => { assertEquals( loadTimeData.getString('scanFailedDialogAdfEmptyText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); return clickScanFailedDialogOkButton(); }) .then(() => { @@ -1622,7 +1719,8 @@ .then(() => { assertEquals( loadTimeData.getString('scanFailedDialogFlatbedOpenText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); return clickScanFailedDialogOkButton(); }) .then(() => { @@ -1635,7 +1733,8 @@ .then(() => { assertEquals( loadTimeData.getString('scanFailedDialogIoErrorText'), - scanningApp.$$('#scanFailedDialogText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#scanFailedDialogText') + .textContent.trim()); return clickScanFailedDialogOkButton(); }); }); @@ -1645,9 +1744,11 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { scanButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#scanButton')); cancelButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#cancelButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#cancelButton')); return getScannerCapabilities(); }) .then(() => { @@ -1691,14 +1792,17 @@ assertTrue(isVisible(/** @type {!CrButtonElement} */ (scanButton))); assertFalse( isVisible(/** @type {!CrButtonElement} */ (cancelButton))); - assertTrue(scanningApp.$$('#toast').open); + assertTrue(scanningApp.shadowRoot.querySelector('#toast').open); assertFalse(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#toastInfoIcon')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#toastInfoIcon')))); assertFalse(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#getHelpLink')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#getHelpLink')))); assertEquals( scanningApp.i18n('scanCanceledToastText'), - scanningApp.$$('#toastText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#toastText') + .textContent.trim()); }); }); @@ -1707,9 +1811,11 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { scanButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#scanButton')); cancelButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#cancelButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#cancelButton')); return getScannerCapabilities(); }) .then(() => { @@ -1725,7 +1831,7 @@ .then(() => { // Click the cancel button to cancel the scan. cancelButton.click(); - assertFalse(scanningApp.$$('#toast').open); + assertFalse(scanningApp.shadowRoot.querySelector('#toast').open); return fakeScanService_.whenCalled('cancelScan'); }) .then(() => { @@ -1736,21 +1842,26 @@ }) .then(() => { // After canceling fails, the error toast should pop up. - assertTrue(scanningApp.$$('#toast').open); + assertTrue(scanningApp.shadowRoot.querySelector('#toast').open); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#toastInfoIcon')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#toastInfoIcon')))); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#getHelpLink')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#getHelpLink')))); assertEquals( scanningApp.i18n('cancelFailedToastText'), - scanningApp.$$('#toastText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#toastText') + .textContent.trim()); // The scan progress page should still be showing with the cancel // button visible. assertTrue( - isVisible(scanningApp.$$('#scanPreview').$$('#scanProgress'))); + isVisible(scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#scanProgress'))); assertTrue(isVisible(/** @type {!CrButtonElement} */ (cancelButton))); assertFalse( - isVisible(scanningApp.$$('#scanPreview').$$('#helperText'))); + isVisible(scanningApp.shadowRoot.querySelector('#scanPreview') + .shadowRoot.querySelector('#helperText'))); assertFalse(isVisible(/** @type {!CrButtonElement} */ (scanButton))); }); }); @@ -1762,24 +1873,28 @@ return initializeScanningApp(expectedScanners, capabilities) .then(() => { scanButton = - /** @type {!CrButtonElement} */ (scanningApp.$$('#scanButton')); + /** @type {!CrButtonElement} */ ( + scanningApp.shadowRoot.querySelector('#scanButton')); return getScannerCapabilities(); }) .then(() => { - assertFalse(scanningApp.$$('#toast').open); + assertFalse(scanningApp.shadowRoot.querySelector('#toast').open); // Click the Scan button and the scan will fail to start. scanButton.click(); return fakeScanService_.whenCalled('startScan'); }) .then(() => { - assertTrue(scanningApp.$$('#toast').open); + assertTrue(scanningApp.shadowRoot.querySelector('#toast').open); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#toastInfoIcon')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#toastInfoIcon')))); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#getHelpLink')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#getHelpLink')))); assertEquals( scanningApp.i18n('startScanFailedToast'), - scanningApp.$$('#toastText').textContent.trim()); + scanningApp.shadowRoot.querySelector('#toastText') + .textContent.trim()); assertFalse(scanButton.disabled); assertTrue(isVisible(/** @type {!CrButtonElement} */ (scanButton))); @@ -1789,11 +1904,14 @@ // Verify the left and right panel exist on app initialization. test('PanelContainerContent', () => { return initializeScanningApp(expectedScanners, capabilities).then(() => { - const panelContainer = scanningApp.$$('#panelContainer'); + const panelContainer = + scanningApp.shadowRoot.querySelector('#panelContainer'); assertTrue(!!panelContainer); - const leftPanel = scanningApp.$$('#panelContainer > #leftPanel'); - const rightPanel = scanningApp.$$('#panelContainer > #rightPanel'); + const leftPanel = + scanningApp.shadowRoot.querySelector('#panelContainer > #leftPanel'); + const rightPanel = + scanningApp.shadowRoot.querySelector('#panelContainer > #rightPanel'); assertTrue(!!leftPanel); assertTrue(!!rightPanel); @@ -1827,9 +1945,11 @@ return initializeScanningApp(/*scanners=*/[], /*capabilities=*/ new Map()) .then(() => { assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('loading-page')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('loading-page')))); assertFalse(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#panelContainer')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#panelContainer')))); }); }); @@ -1838,20 +1958,26 @@ return initializeScanningApp(/*scanners=*/[], /*capabilities=*/ new Map()) .then(() => { assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('loading-page')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('loading-page')))); assertFalse(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#panelContainer')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#panelContainer')))); fakeScanService_.setScanners(expectedScanners); fakeScanService_.setCapabilities(capabilities); - scanningApp.$$('loading-page').$$('#retryButton').click(); + scanningApp.shadowRoot.querySelector('loading-page') + .shadowRoot.querySelector('#retryButton') + .click(); return fakeScanService_.whenCalled('getScanners'); }) .then(() => { assertFalse(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('loading-page')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('loading-page')))); assertTrue(isVisible( - /** @type {!HTMLElement} */ (scanningApp.$$('#panelContainer')))); + /** @type {!HTMLElement} */ ( + scanningApp.shadowRoot.querySelector('#panelContainer')))); }); }); @@ -1863,7 +1989,7 @@ return getScannerCapabilities(); }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); const numScanSettingChanges = testBrowserProxy.getArgs('recordNumScanSettingChanges')[0]; assertEquals(0, numScanSettingChanges); @@ -1879,16 +2005,19 @@ }) .then(() => { return changeSelect( - scanningApp.$$('#fileTypeSelect').$$('select'), + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select'), FileType.kJpg.toString(), /* selectedIndex */ null); }) .then(() => { return changeSelect( - scanningApp.$$('#resolutionSelect').$$('select'), '75', + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select'), + '75', /* selectedIndex */ null); }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); const numScanSettingChanges = testBrowserProxy.getArgs('recordNumScanSettingChanges')[0]; assertEquals(2, numScanSettingChanges); @@ -1904,26 +2033,32 @@ }) .then(() => { return changeSelect( - scanningApp.$$('#colorModeSelect').$$('select'), + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select'), ColorMode.kBlackAndWhite.toString(), /* selectedIndex */ null); }) .then(() => { return changeSelect( - scanningApp.$$('#scannerSelect').$$('select'), /* value */ null, + scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select'), + /* value */ null, /* selectedIndex */ 1); }) .then(() => { return changeSelect( - scanningApp.$$('#fileTypeSelect').$$('select'), + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select'), FileType.kJpg.toString(), /* selectedIndex */ null); }) .then(() => { return changeSelect( - scanningApp.$$('#resolutionSelect').$$('select'), '150', + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select'), + '150', /* selectedIndex */ null); }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); const numScanSettingChanges = testBrowserProxy.getArgs('recordNumScanSettingChanges')[0]; assertEquals(3, numScanSettingChanges); @@ -1939,23 +2074,39 @@ .then(() => { assertEquals( tokenToString(firstScannerId), - scanningApp.$$('#scannerSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - PLATEN, scanningApp.$$('#sourceSelect').$$('select').value); + PLATEN, + scanningApp.shadowRoot.querySelector('#sourceSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( loadTimeData.getString('myFilesSelectOption'), - scanningApp.$$('#scanToSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scanToSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( FileType.kPdf.toString(), - scanningApp.$$('#fileTypeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( ColorMode.kColor.toString(), - scanningApp.$$('#colorModeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( PageSize.kIsoA4.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - '300', scanningApp.$$('#resolutionSelect').$$('select').value); + '300', + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select') + .value); }); }); @@ -1969,23 +2120,39 @@ .then(() => { assertEquals( tokenToString(secondScannerId), - scanningApp.$$('#scannerSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - ADF_SIMPLEX, scanningApp.$$('#sourceSelect').$$('select').value); + ADF_SIMPLEX, + scanningApp.shadowRoot.querySelector('#sourceSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( loadTimeData.getString('myFilesSelectOption'), - scanningApp.$$('#scanToSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scanToSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( FileType.kPdf.toString(), - scanningApp.$$('#fileTypeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( ColorMode.kBlackAndWhite.toString(), - scanningApp.$$('#colorModeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( PageSize.kIsoA4.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - '600', scanningApp.$$('#resolutionSelect').$$('select').value); + '600', + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select') + .value); }); }); @@ -2015,23 +2182,39 @@ .then(() => { assertEquals( tokenToString(firstScannerId), - scanningApp.$$('#scannerSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - PLATEN, scanningApp.$$('#sourceSelect').$$('select').value); + PLATEN, + scanningApp.shadowRoot.querySelector('#sourceSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( loadTimeData.getString('myFilesSelectOption'), - scanningApp.$$('#scanToSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scanToSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( FileType.kPdf.toString(), - scanningApp.$$('#fileTypeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( ColorMode.kColor.toString(), - scanningApp.$$('#colorModeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( PageSize.kIsoA4.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - '300', scanningApp.$$('#resolutionSelect').$$('select').value); + '300', + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select') + .value); assertFalse(scanningApp.multiPageScanChecked); }); }); @@ -2064,23 +2247,39 @@ .then(() => { assertEquals( tokenToString(firstScannerId), - scanningApp.$$('#scannerSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - PLATEN, scanningApp.$$('#sourceSelect').$$('select').value); + PLATEN, + scanningApp.shadowRoot.querySelector('#sourceSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( selectedPath.baseName, - scanningApp.$$('#scanToSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scanToSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( FileType.kPdf.toString(), - scanningApp.$$('#fileTypeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( ColorMode.kBlackAndWhite.toString(), - scanningApp.$$('#colorModeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( PageSize.kMax.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - '75', scanningApp.$$('#resolutionSelect').$$('select').value); + '75', + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select') + .value); assertTrue(scanningApp.multiPageScanChecked); }); }); @@ -2114,23 +2313,39 @@ .then(() => { assertEquals( tokenToString(firstScannerId), - scanningApp.$$('#scannerSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - PLATEN, scanningApp.$$('#sourceSelect').$$('select').value); + PLATEN, + scanningApp.shadowRoot.querySelector('#sourceSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( loadTimeData.getString('myFilesSelectOption'), - scanningApp.$$('#scanToSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scanToSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( FileType.kPdf.toString(), - scanningApp.$$('#fileTypeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#fileTypeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( ColorMode.kColor.toString(), - scanningApp.$$('#colorModeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#colorModeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( PageSize.kIsoA4.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); assertEquals( - '300', scanningApp.$$('#resolutionSelect').$$('select').value); + '300', + scanningApp.shadowRoot.querySelector('#resolutionSelect') + .shadowRoot.querySelector('select') + .value); assertFalse(scanningApp.multiPageScanChecked); }); }); @@ -2221,7 +2436,9 @@ .then(() => { assertEquals( tokenToString(secondScannerId), - scanningApp.$$('#scannerSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#scannerSelect') + .shadowRoot.querySelector('select') + .value); }); }); @@ -2257,7 +2474,7 @@ scanningApp.selectedResolution = scannerSetting.resolutionDpi.toString(); - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); const actualSavedScanSettings = /** @type {!ScanSettings} */ (JSON.parse(/** @type {string} */ ( @@ -2332,7 +2549,7 @@ scanningApp.selectedResolution = newSecondScannerSetting.resolutionDpi.toString(); - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); const actualSavedScanSettings = /** @type {!ScanSettings} */ (JSON.parse(/** @type {string} */ ( @@ -2381,7 +2598,7 @@ return getScannerCapabilities(); }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); const actualSavedScanSettings = /** @type {!ScanSettings} */ (JSON.parse(/** @type {string} */ ( @@ -2422,7 +2639,7 @@ return getScannerCapabilities(); }) .then(() => { - scanningApp.$$('#scanButton').click(); + scanningApp.shadowRoot.querySelector('#scanButton').click(); const actualSavedScanSettings = /** @type {!ScanSettings} */ (JSON.parse(/** @type {string} */ ( @@ -2448,7 +2665,8 @@ .then(() => { assertFalse(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('multi-page-checkbox').$$('#checkboxDiv')))); + scanningApp.shadowRoot.querySelector('multi-page-checkbox') + .shadowRoot.querySelector('#checkboxDiv')))); scanningApp.selectedSource = PLATEN; scanningApp.selectedFileType = FileType.kPng.toString(); @@ -2457,7 +2675,8 @@ .then(() => { assertFalse(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('multi-page-checkbox').$$('#checkboxDiv')))); + scanningApp.shadowRoot.querySelector('multi-page-checkbox') + .shadowRoot.querySelector('#checkboxDiv')))); scanningApp.selectedSource = ADF_DUPLEX; scanningApp.selectedFileType = FileType.kPdf.toString(); @@ -2466,7 +2685,8 @@ .then(() => { assertFalse(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('multi-page-checkbox').$$('#checkboxDiv')))); + scanningApp.shadowRoot.querySelector('multi-page-checkbox') + .shadowRoot.querySelector('#checkboxDiv')))); scanningApp.selectedSource = PLATEN; scanningApp.selectedFileType = FileType.kPdf.toString(); @@ -2475,7 +2695,8 @@ .then(() => { assertTrue(isVisible( /** @type {!HTMLElement} */ ( - scanningApp.$$('#multiPageCheckbox').$$('#checkboxDiv')))); + scanningApp.shadowRoot.querySelector('#multiPageCheckbox') + .shadowRoot.querySelector('#checkboxDiv')))); }); }); @@ -2496,14 +2717,17 @@ }) .then(() => { assertEquals( - 'Scan page 1', scanningApp.$$('#scanButton').textContent.trim()); + 'Scan page 1', + scanningApp.shadowRoot.querySelector('#scanButton') + .textContent.trim()); // Leave the multi-page checkbox checked but switch the file type. scanningApp.selectedFileType = FileType.kPng.toString(); return flushTasks(); }) .then(() => { - const scanButton = scanningApp.$$('#scanButton'); + const scanButton = + scanningApp.shadowRoot.querySelector('#scanButton'); assertEquals('Scan', scanButton.textContent.trim()); // When scan button is clicked expect a normal scan to start. @@ -2529,14 +2753,17 @@ }) .then(() => { assertEquals( - 'Scan page 1', scanningApp.$$('#scanButton').textContent.trim()); + 'Scan page 1', + scanningApp.shadowRoot.querySelector('#scanButton') + .textContent.trim()); // Leave the multi-page checkbox checked but switch the source. scanningApp.selectedSource = ADF_SIMPLEX; return flushTasks(); }) .then(() => { - const scanButton = scanningApp.$$('#scanButton'); + const scanButton = + scanningApp.shadowRoot.querySelector('#scanButton'); assertEquals('Scan', scanButton.textContent.trim()); // When scan button is clicked expect a normal scan to start. @@ -2558,19 +2785,24 @@ }) .then(() => { const pageSizeSelector = - scanningApp.$$('#pageSizeSelect').$$('select'); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select'); changeSelect( pageSizeSelector, PageSize.kIsoA4.toString(), /* selectedIndex */ null); assertEquals( PageSize.kIsoA4.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); changeSelect( pageSizeSelector, PageSize.kMax.toString(), /* selectedIndex */ null); assertEquals( PageSize.kMax.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); }) .then(() => { scanningApp.selectedSource = ADF_DUPLEX; @@ -2579,25 +2811,32 @@ }) .then(() => { const pageSizeSelector = - scanningApp.$$('#pageSizeSelect').$$('select'); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select'); changeSelect( pageSizeSelector, PageSize.kIsoA4.toString(), /* selectedIndex */ null); assertEquals( PageSize.kIsoA4.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); changeSelect( pageSizeSelector, PageSize.kNaLetter.toString(), /* selectedIndex */ null); assertEquals( PageSize.kNaLetter.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); changeSelect( pageSizeSelector, PageSize.kMax.toString(), /* selectedIndex */ null); assertEquals( PageSize.kMax.toString(), - scanningApp.$$('#pageSizeSelect').$$('select').value); + scanningApp.shadowRoot.querySelector('#pageSizeSelect') + .shadowRoot.querySelector('select') + .value); }); });
diff --git a/chrome/test/data/webui/chromeos/scanning/source_select_test.js b/chrome/test/data/webui/chromeos/scanning/source_select_test.js index 9cbaf1d..3996271 100644 --- a/chrome/test/data/webui/chromeos/scanning/source_select_test.js +++ b/chrome/test/data/webui/chromeos/scanning/source_select_test.js
@@ -37,7 +37,7 @@ // options. test('initializeSourceSelect', () => { // Before options are added, the dropdown should be enabled and empty. - const select = sourceSelect.$$('select'); + const select = sourceSelect.shadowRoot.querySelector('select'); assertTrue(!!select); assertFalse(select.disabled);
diff --git a/chrome/test/data/webui/print_preview/advanced_dialog_test.ts b/chrome/test/data/webui/print_preview/advanced_dialog_test.ts index 53591955..3ccedbf 100644 --- a/chrome/test/data/webui/print_preview/advanced_dialog_test.ts +++ b/chrome/test/data/webui/print_preview/advanced_dialog_test.ts
@@ -11,21 +11,7 @@ import {getCddTemplateWithAdvancedSettings} from './print_preview_test_utils.js'; -const advanced_dialog_test = { - suiteName: 'AdvancedDialogTest', - TestNames: { - AdvancedSettings1Option: 'advanced settings 1 option', - AdvancedSettings2Options: 'advanced settings 2 options', - AdvancedSettingsApply: 'advanced settings apply', - AdvancedSettingsApplyWithEnter: 'advanced settings apply with enter', - AdvancedSettingsClose: 'advanced settings close', - AdvancedSettingsFilter: 'advanced settings filter', - }, -}; - -Object.assign(window, {advanced_dialog_test: advanced_dialog_test}); - -suite(advanced_dialog_test.suiteName, function() { +suite('AdvancedDialogTest', function() { let dialog: PrintPreviewAdvancedSettingsDialogElement; let destination: Destination; const printerId: string = 'FooDevice'; @@ -94,14 +80,14 @@ // Tests that the search box does not appear when there is only one option, // and that the vendor item is correctly displayed. - test(advanced_dialog_test.TestNames.AdvancedSettings1Option, function() { + test('AdvancedSettings1Option', function() { setupDialog(1); verifyListWithItemCount(1); }); // Tests that the search box appears when there are two options, and that // the items are correctly displayed. - test(advanced_dialog_test.TestNames.AdvancedSettings2Options, function() { + test('AdvancedSettings2Options', function() { setupDialog(2); verifyListWithItemCount(2); }); @@ -109,7 +95,7 @@ // Tests that the advanced settings dialog correctly updates the settings // value for vendor items when the apply button is clicked. test( - advanced_dialog_test.TestNames.AdvancedSettingsApply, function() { + 'AdvancedSettingsApply', function() { setupDialog(3); setItemValues(); @@ -133,8 +119,7 @@ // Tests that the advanced settings dialog updates the settings value for // vendor items if Enter is pressed on a cr-input. test( - advanced_dialog_test.TestNames.AdvancedSettingsApplyWithEnter, - function() { + 'AdvancedSettingsApplyWithEnter', function() { setupDialog(3); setItemValues(); @@ -163,7 +148,7 @@ // Tests that the advanced settings dialog does not update the settings // value for vendor items when the close button is clicked. test( - advanced_dialog_test.TestNames.AdvancedSettingsClose, function() { + 'AdvancedSettingsClose', function() { setupDialog(3); setItemValues(); @@ -186,7 +171,7 @@ // Tests that the dialog correctly shows and hides settings based on the // value of the search query. test( - advanced_dialog_test.TestNames.AdvancedSettingsFilter, function() { + 'AdvancedSettingsFilter', function() { setupDialog(3); const searchBox = dialog.$.searchBox; const items = dialog.shadowRoot!.querySelectorAll(
diff --git a/chrome/test/data/webui/print_preview/destination_dialog_cros_test.ts b/chrome/test/data/webui/print_preview/destination_dialog_cros_test.ts index c6fe9ca3..b2e755d1 100644 --- a/chrome/test/data/webui/print_preview/destination_dialog_cros_test.ts +++ b/chrome/test/data/webui/print_preview/destination_dialog_cros_test.ts
@@ -15,30 +15,7 @@ import {NativeLayerStub} from './native_layer_stub.js'; import {createDestinationStore, getDestinations, setupTestListenerElement} from './print_preview_test_utils.js'; -const destination_dialog_cros_test = { - suiteName: 'DestinationDialogCrosTest', - TestNames: { - ShowProvisionalDialog: 'ShowProvisionalDialog', - PrintServersChanged: 'PrintServersChanged', - PrintServerSelected: 'PrintServerSelected', - PrinterSetupAssistanceHasDestinations: - 'PrinterSetupAssistanceHasDestinations', - PrinterSetupAssistanceHasNoDestinations: - 'PrinterSetupAssistanceHasNoDestinations', - ManagePrintersMetrics_HasDestinations: - 'ManagePrintersMetrics_HasDestinations', - ManagePrintersMetrics_HasNoDestinations: - 'ManagePrintersMetrics_HasNoDestinations', - PrinterSetupAssistanceHasDestinations_ShowManagedPrintersFalse: - 'PrinterSetupAssistanceHasDestinations_ShowManagedPrintersFalse', - CorrectlyDisplaysAndHidesLoadingUI: 'DisplayLoadingIcon', - }, -}; - -Object.assign( - window, {destination_dialog_cros_test: destination_dialog_cros_test}); - -suite(destination_dialog_cros_test.suiteName, function() { +suite('DestinationDialogCrosTest', function() { let dialog: PrintPreviewDestinationDialogCrosElement; let destinationStore: DestinationStore; @@ -148,8 +125,7 @@ // destinations dialog, and that the escape key closes only the provisional // dialog when it is open, not the destinations dialog. test( - destination_dialog_cros_test.TestNames.ShowProvisionalDialog, - async () => { + 'ShowProvisionalDialog', async () => { const provisionalDestination = { extensionId: 'ABC123', extensionName: 'ABC Printing', @@ -197,7 +173,7 @@ // Test that checks that print server searchable input and its selections are // updated according to the PRINT_SERVERS_CHANGED event. test( - destination_dialog_cros_test.TestNames.PrintServersChanged, async () => { + 'PrintServersChanged', async () => { await finishSetup(); const printServers = [ @@ -227,7 +203,7 @@ // Tests that choosePrintServers is called when the print server searchable // input value is changed. test( - destination_dialog_cros_test.TestNames.PrintServerSelected, async () => { + 'PrintServerSelected', async () => { await finishSetup(); const printServers = [ {id: 'user-print-server-1', name: 'Print Server 1'}, @@ -258,9 +234,7 @@ // Test that the correct elements are displayed when the printer setup // assistance flag is on and destination store has destinations. test( - destination_dialog_cros_test.TestNames - .PrinterSetupAssistanceHasDestinations, - async () => { + 'PrinterSetupAssistanceHasDestinations', async () => { // Set flag enabled. loadTimeData.overrideValues({ isPrintPreviewSetupAssistanceEnabled: true, @@ -294,9 +268,7 @@ // Test that the correct elements are displayed when the printer setup // assistance flag is on and destination store has no destinations. test( - destination_dialog_cros_test.TestNames - .PrinterSetupAssistanceHasNoDestinations, - async () => { + 'PrinterSetupAssistanceHasNoDestinations', async () => { // Set flag enabled. loadTimeData.overrideValues({ isPrintPreviewSetupAssistanceEnabled: true, @@ -336,9 +308,7 @@ // with bucket `DESTINATION_DIALOG_CROS_HAS_PRINTERS` when flag is on and // destination store has destinations. test( - destination_dialog_cros_test.TestNames - .ManagePrintersMetrics_HasDestinations, - async () => { + 'ManagePrintersMetrics_HasDestinations', async () => { // Set flag enabled. loadTimeData.overrideValues({ isPrintPreviewSetupAssistanceEnabled: true, @@ -361,9 +331,7 @@ // with bucket `DESTINATION_DIALOG_CROS_NO_PRINTERS` when flag is on and // destination store has no destinations. test( - destination_dialog_cros_test.TestNames - .ManagePrintersMetrics_HasNoDestinations, - async () => { + 'ManagePrintersMetrics_HasNoDestinations', async () => { // Set flag enabled. loadTimeData.overrideValues({ isPrintPreviewSetupAssistanceEnabled: true, @@ -391,8 +359,7 @@ // getShowManagePrinters return false. Simulates opening print preview from // a UI which cannot launch settings (ex. OS Settings app). test( - destination_dialog_cros_test.TestNames - .PrinterSetupAssistanceHasDestinations_ShowManagedPrintersFalse, + 'PrinterSetupAssistanceHasDestinations_ShowManagedPrintersFalse', async () => { // Set flag enabled. loadTimeData.overrideValues({ @@ -433,8 +400,7 @@ // Test loading icon rendered while destinations are loading and for a minimum // of 2 seconds before destination list and search box are visible. test( - destination_dialog_cros_test.TestNames.CorrectlyDisplaysAndHidesLoadingUI, - async () => { + 'CorrectlyDisplaysAndHidesLoadingUI', async () => { // Set flag enabled. loadTimeData.overrideValues({ isPrintPreviewSetupAssistanceEnabled: true,
diff --git a/chrome/test/data/webui/print_preview/destination_dialog_test.ts b/chrome/test/data/webui/print_preview/destination_dialog_test.ts index c6d1522..e7c30abe 100644 --- a/chrome/test/data/webui/print_preview/destination_dialog_test.ts +++ b/chrome/test/data/webui/print_preview/destination_dialog_test.ts
@@ -27,17 +27,7 @@ import {NativeLayerStub} from './native_layer_stub.js'; import {createDestinationStore, getDestinations, getExtensionDestinations, setupTestListenerElement} from './print_preview_test_utils.js'; -const destination_dialog_test = { - suiteName: 'DestinationDialogTest', - TestNames: { - PrinterList: 'PrinterList', - PrinterListPreloaded: 'PrinterListPreloaded', - }, -}; - -Object.assign(window, {destination_dialog_test: destination_dialog_test}); - -suite(destination_dialog_test.suiteName, function() { +suite('DestinationDialogTest', function() { // <if expr="is_chromeos"> let dialog: PrintPreviewDestinationDialogCrosElement; // </if> @@ -121,7 +111,7 @@ } // Test that destinations are correctly displayed in the lists. - test(destination_dialog_test.TestNames.PrinterList, async () => { + test('PrinterList', async () => { // Native printers are fetched at startup, since the recent printer is set // as native. let whenPrinterListReady = nativeLayer.waitForGetPrinters(1); @@ -143,7 +133,7 @@ // printers have been preloaded before the dialog is opened. Regression test // for https://crbug.com/1330678. test( - destination_dialog_test.TestNames.PrinterListPreloaded, async () => { + 'PrinterListPreloaded', async () => { // All printers are fetched at startup since both native and extension // printers are recent. const whenAllPreloaded = nativeLayer.waitForGetPrinters(2);
diff --git a/chrome/test/data/webui/print_preview/preview_area_test.ts b/chrome/test/data/webui/print_preview/preview_area_test.ts index f9eeb7d..4b44f22 100644 --- a/chrome/test/data/webui/print_preview/preview_area_test.ts +++ b/chrome/test/data/webui/print_preview/preview_area_test.ts
@@ -21,23 +21,7 @@ import {getCddTemplate} from './print_preview_test_utils.js'; import {TestPluginProxy} from './test_plugin_proxy.js'; -const preview_area_test = { - suiteName: 'PreviewAreaTest', - TestNames: { - StateChanges: 'state changes', - // <if expr="is_chromeos"> - StateChangesPrinterSetupCros: - 'state changes with printer setup flag enabled', - ManagePrinterMetricsCros: - 'manage printer metrics triggered with printer setup flag enabled', - // </if> - ViewportSizeChanges: 'viewport size changes', - }, -}; - -Object.assign(window, {preview_area_test: preview_area_test}); - -suite(preview_area_test.suiteName, function() { +suite('PreviewAreaTest', function() { let previewArea: PrintPreviewPreviewAreaElement; let nativeLayer: NativeLayerStub; @@ -86,7 +70,7 @@ } /** Validate some preview area state transitions work as expected. */ - test(preview_area_test.TestNames.StateChanges, function() { + test('StateChanges', function() { // <if expr="is_chromeos"> // TODO(b/289091283): Update to only run test for "not is_chromeos" as part // of flag clean up. For ChromeOS, the error state change on @@ -143,7 +127,7 @@ * Validate some preview area state transitions work as expected on CrOS with * Printer Setup Assistance flag enabled. */ - test(preview_area_test.TestNames.StateChangesPrinterSetupCros, function() { + test('StateChangesPrinterSetupCros', function() { previewArea.remove(); loadTimeData.overrideValues({ isPrintPreviewSetupAssistanceEnabled: true, @@ -194,7 +178,7 @@ // Verify correct metric is triggered when launch printer settings button // is pressed from preview-area error state. - test(preview_area_test.TestNames.ManagePrinterMetricsCros, function() { + test('ManagePrinterMetricsCros', function() { previewArea.remove(); loadTimeData.overrideValues({ isPrintPreviewSetupAssistanceEnabled: true, @@ -244,7 +228,7 @@ // </if> /** Validate preview area sets tabindex correctly based on viewport size. */ - test(preview_area_test.TestNames.ViewportSizeChanges, function() { + test('ViewportSizeChanges', function() { // Simulate starting the preview. const whenPreviewStarted = nativeLayer.whenCalled('getPreview'); previewArea.state = State.READY;
diff --git a/chrome/test/data/webui/print_preview/print_preview_browsertest.cc b/chrome/test/data/webui/print_preview/print_preview_browsertest.cc index 2818eb3..650261d 100644 --- a/chrome/test/data/webui/print_preview/print_preview_browsertest.cc +++ b/chrome/test/data/webui/print_preview/print_preview_browsertest.cc
@@ -578,3 +578,213 @@ RunTestCase("SaveToDriveDisabled"); } #endif + +#if BUILDFLAG(IS_CHROMEOS) +class PrintPreviewPrinterSetupInfoCrosTest : public PrintPreviewBrowserTest { + protected: + void RunTestCase(const std::string& testCase) { + PrintPreviewBrowserTest::RunTest( + "print_preview/printer_setup_info_cros_test.js", + base::StringPrintf("runMochaTest('PrinterSetupInfoTest', '%s');", + testCase.c_str())); + } +}; + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrinterSetupInfoCrosTest, ElementDisplays) { + RunTestCase("ElementDisplays"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrinterSetupInfoCrosTest, ButtonLocalized) { + RunTestCase("ButtonLocalized"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrinterSetupInfoCrosTest, + ManagePrintersButton) { + RunTestCase("ManagePrintersButton"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrinterSetupInfoCrosTest, + MessageMatchesMessageType) { + RunTestCase("MessageMatchesMessageType"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrinterSetupInfoCrosTest, + ManagePrintersButtonMetrics) { + RunTestCase("ManagePrintersButtonMetrics"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrinterSetupInfoCrosTest, + DoNotShowManagePrinters) { + RunTestCase("DoNotShowManagePrinters"); +} + +class PrintPreviewPrintServerStoreTest : public PrintPreviewBrowserTest { + protected: + void RunTestCase(const std::string& testCase) { + PrintPreviewBrowserTest::RunTest( + "print_preview/print_server_store_test.js", + base::StringPrintf("runMochaTest('PrintServerStoreTest', '%s');", + testCase.c_str())); + } +}; + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrintServerStoreTest, ChoosePrintServers) { + RunTestCase("ChoosePrintServers"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrintServerStoreTest, PrintServersChanged) { + RunTestCase("PrintServersChanged"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrintServerStoreTest, + GetPrintServersConfig) { + RunTestCase("GetPrintServersConfig"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPrintServerStoreTest, + ServerPrintersLoading) { + RunTestCase("ServerPrintersLoading"); +} +#endif // BUILDFLAG(IS_CHROMEOS) + +class PrintPreviewDestinationDialogTest : public PrintPreviewBrowserTest { + protected: + void RunTestCase(const std::string& testCase) { + PrintPreviewBrowserTest::RunTest( + "print_preview/destination_dialog_test.js", + base::StringPrintf("runMochaTest('DestinationDialogTest', '%s');", + testCase.c_str())); + } +}; + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogTest, PrinterList) { + RunTestCase("PrinterList"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogTest, + PrinterListPreloaded) { + RunTestCase("PrinterListPreloaded"); +} + +#if BUILDFLAG(IS_CHROMEOS) +class PrintPreviewDestinationDialogCrosTest : public PrintPreviewBrowserTest { + protected: + void RunTestCase(const std::string& testCase) { + PrintPreviewBrowserTest::RunTest( + "print_preview/destination_dialog_cros_test.js", + base::StringPrintf("runMochaTest('DestinationDialogCrosTest', '%s');", + testCase.c_str())); + } +}; + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + ShowProvisionalDialog) { + RunTestCase("ShowProvisionalDialog"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + PrintServersChanged) { + RunTestCase("PrintServersChanged"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + PrintServerSelected) { + RunTestCase("PrintServerSelected"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + PrinterSetupAssistanceHasDestinations) { + RunTestCase("PrinterSetupAssistanceHasDestinations"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + PrinterSetupAssistanceHasNoDestinations) { + RunTestCase("PrinterSetupAssistanceHasNoDestinations"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + ManagePrintersMetrics_HasDestinations) { + RunTestCase("ManagePrintersMetrics_HasDestinations"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + ManagePrintersMetrics_HasNoDestinations) { + RunTestCase("ManagePrintersMetrics_HasNoDestinations"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + ElementsDisplayedWithShowManagePrintersFalse) { + RunTestCase("PrinterSetupAssistanceHasDestinations_ShowManagedPrintersFalse"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewDestinationDialogCrosTest, + CorrectlyDisplaysAndHidesLoadingUI) { + RunTestCase("CorrectlyDisplaysAndHidesLoadingUI"); +} +#endif // BUILDFLAG(IS_CHROMEOS) + +class PrintPreviewAdvancedDialogTest : public PrintPreviewBrowserTest { + protected: + void RunTestCase(const std::string& testCase) { + PrintPreviewBrowserTest::RunTest( + "print_preview/advanced_dialog_test.js", + base::StringPrintf("runMochaTest('AdvancedDialogTest', '%s');", + testCase.c_str())); + } +}; + +IN_PROC_BROWSER_TEST_F(PrintPreviewAdvancedDialogTest, + AdvancedSettings1Option) { + RunTestCase("AdvancedSettings1Option"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewAdvancedDialogTest, + AdvancedSettings2Options) { + RunTestCase("AdvancedSettings2Options"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewAdvancedDialogTest, AdvancedSettingsApply) { + RunTestCase("AdvancedSettingsApply"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewAdvancedDialogTest, + AdvancedSettingsApplyWithEnter) { + RunTestCase("AdvancedSettingsApplyWithEnter"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewAdvancedDialogTest, AdvancedSettingsClose) { + RunTestCase("AdvancedSettingsClose"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewAdvancedDialogTest, AdvancedSettingsFilter) { + RunTestCase("AdvancedSettingsFilter"); +} + +class PrintPreviewPreviewAreaTest : public PrintPreviewBrowserTest { + protected: + void RunTestCase(const std::string& testCase) { + PrintPreviewBrowserTest::RunTest( + "print_preview/preview_area_test.js", + base::StringPrintf("runMochaTest('PreviewAreaTest', '%s');", + testCase.c_str())); + } +}; + +IN_PROC_BROWSER_TEST_F(PrintPreviewPreviewAreaTest, StateChanges) { + RunTestCase("StateChanges"); +} + +#if BUILDFLAG(IS_CHROMEOS) +IN_PROC_BROWSER_TEST_F(PrintPreviewPreviewAreaTest, + StateChangesPrinterSetupCros) { + RunTestCase("StateChangesPrinterSetupCros"); +} + +IN_PROC_BROWSER_TEST_F(PrintPreviewPreviewAreaTest, ManagePrinterMetricsCros) { + RunTestCase("ManagePrinterMetricsCros"); +} +#endif + +IN_PROC_BROWSER_TEST_F(PrintPreviewPreviewAreaTest, ViewportSizeChanges) { + RunTestCase("ViewportSizeChanges"); +}
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js index 61f5b8a..aa423720 100644 --- a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -34,262 +34,6 @@ } }; -GEN('#if BUILDFLAG(IS_CHROMEOS)'); -var PrintPreviewPrinterSetupInfoCrosTest = class extends PrintPreviewTest { - /** @override */ - get browsePreload() { - return 'chrome://print/test_loader.html?module=print_preview/' + - 'printer_setup_info_cros_test.js'; - } - - /** @override */ - get suiteName() { - return printer_setup_info_cros_test.suiteName; - } -}; - -TEST_F('PrintPreviewPrinterSetupInfoCrosTest', 'ElementDisplays', function() { - this.runMochaTest(printer_setup_info_cros_test.TestNames.ElementDisplays); -}); - -TEST_F('PrintPreviewPrinterSetupInfoCrosTest', 'ButtonLocalized', function() { - this.runMochaTest(printer_setup_info_cros_test.TestNames.ButtonLocalized); -}); - -TEST_F( - 'PrintPreviewPrinterSetupInfoCrosTest', 'ManagePrintersButton', function() { - this.runMochaTest( - printer_setup_info_cros_test.TestNames.ManagePrintersButton); - }); - -TEST_F( - 'PrintPreviewPrinterSetupInfoCrosTest', 'MessageMatchesMessageType', - function() { - this.runMochaTest( - printer_setup_info_cros_test.TestNames.MessageMatchesMessageType); - }); - -TEST_F( - 'PrintPreviewPrinterSetupInfoCrosTest', 'ManagePrintersButtonMetrics', - function() { - this.runMochaTest( - printer_setup_info_cros_test.TestNames.ManagePrintersButtonMetrics); - }); - -TEST_F( - 'PrintPreviewPrinterSetupInfoCrosTest', 'DoNotShowManagePrinters', - function() { - this.runMochaTest( - printer_setup_info_cros_test.TestNames.DoNotShowManagePrinters); - }); - -GEN('#endif') - -GEN('#if BUILDFLAG(IS_CHROMEOS)'); -var PrintPreviewPrintServerStoreTestCros = class extends PrintPreviewTest { - /** @override */ - get browsePreload() { - return 'chrome://print/test_loader.html?module=print_preview/print_server_store_test.js'; - } - - /** @override */ - get suiteName() { - return print_server_store_test.suiteName; - } -}; -TEST_F( - 'PrintPreviewPrintServerStoreTestCros', 'ChoosePrintServers', function() { - this.runMochaTest(print_server_store_test.TestNames.ChoosePrintServers); - }); - -TEST_F( - 'PrintPreviewPrintServerStoreTestCros', 'PrintServersChanged', function() { - this.runMochaTest(print_server_store_test.TestNames.PrintServersChanged); - }); - -TEST_F( - 'PrintPreviewPrintServerStoreTestCros', 'GetPrintServersConfig', - function() { - this.runMochaTest( - print_server_store_test.TestNames.GetPrintServersConfig); - }); - -TEST_F( - 'PrintPreviewPrintServerStoreTestCros', 'ServerPrintersLoading', - function() { - this.runMochaTest( - print_server_store_test.TestNames.ServerPrintersLoading); - }); -GEN('#endif'); - -var PrintPreviewDestinationDialogTest = class extends PrintPreviewTest { - /** @override */ - get browsePreload() { - return 'chrome://print/test_loader.html?module=print_preview/destination_dialog_test.js'; - } - - /** @override */ - get suiteName() { - return destination_dialog_test.suiteName; - } -}; - -TEST_F('PrintPreviewDestinationDialogTest', 'PrinterList', function() { - this.runMochaTest(destination_dialog_test.TestNames.PrinterList); -}); - -TEST_F('PrintPreviewDestinationDialogTest', 'PrinterListPreloaded', function() { - this.runMochaTest(destination_dialog_test.TestNames.PrinterListPreloaded); -}); - -GEN('#if BUILDFLAG(IS_CHROMEOS)'); -var PrintPreviewDestinationDialogCrosTest = class extends PrintPreviewTest { - /** @override */ - get browsePreload() { - return 'chrome://print/test_loader.html?module=print_preview/destination_dialog_cros_test.js'; - } - - /** @override */ - get suiteName() { - return destination_dialog_cros_test.suiteName; - } -}; - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', 'ShowProvisionalDialog', - function() { - this.runMochaTest( - destination_dialog_cros_test.TestNames.ShowProvisionalDialog); - }); - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', 'PrintServersChanged', function() { - this.runMochaTest( - destination_dialog_cros_test.TestNames.PrintServersChanged); - }); - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', 'PrintServerSelected', function() { - this.runMochaTest( - destination_dialog_cros_test.TestNames.PrintServerSelected); - }); - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', - 'PrinterSetupAssistanceHasDestinations', function() { - this.runMochaTest(destination_dialog_cros_test.TestNames - .PrinterSetupAssistanceHasDestinations); - }); - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', - 'PrinterSetupAssistanceHasNoDestinations', function() { - this.runMochaTest(destination_dialog_cros_test.TestNames - .PrinterSetupAssistanceHasNoDestinations); - }); - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', - 'ManagePrintersMetrics_HasDestinations', function() { - this.runMochaTest(destination_dialog_cros_test.TestNames - .ManagePrintersMetrics_HasDestinations); - }); - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', - 'ManagePrintersMetrics_HasNoDestinations', function() { - this.runMochaTest(destination_dialog_cros_test.TestNames - .ManagePrintersMetrics_HasNoDestinations); - }); - -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', - 'ElementsDisplayedWithShowManagePrintersFalse', function() { - this.runMochaTest( - destination_dialog_cros_test.TestNames - .PrinterSetupAssistanceHasDestinations_ShowManagedPrintersFalse); - }); -TEST_F( - 'PrintPreviewDestinationDialogCrosTest', - 'CorrectlyDisplaysAndHidesLoadingUI', function() { - this.runMochaTest(destination_dialog_cros_test.TestNames - .CorrectlyDisplaysAndHidesLoadingUI) - }); -GEN('#endif'); - -var PrintPreviewAdvancedDialogTest = class extends PrintPreviewTest { - /** @override */ - get browsePreload() { - return 'chrome://print/test_loader.html?module=print_preview/advanced_dialog_test.js'; - } - - /** @override */ - get suiteName() { - return advanced_dialog_test.suiteName; - } -}; - -TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettings1Option', function() { - this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettings1Option); -}); - -TEST_F( - 'PrintPreviewAdvancedDialogTest', 'AdvancedSettings2Options', function() { - this.runMochaTest( - advanced_dialog_test.TestNames.AdvancedSettings2Options); - }); - -TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettingsApply', function() { - this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettingsApply); -}); - -TEST_F( - 'PrintPreviewAdvancedDialogTest', 'AdvancedSettingsApplyWithEnter', - function() { - this.runMochaTest( - advanced_dialog_test.TestNames.AdvancedSettingsApplyWithEnter); - }); - -TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettingsClose', function() { - this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettingsClose); -}); - -TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettingsFilter', function() { - this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettingsFilter); -}); - -var PrintPreviewPreviewAreaTest = class extends PrintPreviewTest { - /** @override */ - get browsePreload() { - return 'chrome://print/test_loader.html?module=print_preview/preview_area_test.js'; - } - - /** @override */ - get suiteName() { - return preview_area_test.suiteName; - } -}; - -TEST_F('PrintPreviewPreviewAreaTest', 'StateChanges', function() { - this.runMochaTest(preview_area_test.TestNames.StateChanges); -}); - -GEN('#if BUILDFLAG(IS_CHROMEOS)'); -TEST_F( - 'PrintPreviewPreviewAreaTest', 'StateChangesPrinterSetupCros', function() { - this.runMochaTest( - preview_area_test.TestNames.StateChangesPrinterSetupCros); - }); - -TEST_F('PrintPreviewPreviewAreaTest', 'ManagePrinterMetricsCros', function() { - this.runMochaTest(preview_area_test.TestNames.ManagePrinterMetricsCros); -}); -GEN('#endif'); - -TEST_F('PrintPreviewPreviewAreaTest', 'ViewportSizeChanges', function() { - this.runMochaTest(preview_area_test.TestNames.ViewportSizeChanges); -}); - var PrintPreviewCustomMarginsTest = class extends PrintPreviewTest { /** @override */ get browsePreload() {
diff --git a/chrome/test/data/webui/print_preview/print_server_store_test.ts b/chrome/test/data/webui/print_preview/print_server_store_test.ts index 8cbe0ae..dc26f135 100644 --- a/chrome/test/data/webui/print_preview/print_server_store_test.ts +++ b/chrome/test/data/webui/print_preview/print_server_store_test.ts
@@ -9,19 +9,7 @@ import {NativeLayerCrosStub, setNativeLayerCrosInstance} from './native_layer_cros_stub.js'; -const print_server_store_test = { - suiteName: 'PrintServerStoreTest', - TestNames: { - PrintServersChanged: 'print servers changed', - GetPrintServersConfig: 'get print servers config', - ServerPrintersLoading: 'server printers loading', - ChoosePrintServers: 'choose print servers', - }, -}; - -Object.assign(window, {print_server_store_test: print_server_store_test}); - -suite(print_server_store_test.suiteName, function() { +suite('PrintServerStoreTest', function() { let printServerStore: PrintServerStore; let nativeLayerCros: NativeLayerCrosStub; @@ -45,7 +33,7 @@ // Tests that print servers with the selected name are selected by ID is the // native layer choosePrintServers is called. test( - print_server_store_test.TestNames.ChoosePrintServers, async () => { + 'ChoosePrintServers', async () => { const printServers = [ {id: 'user-server1', name: 'Print Server 1'}, {id: 'device-server2', name: 'Print Server 2'}, @@ -70,7 +58,7 @@ // Tests that print servers and fetching mode are updated when // PRINT_SERVERS_CHANGED occurs. test( - print_server_store_test.TestNames.PrintServersChanged, async () => { + 'PrintServersChanged', async () => { const printServers = [ {id: 'server1', name: 'Print Server 1'}, {id: 'server2', name: 'Print Server 2'}, @@ -96,7 +84,7 @@ // getPrintServersConfig is called and an update to the print servers config // occurs. test( - print_server_store_test.TestNames.GetPrintServersConfig, async () => { + 'GetPrintServersConfig', async () => { const printServers = [ {id: 'server1', name: 'Print Server 1'}, {id: 'server2', name: 'Print Server 2'}, @@ -120,7 +108,7 @@ // Tests that an event is dispatched are updated when SERVER_PRINTERS_LOADING // is called. - test(print_server_store_test.TestNames.ServerPrintersLoading, async () => { + test('ServerPrintersLoading', async () => { const whenServerPrintersLoadedEvent = eventToPromise( PrintServerStoreEventType.SERVER_PRINTERS_LOADING, printServerStore);
diff --git a/chrome/test/data/webui/print_preview/printer_setup_info_cros_test.ts b/chrome/test/data/webui/print_preview/printer_setup_info_cros_test.ts index 132f2e6..9cf88b8 100644 --- a/chrome/test/data/webui/print_preview/printer_setup_info_cros_test.ts +++ b/chrome/test/data/webui/print_preview/printer_setup_info_cros_test.ts
@@ -11,23 +11,7 @@ import {NativeLayerCrosStub, setNativeLayerCrosInstance} from './native_layer_cros_stub.js'; import {NativeLayerStub} from './native_layer_stub.js'; -const printer_setup_info_cros_test = { - suiteName: 'PrinterSetupInfoCrosTest', - TestNames: { - ElementDisplays: 'Element displays', - ButtonLocalized: 'Button text is localized', - ManagePrintersButton: 'Manage printers button launches settings', - MessageMatchesMessageType: 'Message matches message type', - ManagePrintersButtonMetrics: 'Manage printers button records metrics', - DoNotShowManagePrinters: - 'Manage printers button hidden when getShowManagePrinters is false', - }, -}; - -Object.assign( - window, {printer_setup_info_cros_test: printer_setup_info_cros_test}); - -suite(printer_setup_info_cros_test.suiteName, function() { +suite('PrinterSetupInfoTest', function() { let setupInfoElement: PrintPreviewPrinterSetupInfoCrosElement; let nativeLayer: NativeLayerStub; let nativeLayerCros: NativeLayerCrosStub; @@ -78,19 +62,18 @@ } /** Verifies element can be added to UI and display. */ - test( - printer_setup_info_cros_test.TestNames.ElementDisplays, async function() { - await setupElement(); + test('ElementDisplays', async function() { + await setupElement(); - assertTrue(!!setupInfoElement); - assertTrue(isChildVisible(setupInfoElement, 'cr-button')); - assertTrue(isChildVisible(setupInfoElement, '.message-heading')); - assertTrue(isChildVisible(setupInfoElement, '.message-detail')); - }); + assertTrue(!!setupInfoElement); + assertTrue(isChildVisible(setupInfoElement, 'cr-button')); + assertTrue(isChildVisible(setupInfoElement, '.message-heading')); + assertTrue(isChildVisible(setupInfoElement, '.message-detail')); + }); /** Verifies button text is localized. */ test( - printer_setup_info_cros_test.TestNames.ButtonLocalized, async function() { + 'ButtonLocalized', async function() { await setupElement(); const managePrintersLabelKey = 'managePrintersLabel'; @@ -105,24 +88,21 @@ /** * Verifies manage printers button invokes launch settings from native layer. */ - test( - printer_setup_info_cros_test.TestNames.ManagePrintersButton, - async function() { - await setupElement(); - assertEquals(0, nativeLayer.getCallCount('managePrinters')); + test('ManagePrintersButton', async function() { + await setupElement(); + assertEquals(0, nativeLayer.getCallCount('managePrinters')); - // Click button. - const managePrinters = - getShadowElement<CrButtonElement>(setupInfoElement, 'cr-button'); - managePrinters.click(); + // Click button. + const managePrinters = + getShadowElement<CrButtonElement>(setupInfoElement, 'cr-button'); + managePrinters.click(); - assertEquals(1, nativeLayer.getCallCount('managePrinters')); - }); + assertEquals(1, nativeLayer.getCallCount('managePrinters')); + }); /** Verify correct localized message displayed for message type. */ test( - printer_setup_info_cros_test.TestNames.MessageMatchesMessageType, - async function() { + 'MessageMatchesMessageType', async function() { await setupElement(); // Default message type configured to be "no-printers". @@ -184,8 +164,7 @@ * Verifies manage printers button invokes launch settings metric. */ test( - printer_setup_info_cros_test.TestNames.ManagePrintersButtonMetrics, - async function() { + 'ManagePrintersButtonMetrics', async function() { await setupElement(); const recordMetricsFunction = 'recordInHistogram'; assertEquals(0, nativeLayer.getCallCount(recordMetricsFunction)); @@ -213,15 +192,13 @@ * Verifies manage printers button hidden when getShowManagePrinters returns * false. */ - test( - printer_setup_info_cros_test.TestNames.DoNotShowManagePrinters, - async function() { - nativeLayerCros.setShowManagePrinters(false); - await setupElement(); + test('DoNotShowManagePrinters', async function() { + nativeLayerCros.setShowManagePrinters(false); + await setupElement(); - assertTrue(!!setupInfoElement); - assertTrue(isChildVisible(setupInfoElement, '.message-heading')); - assertTrue(isChildVisible(setupInfoElement, '.message-detail')); - assertFalse(isChildVisible(setupInfoElement, 'cr-button')); - }); + assertTrue(!!setupInfoElement); + assertTrue(isChildVisible(setupInfoElement, '.message-heading')); + assertTrue(isChildVisible(setupInfoElement, '.message-detail')); + assertFalse(isChildVisible(setupInfoElement, 'cr-button')); + }); });
diff --git a/chrome/test/data/webui/side_panel/read_anything/highlight_callback_toggles_highlight.js b/chrome/test/data/webui/side_panel/read_anything/highlight_callback_toggles_highlight.js index f2e388f..20ac9cf 100644 --- a/chrome/test/data/webui/side_panel/read_anything/highlight_callback_toggles_highlight.js +++ b/chrome/test/data/webui/side_panel/read_anything/highlight_callback_toggles_highlight.js
@@ -9,10 +9,36 @@ (() => { chrome.readingMode.onConnected = () => {}; const readAnythingApp = document.querySelector('read-anything-app'); + const container = readAnythingApp.shadowRoot.getElementById('container'); const toolbar = readAnythingApp.shadowRoot.querySelector('read-anything-toolbar') .shadowRoot; const highlightButton = toolbar.getElementById('highlight'); + const sentence1 = 'Big wheel keep on turning.'; + const sentence2 = 'Proud Mary keep on burning.'; + const axTree = { + rootId: 1, + nodes: [ + { + id: 1, + role: 'rootWebArea', + htmlTag: '#document', + childIds: [2, 3], + }, + { + id: 2, + role: 'staticText', + name: sentence1, + }, + { + id: 3, + role: 'staticText', + name: sentence2, + }, + ], + }; + chrome.readingMode.setContentForTesting(axTree, [2, 3]); + let result = true; const assertEquals = (actual, expected) => { const isEqual = actual === expected; @@ -24,15 +50,50 @@ result = result && isEqual; return isEqual; }; + const assertNE = (actual, expected) => { + const isNotEqual = actual !== expected; + if (!isNotEqual) { + console.error( + 'Expected ' + JSON.stringify(actual) + ' to be not equal to ' + + JSON.stringify(expected)); + } + result = result && isNotEqual; + return isNotEqual; + }; - // TODO(b/1474951): Test that the actual functionality is toggled too + // Default on assertEquals( highlightButton.getAttribute('iron-icon'), 'read-anything:highlight-on'); + + // Speech doesn't actually run in tests, so manually call start + readAnythingApp.playSpeech(); + const utterances = readAnythingApp.getUtterancesToSpeak(); + assertEquals(utterances.length, 2); + let utterance = utterances[0]; + utterance.onstart(); + utterance.onend(); + utterance = utterances[1]; + utterance.onstart(); + + // Color should start visible, and the previous highlight should be there + const highlights = container.querySelectorAll('.current-read-highlight'); + assertEquals(highlights.length, 1); + assertEquals( + container.querySelectorAll('.previous-read-highlight').length, 1); + let highlightColor = window.getComputedStyle(highlights[0]) + .getPropertyValue('--current-highlight-bg-color'); + assertNE(highlightColor, 'transparent'); + + // After turning off the highlight, it should be transparent, and the + // previous highlight should still be there highlightButton.click(); assertEquals( highlightButton.getAttribute('iron-icon'), 'read-anything:highlight-off'); - highlightButton.click(); assertEquals( - highlightButton.getAttribute('iron-icon'), 'read-anything:highlight-on'); + container.querySelectorAll('.previous-read-highlight').length, 1); + highlightColor = window.getComputedStyle(highlights[0]) + .getPropertyValue('--current-highlight-bg-color'); + assertEquals(highlightColor, 'transparent'); + return result; })();
diff --git a/chrome/test/media_router/README.md b/chrome/test/media_router/README.md index cc6112e..43e73b5 100644 --- a/chrome/test/media_router/README.md +++ b/chrome/test/media_router/README.md
@@ -18,10 +18,6 @@ test the functionalities of the Media Router dialog are in `media_router_integration_ui_browsertest.cc`. -* `MediaRouterIntegrationIncognitoBrowserTest`: Same as -`MediaRouterIntegrationBrowserTest`, except for that the tests are run using an -incognito profile. - * `MediaRouterE2EBrowserTest`: Tests Chromecast-specific functionality of Media Router using the Cast Media Route Provider. Requires an actual Chromecast device.
diff --git a/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc b/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc index dc1ef6af..5bfeaae 100644 --- a/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc +++ b/chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.cc
@@ -165,12 +165,12 @@ // Handler so MockMediaRouter will respond to requests to create a route. // Will construct a RouteRequestResult based on the set result code and // then call the handler's callback, which should call the page's callback. - ON_CALL(*media_router_, CreateRouteInternal(_, _, _, _, _, _, _)) + ON_CALL(*media_router_, CreateRouteInternal(_, _, _, _, _, _)) .WillByDefault( [this](const MediaSource::Id& source_id, const MediaSink::Id& sink_id, const url::Origin& origin, content::WebContents* web_contents, - MediaRouteResponseCallback& callback, base::TimeDelta timeout, - bool incognito) { + MediaRouteResponseCallback& callback, + base::TimeDelta timeout) { std::unique_ptr<RouteRequestResult> result; if (result_code_ == mojom::RouteRequestResultCode::OK) { MediaSource source(source_id); @@ -610,9 +610,8 @@ media_router::MediaRouterFactory::GetInstance() ->GetApiForBrowserContext(browser()->profile())); } - EXPECT_CALL(*media_router, - CreateRouteInternal(media_source_id, sink_name, _, web_contents, - _, timeout, false)); + EXPECT_CALL(*media_router, CreateRouteInternal(media_source_id, sink_name, _, + web_contents, _, timeout)); } AccessCodeCastPrefUpdater*
diff --git a/chrome/test/media_router/media_router_e2e_browsertest.cc b/chrome/test/media_router/media_router_e2e_browsertest.cc index fc9b9f1..df63235 100644 --- a/chrome/test/media_router/media_router_e2e_browsertest.cc +++ b/chrome/test/media_router/media_router_e2e_browsertest.cc
@@ -94,7 +94,7 @@ source.id(), sink.id(), origin, web_contents, base::BindOnce(&MediaRouterE2EBrowserTest::OnRouteResponseReceived, base::Unretained(this)), - base::TimeDelta(), is_incognito()); + base::TimeDelta()); // Wait for the route request to be fulfilled (and route to be started). ASSERT_TRUE(ConditionalWait(
diff --git a/chrome/test/media_router/media_router_integration_browsertest.cc b/chrome/test/media_router/media_router_integration_browsertest.cc index 175e564..9351185 100644 --- a/chrome/test/media_router/media_router_integration_browsertest.cc +++ b/chrome/test/media_router/media_router_integration_browsertest.cc
@@ -521,32 +521,7 @@ StartSessionAndAssertNotFoundError(); } -Browser* MediaRouterIntegrationIncognitoBrowserTest::browser() { - if (!incognito_browser_) - incognito_browser_ = CreateIncognitoBrowser(); - return incognito_browser_; -} - -IN_PROC_BROWSER_TEST_P(MediaRouterIntegrationIncognitoBrowserTest, Basic) { - RunBasicTest(); - // If we tear down before route observers are notified of route termination, - // MediaRouter will create another TerminateRoute() request which will have a - // dangling Mojo callback at shutdown. So we must wait for the update. - WaitUntilNoRoutes(GetActiveWebContents()); -} - -IN_PROC_BROWSER_TEST_P(MediaRouterIntegrationIncognitoBrowserTest, - ReconnectSession) { - RunReconnectSessionTest(); - // If we tear down before route observers are notified of route termination, - // MediaRouter will create another TerminateRoute() request which will have a - // dangling Mojo callback at shutdown. So we must wait for the update. - WaitUntilNoRoutes(GetActiveWebContents()); -} - INSTANTIATE_MEDIA_ROUTER_INTEGRATION_BROWER_TEST_SUITE( MediaRouterIntegrationBrowserTest); -INSTANTIATE_MEDIA_ROUTER_INTEGRATION_BROWER_TEST_SUITE( - MediaRouterIntegrationIncognitoBrowserTest); } // namespace media_router
diff --git a/chrome/test/media_router/media_router_integration_browsertest.h b/chrome/test/media_router/media_router_integration_browsertest.h index f3266f7..b86dd8a 100644 --- a/chrome/test/media_router/media_router_integration_browsertest.h +++ b/chrome/test/media_router/media_router_integration_browsertest.h
@@ -193,8 +193,6 @@ std::unique_ptr<TestMediaRouteProvider> test_provider_; - bool is_incognito() { return browser()->profile()->IsOffTheRecord(); } - // Returns the superclass' browser(). Marked virtual so that it can // be overridden by MediaRouterIntegrationIncognitoBrowserTest. virtual Browser* browser(); @@ -205,15 +203,6 @@ base::test::ScopedFeatureList feature_list_; }; -class MediaRouterIntegrationIncognitoBrowserTest - : public MediaRouterIntegrationBrowserTest { - protected: - Browser* browser() override; - - private: - raw_ptr<Browser, AcrossTasksDanglingUntriaged> incognito_browser_ = nullptr; -}; - } // namespace media_router #endif // CHROME_TEST_MEDIA_ROUTER_MEDIA_ROUTER_INTEGRATION_BROWSERTEST_H_
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc index b3e70b8..3524860 100644 --- a/chrome/updater/app/app_install.cc +++ b/chrome/updater/app/app_install.cc
@@ -49,25 +49,46 @@ class AppInstallControllerImpl : public AppInstallController { public: - explicit AppInstallControllerImpl( - scoped_refptr<UpdateService> /*update_service*/) {} + explicit AppInstallControllerImpl(scoped_refptr<UpdateService> update_service) + : update_service_(update_service) {} // Override for AppInstallController. - void InstallApp(const std::string& /*app_id*/, + void InstallApp(const std::string& app_id, const std::string& /*app_name*/, base::OnceCallback<void(int)> callback) override { - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), 0)); + // TODO(crbug.com/1484292): Factor out common code from app_install_win.cc. + RegistrationRequest request; + request.app_id = app_id; + request.version = base::Version(kNullVersion); + absl::optional<tagging::AppArgs> app_args = GetAppArgs(app_id); + absl::optional<tagging::TagArgs> tag_args = GetTagArgs().tag_args; + if (app_args) { + request.ap = app_args->ap; + } + if (tag_args) { + request.brand_code = tag_args->brand_code; + } + update_service_->Install(request, GetDecodedInstallDataFromAppArgs(app_id), + GetInstallDataIndexFromAppArgs(app_id), + UpdateService::Priority::kForeground, + base::DoNothing(), + base::BindOnce([](UpdateService::Result result) { + return static_cast<int>(result); + }).Then(std::move(callback))); } void InstallAppOffline(const std::string& app_id, - const std::string& app_name, + const std::string& /*app_name*/, base::OnceCallback<void(int)> callback) override { + // TODO(crbug.com/1484292): Implement this. base::SequencedTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), 0)); } protected: ~AppInstallControllerImpl() override = default; + + private: + scoped_refptr<UpdateService> update_service_; }; } // namespace
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 22b0d7e4..8f98ffc 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -45,6 +45,7 @@ virtual void InstallUpdaterAndApp( const std::string& app_id, const bool is_silent_install, + const std::string& tag, const std::string& child_window_text_to_find) const = 0; virtual void SetActive(const std::string& app_id) const = 0; virtual void ExpectActive(const std::string& app_id) const = 0; @@ -94,6 +95,8 @@ virtual void ExpectLogRotated() const = 0; virtual void ExpectRegistered(const std::string& app_id) const = 0; virtual void ExpectNotRegistered(const std::string& app_id) const = 0; + virtual void ExpectAppTag(const std::string& app_id, + const std::string& tag) const = 0; virtual void ExpectAppVersion(const std::string& app_id, const base::Version& version) const = 0; virtual void RunWake(int exit_code) const = 0;
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index b454f728..db48790 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -81,10 +81,12 @@ void InstallUpdaterAndApp( const std::string& app_id, const bool is_silent_install, + const std::string& tag, const std::string& child_window_text_to_find) const override { RunCommand("install_updater_and_app", {Param("app_id", app_id), Param("is_silent_install", BoolToString(is_silent_install)), + Param("tag", tag), Param("child_window_text_to_find", child_window_text_to_find)}); } @@ -233,6 +235,11 @@ RunCommand("expect_not_registered", {Param("app_id", app_id)}); } + void ExpectAppTag(const std::string& app_id, + const std::string& tag) const override { + RunCommand("expect_app_tag", {Param("app_id", app_id), Param("tag", tag)}); + } + void ExpectAppVersion(const std::string& app_id, const base::Version& version) const override { RunCommand("expect_app_version", {Param("app_id", app_id),
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index d001d71..70034c17 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -54,9 +54,11 @@ void InstallUpdaterAndApp( const std::string& app_id, const bool is_silent_install, + const std::string& tag, const std::string& child_window_text_to_find) const override { - updater::test::InstallUpdaterAndApp( - updater_scope_, app_id, is_silent_install, child_window_text_to_find); + updater::test::InstallUpdaterAndApp(updater_scope_, app_id, + is_silent_install, tag, + child_window_text_to_find); } void ExpectInstalled() const override { @@ -193,6 +195,11 @@ updater::test::ExpectNotRegistered(updater_scope_, app_id); } + void ExpectAppTag(const std::string& app_id, + const std::string& tag) const override { + updater::test::ExpectAppTag(updater_scope_, app_id, tag); + } + void ExpectAppVersion(const std::string& app_id, const base::Version& version) const override { updater::test::ExpectAppVersion(updater_scope_, app_id, version);
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index 5fc067c..44eeec3 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -179,8 +179,9 @@ void InstallUpdaterAndApp(const std::string& app_id, const bool is_silent_install, + const std::string& tag, const std::string& child_window_text_to_find = {}) { - test_commands_->InstallUpdaterAndApp(app_id, is_silent_install, + test_commands_->InstallUpdaterAndApp(app_id, is_silent_install, tag, child_window_text_to_find); } @@ -325,6 +326,10 @@ test_commands_->ExpectNotRegistered(app_id); } + void ExpectAppTag(const std::string& app_id, const std::string& tag) { + test_commands_->ExpectAppTag(app_id, tag); + } + void ExpectAppVersion(const std::string& app_id, const base::Version& version) { test_commands_->ExpectAppVersion(app_id, version); @@ -881,7 +886,6 @@ ASSERT_NO_FATAL_FAILURE(Uninstall()); } -#if BUILDFLAG(IS_WIN) TEST_F(IntegrationTest, InstallUpdaterAndApp) { ScopedServer test_server(test_commands_); const std::string kAppId("test"); @@ -891,7 +895,7 @@ base::Version({0, 0, 0, 0}), v1)); ASSERT_NO_FATAL_FAILURE( - InstallUpdaterAndApp(kAppId, /*is_silent_install=*/true)); + InstallUpdaterAndApp(kAppId, /*is_silent_install=*/true, "usagestats=1")); ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId, v1)); @@ -900,6 +904,64 @@ ASSERT_NO_FATAL_FAILURE(Uninstall()); } +TEST_F(IntegrationTest, InstallUpdaterAndTwoApps) { + ScopedServer test_server(test_commands_); + const std::string kAppId("test"); + const std::string kAppId2("test2"); + const base::Version v1("1"); + ASSERT_NO_FATAL_FAILURE(ExpectInstallSequence( + &test_server, kAppId, "", UpdateService::Priority::kForeground, + base::Version({0, 0, 0, 0}), v1)); + ASSERT_NO_FATAL_FAILURE(InstallUpdaterAndApp( + kAppId, /*is_silent_install=*/true, + base::StrCat({"appguid=", kAppId, "&ap=foo&usagestats=1"}))); + ASSERT_NO_FATAL_FAILURE(ExpectInstallSequence( + &test_server, kAppId2, "", UpdateService::Priority::kForeground, + base::Version({0, 0, 0, 0}), v1)); + ASSERT_NO_FATAL_FAILURE(InstallUpdaterAndApp( + kAppId2, /*is_silent_install=*/true, + base::StrCat({"appguid=", kAppId2, "&ap=foo2&usagestats=1"}))); + ASSERT_TRUE(WaitForUpdaterExit()); + + ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId, v1)); + ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId2, v1)); + ASSERT_NO_FATAL_FAILURE(ExpectAppTag(kAppId, "foo")); + ASSERT_NO_FATAL_FAILURE(ExpectAppTag(kAppId2, "foo2")); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); + ASSERT_NO_FATAL_FAILURE(Uninstall()); +} + +TEST_F(IntegrationTest, ChangeTag) { + ScopedServer test_server(test_commands_); + const std::string kAppId("test"); + const base::Version v1("1"); + ASSERT_NO_FATAL_FAILURE(ExpectInstallSequence( + &test_server, kAppId, "", UpdateService::Priority::kForeground, + base::Version({0, 0, 0, 0}), v1)); + ASSERT_NO_FATAL_FAILURE(InstallUpdaterAndApp( + kAppId, /*is_silent_install=*/true, + base::StrCat({"appguid=", kAppId, "&ap=foo&usagestats=1"}))); + ASSERT_NO_FATAL_FAILURE(ExpectInstallSequence( + &test_server, kAppId, "", UpdateService::Priority::kForeground, + base::Version({1}), v1)); + ASSERT_NO_FATAL_FAILURE(InstallUpdaterAndApp( + kAppId, /*is_silent_install=*/true, + base::StrCat({"appguid=", kAppId, "&ap=foo2&usagestats=1"}))); + ASSERT_TRUE(WaitForUpdaterExit()); + + ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId, v1)); + + // TODO(crbug.com/1471724): An overinstall with a new AP should change the AP. + // Once this is fixed, the below assertion should be: + // ASSERT_NO_FATAL_FAILURE(ExpectAppTag(kAppId, "foo2")); + ASSERT_NO_FATAL_FAILURE(ExpectAppTag(kAppId, "foo")); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); + ASSERT_NO_FATAL_FAILURE(Uninstall()); +} + +#if BUILDFLAG(IS_WIN) TEST_F(IntegrationTest, Handoff) { ScopedServer test_server(test_commands_); ASSERT_NO_FATAL_FAILURE(Install()); @@ -2060,8 +2122,8 @@ /*should_update=*/true, false, "", crx_path), }); - ASSERT_NO_FATAL_FAILURE( - InstallUpdaterAndApp(kMsiAppId, /*is_silent_install=*/true)); + ASSERT_NO_FATAL_FAILURE(InstallUpdaterAndApp( + kMsiAppId, /*is_silent_install=*/true, "usagestats=1")); ASSERT_TRUE(WaitForUpdaterExit()); ExpectAppInstalled(kMsiAppId, kMsiUpdatedVersion); @@ -2191,8 +2253,9 @@ ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get())); if (GetParam().interactive_install) { - ASSERT_NO_FATAL_FAILURE(InstallUpdaterAndApp( - kMsiAppId, /*is_silent_install=*/false, GetParam().installer_text)); + ASSERT_NO_FATAL_FAILURE( + InstallUpdaterAndApp(kMsiAppId, /*is_silent_install=*/false, + "usagestats=1", GetParam().installer_text)); ASSERT_TRUE(WaitForUpdaterExit()); } else { int64_t crx_file_size = 0;
diff --git a/chrome/updater/test/integration_tests_helper.cc b/chrome/updater/test/integration_tests_helper.cc index a9856692..e7a64b0 100644 --- a/chrome/updater/test/integration_tests_helper.cc +++ b/chrome/updater/test/integration_tests_helper.cc
@@ -286,6 +286,9 @@ WithSwitch("app_id", WithSystemScope(Wrap(&ExpectRegistered)))}, {"expect_not_registered", WithSwitch("app_id", WithSystemScope(Wrap(&ExpectNotRegistered)))}, + {"expect_app_tag", + WithSwitch("tag", + WithSwitch("app_id", WithSystemScope(Wrap(&ExpectAppTag))))}, {"expect_app_version", WithSwitch("version", WithSwitch("app_id", WithSystemScope( Wrap(&ExpectAppVersion))))}, @@ -330,10 +333,13 @@ WithSwitch("version", WithSystemScope(Wrap(&ExpectVersionNotActive)))}, {"install", WithSystemScope(Wrap(&Install))}, {"install_updater_and_app", - WithSwitch("child_window_text_to_find", - WithSwitch("is_silent_install", - WithSwitch("app_id", WithSystemScope(Wrap( - &InstallUpdaterAndApp)))))}, + WithSwitch( + "child_window_text_to_find", + WithSwitch( + "tag", + WithSwitch("is_silent_install", + WithSwitch("app_id", WithSystemScope(Wrap( + &InstallUpdaterAndApp))))))}, {"print_log", WithSystemScope(Wrap(&PrintLog))}, {"run_wake", WithSwitch("exit_code", WithSystemScope(Wrap(&RunWake)))}, {"run_wake_all", WithSystemScope(Wrap(&RunWakeAll))},
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc index 50585f36..4ef98a4 100644 --- a/chrome/updater/test/integration_tests_impl.cc +++ b/chrome/updater/test/integration_tests_impl.cc
@@ -416,12 +416,13 @@ void InstallUpdaterAndApp(UpdaterScope scope, const std::string& app_id, const bool is_silent_install, + const std::string& tag, const std::string& child_window_text_to_find) { const base::FilePath path = GetSetupExecutablePath(); ASSERT_FALSE(path.empty()); base::CommandLine command_line(path); command_line.AppendSwitch(kInstallSwitch); - command_line.AppendSwitchASCII(kTagSwitch, "usagestats=1"); + command_line.AppendSwitchASCII(kTagSwitch, tag); command_line.AppendSwitchASCII(kAppIdSwitch, app_id); if (is_silent_install) { ASSERT_TRUE(child_window_text_to_find.empty()); @@ -878,6 +879,14 @@ app_id)); } +void ExpectAppTag(UpdaterScope scope, + const std::string& app_id, + const std::string& tag) { + EXPECT_EQ(tag, base::MakeRefCounted<PersistedData>( + scope, CreateGlobalPrefs(scope)->GetPrefService()) + ->GetAP(app_id)); +} + void ExpectAppVersion(UpdaterScope scope, const std::string& app_id, const base::Version& version) {
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index 32ea13d3..d6878ea 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -140,6 +140,7 @@ void InstallUpdaterAndApp(UpdaterScope scope, const std::string& app_id, const bool is_silent_install, + const std::string& tag, const std::string& child_window_text_to_find); // Expects that the updater is installed on the system and the specified @@ -253,6 +254,10 @@ void ExpectNotRegistered(UpdaterScope scope, const std::string& app_id); +void ExpectAppTag(UpdaterScope scope, + const std::string& app_id, + const std::string& tag); + void ExpectAppVersion(UpdaterScope scope, const std::string& app_id, const base::Version& version);
diff --git a/chrome/updater/test/test_installer/main.cc b/chrome/updater/test/test_installer/main.cc index 4aaf8b69..d2b20ec 100644 --- a/chrome/updater/test/test_installer/main.cc +++ b/chrome/updater/test/test_installer/main.cc
@@ -15,6 +15,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/process/launch.h" #include "chrome/updater/win/installer/pe_resource.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace { @@ -44,15 +45,36 @@ return {}; } -bool RunScript(const base::FilePath& script_path) { +absl::optional<int> RunScript(const base::FilePath& script_path) { // Copy current process's command line so all arguments are forwarded. base::CommandLine command = *base::CommandLine::ForCurrentProcess(); command.SetProgram(script_path); command.PrependWrapper(CommandWrapperForScript(script_path)); int exit_code = -1; return base::LaunchProcess(command, {}) - .WaitForExitWithTimeout(base::Minutes(1), &exit_code) && - exit_code == 0; + .WaitForExitWithTimeout(base::Minutes(1), &exit_code) + ? absl::make_optional(exit_code) + : absl::nullopt; +} + +absl::optional<base::FilePath> CreateScriptFile( + HMODULE module, + const std::wstring& name, + const std::wstring& type, + const base::FilePath& working_dir) { + CHECK(name == L"BATCH" || name == L"POWERSHELL" || name == L"PYTHON"); + + updater::PEResource resource(name.c_str(), type.c_str(), module); + if (!resource.IsValid() || resource.Size() < 1) { + return {}; + } + + const base::FilePath script_path = + working_dir.AppendASCII("TestAppSetup") + .AddExtension(ExtensionFromResourceName(name)); + return resource.WriteToDisk(script_path.value().c_str()) + ? absl::make_optional(script_path) + : absl::nullopt; } BOOL CALLBACK OnResourceFound(HMODULE module, @@ -71,35 +93,39 @@ // Ignore unsupported script type and continue to enumerate other resources. return TRUE; } - - updater::PEResource resource(name, type, module); - if (!resource.IsValid() || resource.Size() < 1) { - return FALSE; - } - const base::FilePath* working_dir = reinterpret_cast<const base::FilePath*>(context); - const base::FilePath script_path = - working_dir->AppendASCII("TestAppSetup") - .AddExtension(ExtensionFromResourceName(name)); - if (!resource.WriteToDisk(script_path.value().c_str()) || - !RunScript(script_path)) { - return FALSE; - } - - return TRUE; + const auto script_path = CreateScriptFile(module, name, type, *working_dir); + return script_path && RunScript(*script_path); } int RunAllResourceScripts() { + constexpr char kScriptResourceNameSwitch[] = "script_resource_name"; + base::ScopedTempDir working_dir; if (!working_dir.CreateUniqueTempDir()) { return 1; } - return ::EnumResourceNames(nullptr, L"SCRIPT", OnResourceFound, - reinterpret_cast<LONG_PTR>(&working_dir.GetPath())) - ? 0 - : 1; + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + kScriptResourceNameSwitch)) { + return ::EnumResourceNames( + nullptr, L"SCRIPT", OnResourceFound, + reinterpret_cast<LONG_PTR>(&working_dir.GetPath())) + ? 0 + : 1; + } + + const auto script_resource_name = + base::CommandLine::ForCurrentProcess()->GetSwitchValueNative( + kScriptResourceNameSwitch); + const auto script_path = CreateScriptFile(nullptr, script_resource_name, + L"SCRIPT", working_dir.GetPath()); + if (!script_path) { + return -1; + } + const auto result = RunScript(*script_path); + return result ? *result : -1; } } // namespace
diff --git a/chrome/updater/test/test_installer/test_app2_setup.cmd b/chrome/updater/test/test_installer/test_app2_setup.cmd index fa31004..83140f4d 100644 --- a/chrome/updater/test/test_installer/test_app2_setup.cmd +++ b/chrome/updater/test/test_installer/test_app2_setup.cmd
@@ -9,6 +9,7 @@ set COMPANY=Google set APPID={AE098195-B8DB-4A49-8E23-84FCACB61FF1} set PRODUCT_VERSION=1.0.0.0 +set EXIT_CODE=0 :ParseCommandLine if "%1" == "" GOTO EndParseCommandLine @@ -35,6 +36,12 @@ shift GOTO ParseCommandLine ) +if "%1" == "--exit_code" ( + set EXIT_CODE=%2 + shift + shift + GOTO ParseCommandLine +) shift GOTO ParseCommandLine @@ -42,3 +49,4 @@ :EndParseCommandLine reg.exe add %REG_HIVE%\Software\%COMPANY%\Update\Clients\%APPID% /v pv /t REG_SZ /d %PRODUCT_VERSION% /f /reg:32 +EXIT %EXIT_CODE%
diff --git a/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.cc b/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.cc index 238fc701..1802fc1 100644 --- a/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.cc +++ b/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.cc
@@ -368,7 +368,7 @@ } // static -void CellularNetworkMetricsLogger::LogUserTextMessageSuppressionType( +void CellularNetworkMetricsLogger::LogUserTextMessageSuppressionState( ash::UserTextMessageSuppressionState state) { UserTextMessageSuppressionState histogram_type; switch (state) { @@ -379,12 +379,12 @@ histogram_type = UserTextMessageSuppressionState::kTextMessagesSuppress; break; } - base::UmaHistogramEnumeration(kUserAllowTextMessagesSuppressionTypeHistogram, + base::UmaHistogramEnumeration(kUserAllowTextMessagesSuppressionStateHistogram, histogram_type); } // static -void CellularNetworkMetricsLogger::LogPolicyTextMessageSuppressionType( +void CellularNetworkMetricsLogger::LogPolicyTextMessageSuppressionState( ash::PolicyTextMessageSuppressionState state) { PolicyTextMessageSuppressionState histogram_type; switch (state) { @@ -399,7 +399,7 @@ break; } base::UmaHistogramEnumeration( - kPolicyAllowTextMessagesSuppressionTypeHistogram, histogram_type); + kPolicyAllowTextMessagesSuppressionStateHistogram, histogram_type); } void CellularNetworkMetricsLogger::OnConnectionResult(
diff --git a/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.h b/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.h index 7e6bf18..1ba5d62b 100644 --- a/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.h +++ b/chromeos/ash/components/network/metrics/cellular_network_metrics_logger.h
@@ -209,10 +209,10 @@ static constexpr char kESimUserInstallUserErrorsIncludedViaSmds[] = "Network.Ash.Cellular.ESim.UserInstall.UserErrorsIncluded.ViaSmds"; - static constexpr char kUserAllowTextMessagesSuppressionTypeHistogram[] = - "Network.Ash.Cellular.AllowTextMessages.User.SuppressionType"; - static constexpr char kPolicyAllowTextMessagesSuppressionTypeHistogram[] = - "Network.Ash.Cellular.AllowTextMessages.Policy.SuppressionType"; + static constexpr char kUserAllowTextMessagesSuppressionStateHistogram[] = + "Network.Ash.Cellular.AllowTextMessages.User.SuppressionState"; + static constexpr char kPolicyAllowTextMessagesSuppressionStateHistogram[] = + "Network.Ash.Cellular.AllowTextMessages.Policy.SuppressionState"; CellularNetworkMetricsLogger( NetworkStateHandler* network_state_handler, @@ -269,9 +269,9 @@ // invalid activation code. static bool HermesResponseStatusIsUserError(HermesResponseStatus status); - static void LogUserTextMessageSuppressionType( + static void LogUserTextMessageSuppressionState( ash::UserTextMessageSuppressionState state); - static void LogPolicyTextMessageSuppressionType( + static void LogPolicyTextMessageSuppressionState( ash::PolicyTextMessageSuppressionState state); private:
diff --git a/chromeos/ash/components/network/network_metadata_store.cc b/chromeos/ash/components/network/network_metadata_store.cc index d29b313..413d6b6 100644 --- a/chromeos/ash/components/network/network_metadata_store.cc +++ b/chromeos/ash/components/network/network_metadata_store.cc
@@ -609,7 +609,7 @@ SetPref(network_guid, kUserTextMessageSuppressionState, base::Value(base::to_underlying(state))); - CellularNetworkMetricsLogger::LogUserTextMessageSuppressionType(state); + CellularNetworkMetricsLogger::LogUserTextMessageSuppressionState(state); } UserTextMessageSuppressionState
diff --git a/chromeos/ash/components/network/network_metadata_store_unittest.cc b/chromeos/ash/components/network/network_metadata_store_unittest.cc index f0c392bd..73a832d 100644 --- a/chromeos/ash/components/network/network_metadata_store_unittest.cc +++ b/chromeos/ash/components/network/network_metadata_store_unittest.cc
@@ -909,13 +909,13 @@ metadata_store()->GetUserTextMessageSuppressionState(kCellularkGuid)); histogram_tester.ExpectBucketCount( CellularNetworkMetricsLogger:: - kUserAllowTextMessagesSuppressionTypeHistogram, + kUserAllowTextMessagesSuppressionStateHistogram, CellularNetworkMetricsLogger::UserTextMessageSuppressionState:: kTextMessagesSuppress, 1u); histogram_tester.ExpectTotalCount( CellularNetworkMetricsLogger:: - kUserAllowTextMessagesSuppressionTypeHistogram, + kUserAllowTextMessagesSuppressionStateHistogram, 1u); // Case: Suppression state should be Allow when the user text message @@ -927,13 +927,13 @@ metadata_store()->GetUserTextMessageSuppressionState(kCellularkGuid)); histogram_tester.ExpectBucketCount( CellularNetworkMetricsLogger:: - kUserAllowTextMessagesSuppressionTypeHistogram, + kUserAllowTextMessagesSuppressionStateHistogram, CellularNetworkMetricsLogger::UserTextMessageSuppressionState:: kTextMessagesAllow, 1u); histogram_tester.ExpectTotalCount( CellularNetworkMetricsLogger:: - kUserAllowTextMessagesSuppressionTypeHistogram, + kUserAllowTextMessagesSuppressionStateHistogram, 2u); }
diff --git a/chromeos/ash/components/network/text_message_provider.cc b/chromeos/ash/components/network/text_message_provider.cc index 6b66d0d..d3e1552 100644 --- a/chromeos/ash/components/network/text_message_provider.cc +++ b/chromeos/ash/components/network/text_message_provider.cc
@@ -53,7 +53,7 @@ // Only log metrics when the suppression state changes. if (!old_state.has_value() || policy_suppression_state_ != old_state) { - CellularNetworkMetricsLogger::LogPolicyTextMessageSuppressionType( + CellularNetworkMetricsLogger::LogPolicyTextMessageSuppressionState( *policy_suppression_state_); } }
diff --git a/chromeos/ash/components/network/text_message_provider_unittest.cc b/chromeos/ash/components/network/text_message_provider_unittest.cc index 738d6e3..39ced1a 100644 --- a/chromeos/ash/components/network/text_message_provider_unittest.cc +++ b/chromeos/ash/components/network/text_message_provider_unittest.cc
@@ -111,18 +111,18 @@ size_t unset_count) { histogram_tester_->ExpectBucketCount( CellularNetworkMetricsLogger:: - kPolicyAllowTextMessagesSuppressionTypeHistogram, + kPolicyAllowTextMessagesSuppressionStateHistogram, CellularNetworkMetricsLogger::PolicyTextMessageSuppressionState::kUnset, unset_count); histogram_tester_->ExpectBucketCount( CellularNetworkMetricsLogger:: - kPolicyAllowTextMessagesSuppressionTypeHistogram, + kPolicyAllowTextMessagesSuppressionStateHistogram, CellularNetworkMetricsLogger::PolicyTextMessageSuppressionState:: kTextMessagesAllow, allow_count); histogram_tester_->ExpectBucketCount( CellularNetworkMetricsLogger:: - kPolicyAllowTextMessagesSuppressionTypeHistogram, + kPolicyAllowTextMessagesSuppressionStateHistogram, CellularNetworkMetricsLogger::PolicyTextMessageSuppressionState:: kTextMessagesSuppress, suppress_count);
diff --git a/chromeos/ash/components/report/utils/pref_utils.cc b/chromeos/ash/components/report/utils/pref_utils.cc index c53558ba..9920a892 100644 --- a/chromeos/ash/components/report/utils/pref_utils.cc +++ b/chromeos/ash/components/report/utils/pref_utils.cc
@@ -137,7 +137,7 @@ SaveStatusRequest save_request; // Store 1-day-active data. - if (one_day_ts != base::Time() || one_day_ts != base::Time::UnixEpoch()) { + if (one_day_ts != base::Time() && one_day_ts != base::Time::UnixEpoch()) { ActiveStatus one_day_status; one_day_status.set_use_case(PrivateComputingUseCase::CROS_FRESNEL_DAILY); one_day_status.set_last_ping_date( @@ -147,7 +147,7 @@ } // Store 28-day-active data. - if (twenty_eight_day_ts != base::Time() || + if (twenty_eight_day_ts != base::Time() && twenty_eight_day_ts != base::Time::UnixEpoch()) { ActiveStatus twenty_eight_day_status; twenty_eight_day_status.set_use_case( @@ -159,7 +159,7 @@ } // Store Churn data. - if (cohort_ts != base::Time() || cohort_ts != base::Time::UnixEpoch()) { + if (cohort_ts != base::Time() && cohort_ts != base::Time::UnixEpoch()) { ActiveStatus cohort_status; cohort_status.set_use_case( PrivateComputingUseCase::CROS_FRESNEL_CHURN_MONTHLY_COHORT);
diff --git a/chromeos/ash/components/report/utils/pref_utils_unittest.cc b/chromeos/ash/components/report/utils/pref_utils_unittest.cc index f3e67050..66476ba 100644 --- a/chromeos/ash/components/report/utils/pref_utils_unittest.cc +++ b/chromeos/ash/components/report/utils/pref_utils_unittest.cc
@@ -139,15 +139,23 @@ base::Time ts_1da; base::Time ts_28da; base::Time ts_churn_cohort; + base::Time ts_churn_observation; EXPECT_TRUE(base::Time::FromUTCString("2023-05-01", &ts_1da)); EXPECT_TRUE(base::Time::FromUTCString("2023-04-01", &ts_28da)); + + // Normally churn and cohort should have the same last ping dates. + // Below we will test this method in the odd case it stores different dates. EXPECT_TRUE(base::Time::FromUTCString("2023-03-01", &ts_churn_cohort)); + EXPECT_TRUE(base::Time::FromUTCString("2023-03-01", &ts_churn_observation)); + local_state->SetTime(prefs::kDeviceActiveLastKnown1DayActivePingTimestamp, ts_1da); local_state->SetTime(prefs::kDeviceActiveLastKnown28DayActivePingTimestamp, ts_28da); local_state->SetTime(prefs::kDeviceActiveChurnCohortMonthlyPingTimestamp, ts_churn_cohort); + local_state->SetTime(prefs::kDeviceActiveChurnObservationMonthlyPingTimestamp, + ts_churn_observation); local_state->SetInteger(prefs::kDeviceActiveLastKnownChurnActiveStatus, 1); local_state->SetBoolean( @@ -193,4 +201,43 @@ .is_active_current_period_minus_2()); } +TEST_F(PrefUtilsTest, + CreatePreservedFileContentsForUnsynedCohortAndObservation) { + PrefService* local_state = GetLocalState(); + + // Prepare a sample PrefService instance with stored values. + base::Time ts_churn_cohort; + base::Time ts_churn_observation; + + // Test odd case cohort and observation store different last ping dates. + EXPECT_TRUE(base::Time::FromUTCString("2023-03-01", &ts_churn_cohort)); + EXPECT_TRUE(base::Time::FromUTCString("2023-02-01", &ts_churn_observation)); + + local_state->SetTime(prefs::kDeviceActiveChurnCohortMonthlyPingTimestamp, + ts_churn_cohort); + local_state->SetTime(prefs::kDeviceActiveChurnObservationMonthlyPingTimestamp, + ts_churn_observation); + + local_state->SetInteger(prefs::kDeviceActiveLastKnownChurnActiveStatus, 1); + local_state->SetBoolean( + prefs::kDeviceActiveLastKnownIsActiveCurrentPeriodMinus0, true); + local_state->SetBoolean( + prefs::kDeviceActiveLastKnownIsActiveCurrentPeriodMinus1, true); + local_state->SetBoolean( + prefs::kDeviceActiveLastKnownIsActiveCurrentPeriodMinus2, true); + + // Create the preserved file contents. + SaveStatusRequest save_request = CreatePreservedFileContents(local_state); + + // Active status stored for: Churn Cohort. + // No preserved file data stored for Churn Observation because it's + // out of sync with the cohort last ping. + EXPECT_EQ(1, save_request.active_status_size()); + EXPECT_EQ(PrivateComputingUseCase::CROS_FRESNEL_CHURN_MONTHLY_COHORT, + save_request.active_status(0).use_case()); + EXPECT_EQ("2023-03-01 00:00:00.000 GMT", + save_request.active_status(0).last_ping_date()); + EXPECT_EQ(1, save_request.active_status(0).churn_active_status()); +} + } // namespace ash::report::utils
diff --git a/chromeos/assistant/internal b/chromeos/assistant/internal index 000d238..5c8d934 160000 --- a/chromeos/assistant/internal +++ b/chromeos/assistant/internal
@@ -1 +1 @@ -Subproject commit 000d2387867d26ced802a4e18ef0ef970e17a755 +Subproject commit 5c8d934c2f1056cf21a80ba7896d6a65977dd580
diff --git a/chromeos/dbus/missive/history_tracker.cc b/chromeos/dbus/missive/history_tracker.cc index ef199e7..7c9ec3c6 100644 --- a/chromeos/dbus/missive/history_tracker.cc +++ b/chromeos/dbus/missive/history_tracker.cc
@@ -15,12 +15,12 @@ HistoryTracker::HistoryTracker( scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner) - : sequenced_task_runner_(sequenced_task_runner) {} - -HistoryTracker::~HistoryTracker() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + : sequenced_task_runner_(sequenced_task_runner) { + DETACH_FROM_SEQUENCE(sequence_checker_); } +HistoryTracker::~HistoryTracker() = default; + // static HistoryTracker* HistoryTracker::Get() { static HistoryTracker tracker{ @@ -29,13 +29,27 @@ } void HistoryTracker::AddObserver(HistoryTracker::Observer* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - observer_list_.AddObserver(observer); + sequenced_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](HistoryTracker::Observer* observer) { + auto* const tracker = HistoryTracker::Get(); + DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); + tracker->observer_list_.AddObserver(observer); + }, + observer)); } void HistoryTracker::RemoveObserver(const HistoryTracker::Observer* observer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - observer_list_.RemoveObserver(observer); + sequenced_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](const HistoryTracker::Observer* observer) { + auto* const tracker = HistoryTracker::Get(); + DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); + tracker->observer_list_.RemoveObserver(observer); + }, + observer)); } bool HistoryTracker::debug_state() const { @@ -50,16 +64,28 @@ void HistoryTracker::retrieve_data( base::OnceCallback<void(const ERPHealthData&)> cb) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::move(cb).Run(data_); + sequenced_task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce([]() { + auto* const tracker = HistoryTracker::Get(); + DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); + return tracker->data_; + }), + std::move(cb)); // Call cb(tracker->data_) on the current thread. } void HistoryTracker::set_data(ERPHealthData data, base::OnceClosure cb) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - data_ = std::move(data); - std::move(cb).Run(); - for (const auto& observer : observer_list_) { - observer.OnNewData(data_); - } + sequenced_task_runner_->PostTaskAndReply( + FROM_HERE, + base::BindOnce( + [](ERPHealthData data) { + auto* const tracker = HistoryTracker::Get(); + DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); + tracker->data_ = std::move(data); + for (const auto& observer : tracker->observer_list_) { + observer.OnNewData(tracker->data_); + } + }, + std::move(data)), + std::move(cb)); // Call cb() on the current thread. } } // namespace reporting
diff --git a/chromeos/dbus/missive/history_tracker_unittest.cc b/chromeos/dbus/missive/history_tracker_unittest.cc index 8198625b..6e4a6a6 100644 --- a/chromeos/dbus/missive/history_tracker_unittest.cc +++ b/chromeos/dbus/missive/history_tracker_unittest.cc
@@ -36,7 +36,7 @@ EXPECT_FALSE(tracker_->debug_state()); } -TEST_F(HistoryTrackerTest, CollelctHistoryTest) { +TEST_F(HistoryTrackerTest, CollectHistoryTest) { ERPHealthData data; auto* const enqueue_record = data.add_history()->mutable_enqueue_record_call(); @@ -136,6 +136,8 @@ base::BindOnce(&test::TestCallbackAutoWaiter::Signal, base::Unretained(&waiter))); } + + task_environment_.RunUntilIdle(); // Drain possible unfinished tasks. } } // namespace } // namespace reporting
diff --git a/chromeos/dbus/missive/missive_client.cc b/chromeos/dbus/missive/missive_client.cc index 4a4257c2..cbd3d04 100644 --- a/chromeos/dbus/missive/missive_client.cc +++ b/chromeos/dbus/missive/missive_client.cc
@@ -275,6 +275,15 @@ return reporting::Status(reporting::error::INTERNAL, "Response was not parsable."); } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Accept health data if present (ChromeOS only) + if (response_body.has_health_data()) { + ::reporting::HistoryTracker::Get()->set_data( + std::move(response_body.health_data()), base::DoNothing()); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + reporting::Status status; status.RestoreFrom(response_body.status()); return status; @@ -294,6 +303,12 @@ owner, std::move(completion_callback)) { request_.set_priority(priority); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Turn on/off the debug state flag (for Ash only). + request_.set_health_data_logging_enabled( + ::reporting::HistoryTracker::Get()->debug_state()); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } bool WriteRequest(dbus::MessageWriter* writer) override { @@ -306,6 +321,15 @@ return reporting::Status(reporting::error::INTERNAL, "Response was not parsable."); } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Accept health data if present (ChromeOS only) + if (response_body.has_health_data()) { + ::reporting::HistoryTracker::Get()->set_data( + std::move(response_body.health_data()), base::DoNothing()); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + reporting::Status status; status.RestoreFrom(response_body.status()); return status; @@ -364,12 +388,38 @@ base::DoNothing()) { *request_.mutable_sequence_information() = sequence_information; request_.set_force_confirm(force_confirm); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Turn on/off the debug state flag (for Ash only). + request_.set_health_data_logging_enabled( + ::reporting::HistoryTracker::Get()->debug_state()); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) } bool WriteRequest(dbus::MessageWriter* writer) override { return writer->AppendProtoAsArrayOfBytes(request_); } + reporting::Status ParseResponse(dbus::MessageReader* reader) override { + reporting::ConfirmRecordUploadResponse response_body; + if (!reader->PopArrayOfBytesAsProto(&response_body)) { + return reporting::Status(reporting::error::INTERNAL, + "Response was not parsable."); + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Accept health data if present (ChromeOS only) + if (response_body.has_health_data()) { + ::reporting::HistoryTracker::Get()->set_data( + std::move(response_body.health_data()), base::DoNothing()); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + reporting::Status status; + status.RestoreFrom(response_body.status()); + return status; + } + private: reporting::ConfirmRecordUploadRequest request_; };
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni index f05aa9f..49dec930 100644 --- a/chromeos/tast_control.gni +++ b/chromeos/tast_control.gni
@@ -227,6 +227,9 @@ # b/296913657 "secagentd.ProcessEvents@amd64-generic", + # https://crbug.com/1483337 + "lacros.Activate.keep_alive", + # READ COMMENT AT TOP BEFORE ADDING NEW TESTS HERE. ] @@ -270,5 +273,8 @@ # https://crbug.com/1470305 "inputs.VirtualKeyboardTypingOmnibox.a11y_lacros", + # https://crbug.com/1483337 + "lacros.Activate.keep_alive", + # THIS IS THE LACROS LIST, SCROLL UP FOR CHROME/CHROMEOS. ]
diff --git a/chromeos/ui/base/file_icon_util.cc b/chromeos/ui/base/file_icon_util.cc index 4944f4e..df830f9 100644 --- a/chromeos/ui/base/file_icon_util.cc +++ b/chromeos/ui/base/file_icon_util.cc
@@ -9,6 +9,7 @@ #include "base/containers/fixed_flat_map.h" #include "base/files/file_path.h" +#include "base/memory/raw_ref.h" #include "base/no_destructor.h" #include "base/strings/string_piece_forward.h" #include "base/strings/string_util.h" @@ -48,7 +49,7 @@ }; struct IconParams { - const gfx::VectorIcon& icon; + const raw_ref<const gfx::VectorIcon> icon; ColorId color_id; }; @@ -133,43 +134,55 @@ static const base::NoDestructor<std::map<IconType, IconParams>> icon_type_to_icon_params( {{IconType::kArchive, - IconParams{kFiletypeArchiveIcon, ColorId::kGrey}}, - {IconType::kAudio, IconParams{kFiletypeAudioIcon, ColorId::kRed}}, - {IconType::kChart, IconParams{kFiletypeChartIcon, ColorId::kGreen}}, + IconParams{raw_ref(kFiletypeArchiveIcon), ColorId::kGrey}}, + {IconType::kAudio, + IconParams{raw_ref(kFiletypeAudioIcon), ColorId::kRed}}, + {IconType::kChart, + IconParams{raw_ref(kFiletypeChartIcon), ColorId::kGreen}}, {IconType::kDrive, - IconParams{kFiletypeTeamDriveIcon, ColorId::kGrey}}, + IconParams{raw_ref(kFiletypeTeamDriveIcon), ColorId::kGrey}}, {IconType::kExcel, - IconParams{kFiletypeExcelIcon, ColorId::kFiletypeExcel}}, - {IconType::kFolder, IconParams{kFiletypeFolderIcon, ColorId::kGrey}}, + IconParams{raw_ref(kFiletypeExcelIcon), ColorId::kFiletypeExcel}}, + {IconType::kFolder, + IconParams{raw_ref(kFiletypeFolderIcon), ColorId::kGrey}}, {IconType::kFolderShared, - IconParams{kFiletypeSharedIcon, ColorId::kGrey}}, - {IconType::kGdoc, IconParams{kFiletypeGdocIcon, ColorId::kBlue}}, - {IconType::kGdraw, IconParams{kFiletypeGdrawIcon, ColorId::kRed}}, + IconParams{raw_ref(kFiletypeSharedIcon), ColorId::kGrey}}, + {IconType::kGdoc, + IconParams{raw_ref(kFiletypeGdocIcon), ColorId::kBlue}}, + {IconType::kGdraw, + IconParams{raw_ref(kFiletypeGdrawIcon), ColorId::kRed}}, {IconType::kGeneric, - IconParams{kFiletypeGenericIcon, ColorId::kGrey}}, + IconParams{raw_ref(kFiletypeGenericIcon), ColorId::kGrey}}, {IconType::kGform, - IconParams{kFiletypeGformIcon, ColorId::kFiletypeGform}}, - {IconType::kGmap, IconParams{kFiletypeGmapIcon, ColorId::kRed}}, + IconParams{raw_ref(kFiletypeGformIcon), ColorId::kFiletypeGform}}, + {IconType::kGmap, + IconParams{raw_ref(kFiletypeGmapIcon), ColorId::kRed}}, {IconType::kGsheet, - IconParams{kFiletypeGsheetIcon, ColorId::kGreen}}, + IconParams{raw_ref(kFiletypeGsheetIcon), ColorId::kGreen}}, {IconType::kGsite, - IconParams{kFiletypeGsiteIcon, ColorId::kFiletypeGsite}}, + IconParams{raw_ref(kFiletypeGsiteIcon), ColorId::kFiletypeGsite}}, {IconType::kGslide, - IconParams{kFiletypeGslidesIcon, ColorId::kYellow}}, + IconParams{raw_ref(kFiletypeGslidesIcon), ColorId::kYellow}}, {IconType::kGtable, - IconParams{kFiletypeGtableIcon, ColorId::kGreen}}, - {IconType::kImage, IconParams{kFiletypeImageIcon, ColorId::kRed}}, - {IconType::kLinux, IconParams{kFiletypeLinuxIcon, ColorId::kGrey}}, - {IconType::kPdf, IconParams{kFiletypePdfIcon, ColorId::kRed}}, + IconParams{raw_ref(kFiletypeGtableIcon), ColorId::kGreen}}, + {IconType::kImage, + IconParams{raw_ref(kFiletypeImageIcon), ColorId::kRed}}, + {IconType::kLinux, + IconParams{raw_ref(kFiletypeLinuxIcon), ColorId::kGrey}}, + {IconType::kPdf, + IconParams{raw_ref(kFiletypePdfIcon), ColorId::kRed}}, {IconType::kPpt, - IconParams{kFiletypePptIcon, ColorId::kFiletypePpt}}, - {IconType::kScript, IconParams{kFiletypeScriptIcon, ColorId::kBlue}}, + IconParams{raw_ref(kFiletypePptIcon), ColorId::kFiletypePpt}}, + {IconType::kScript, + IconParams{raw_ref(kFiletypeScriptIcon), ColorId::kBlue}}, {IconType::kSites, - IconParams{kFiletypeSitesIcon, ColorId::kFiletypeSites}}, - {IconType::kTini, IconParams{kFiletypeTiniIcon, ColorId::kBlue}}, - {IconType::kVideo, IconParams{kFiletypeVideoIcon, ColorId::kRed}}, + IconParams{raw_ref(kFiletypeSitesIcon), ColorId::kFiletypeSites}}, + {IconType::kTini, + IconParams{raw_ref(kFiletypeTiniIcon), ColorId::kBlue}}, + {IconType::kVideo, + IconParams{raw_ref(kFiletypeVideoIcon), ColorId::kRed}}, {IconType::kWord, - IconParams{kFiletypeWordIcon, ColorId::kFiletypeWord}}}); + IconParams{raw_ref(kFiletypeWordIcon), ColorId::kFiletypeWord}}}); return *icon_type_to_icon_params; } @@ -186,7 +199,7 @@ absl::optional<int> dip_size) { const IconParams& params = GetIconParamsFromIconType(icon); const gfx::IconDescription description( - params.icon, dip_size.value_or(kIconDefaultDipSize), + *params.icon, dip_size.value_or(kIconDefaultDipSize), ResolveColor(params.color_id, dark_background)); return gfx::CreateVectorIcon(description); @@ -357,7 +370,8 @@ } // namespace internal const gfx::VectorIcon& GetIconForPath(const base::FilePath& filepath) { - return GetIconParamsFromIconType(internal::GetIconTypeForPath(filepath)).icon; + return *GetIconParamsFromIconType(internal::GetIconTypeForPath(filepath)) + .icon; } gfx::ImageSkia GetIconForPath(const base::FilePath& filepath, @@ -373,8 +387,8 @@ } const gfx::VectorIcon& GetIconFromType(const std::string& icon_type) { - return GetIconParamsFromIconType(internal::GetIconTypeFromString(icon_type)) - .icon; + return *GetIconParamsFromIconType(internal::GetIconTypeFromString(icon_type)) + .icon; } gfx::ImageSkia GetIconFromType(const std::string& icon_type,
diff --git a/chromeos/ui/vector_icons/BUILD.gn b/chromeos/ui/vector_icons/BUILD.gn index f7434c10..318de13 100644 --- a/chromeos/ui/vector_icons/BUILD.gn +++ b/chromeos/ui/vector_icons/BUILD.gn
@@ -40,6 +40,7 @@ "filetype_video.icon", "filetype_word.icon", "float_window.icon", + "game_dashboard_gamepad.icon", "keyboard_shortcuts.icon", "notification_assistant.icon", "notification_supervised_user.icon",
diff --git a/chrome/app/vector_icons/game_controls_gamepad.icon b/chromeos/ui/vector_icons/game_dashboard_gamepad.icon similarity index 100% rename from chrome/app/vector_icons/game_controls_gamepad.icon rename to chromeos/ui/vector_icons/game_dashboard_gamepad.icon
diff --git a/clank b/clank index 55f9354..e3a3ec4 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 55f9354534a9170aebc212260f3a8e73c2804a32 +Subproject commit e3a3ec407403dece9002c87d4de7130e2ab877e4
diff --git a/components/autofill/core/browser/address_normalizer_impl.cc b/components/autofill/core/browser/address_normalizer_impl.cc index b0cf8d5..a6ba2a00 100644 --- a/components/autofill/core/browser/address_normalizer_impl.cc +++ b/components/autofill/core/browser/address_normalizer_impl.cc
@@ -282,8 +282,9 @@ const base::android::JavaParamRef<jobject>& jprofile, jint jtimeout_seconds, const base::android::JavaParamRef<jobject>& jdelegate) { - AutofillProfile profile = - AutofillProfile::CreateFromJavaObject(jprofile, app_locale_); + // TODO(crbug.com/1484006): Check if existing profile needs to be passed. + AutofillProfile profile = AutofillProfile::CreateFromJavaObject( + jprofile, /*existing_profile=*/nullptr, app_locale_); // Start the normalization. NormalizeAddressAsync(
diff --git a/components/autofill/core/browser/autofill_profile_import_process.cc b/components/autofill/core/browser/autofill_profile_import_process.cc index c573b4d..59cf170 100644 --- a/components/autofill/core/browser/autofill_profile_import_process.cc +++ b/components/autofill/core/browser/autofill_profile_import_process.cc
@@ -197,7 +197,7 @@ if (!base::FeatureList::IsEnabled( features::test::kAutofillDisableSilentProfileUpdates)) { merged_profile.set_modification_date(AutofillClock::Now()); - updated_profiles_.emplace_back(merged_profile); + silently_updated_profiles_.emplace_back(merged_profile); } else { ++number_of_unchanged_profiles; } @@ -222,7 +222,7 @@ import_type_ = AutofillProfileImportType::kUnusableIncompleteProfile; } } else { - bool silent_updates_present = updated_profiles_.size() > 0; + bool silent_updates_present = !silently_updated_profiles_.empty(); if (merge_candidate_.has_value()) { import_type_ = @@ -263,7 +263,7 @@ // One of the unchanged or updated profiles might be considered for migration. // In this case, `import_type()` is `kProfileMigrationAndMaybeSilentUpdates`. DCHECK_EQ(existing_profiles.size(), - number_of_unchanged_profiles + updated_profiles_.size() + + number_of_unchanged_profiles + silently_updated_profiles_.size() + (merge_candidate_.has_value() ? 1 : 0)); DCHECK_NE(import_type_, AutofillProfileImportType::kImportTypeUnspecified); } @@ -304,8 +304,8 @@ std::vector<AutofillProfile> resulting_profiles; std::set<std::string> guids_of_changed_profiles; - // Add all updated profiles. - for (const auto& updated_profile : updated_profiles_) { + // Add all silently updated profiles. + for (const auto& updated_profile : silently_updated_profiles_) { resulting_profiles.push_back(updated_profile); guids_of_changed_profiles.insert(updated_profile.guid()); } @@ -324,7 +324,7 @@ // revived below as one of the unchanged profiles. guids_of_changed_profiles.insert(confirmed_import_candidate_->guid()); // If the `import_candidate_` was silently updated, it is part of - // `updated_profiles_`. Remove the corresponding + // `silently_updated_profiles_`. Remove the corresponding // `confirmed_import_candidate_` from `reesulting_profiles`, so it doesn't // get revived. base::EraseIf(resulting_profiles, [&](const AutofillProfile& profile) { @@ -431,8 +431,7 @@ // At this point, a user decision must have been supplied. DCHECK_NE(user_decision_, UserDecision::kUndefined); - // If there are any updated profiles, return true. - if (updated_profiles_.size() > 0) { + if (!silently_updated_profiles_.empty()) { return true; }
diff --git a/components/autofill/core/browser/autofill_profile_import_process.h b/components/autofill/core/browser/autofill_profile_import_process.h index 5e020f154..e0c766b 100644 --- a/components/autofill/core/browser/autofill_profile_import_process.h +++ b/components/autofill/core/browser/autofill_profile_import_process.h
@@ -141,8 +141,8 @@ return merge_candidate_; } - const std::vector<AutofillProfile>& updated_profiles() const { - return updated_profiles_; + const std::vector<AutofillProfile>& silently_updated_profiles() const { + return silently_updated_profiles_; } const AutofillProfileImportId& import_id() const { return import_id_; } @@ -265,7 +265,7 @@ AutofillProfile observed_profile_; // Profiles that are silently updatable with the observed profile. - std::vector<AutofillProfile> updated_profiles_; + std::vector<AutofillProfile> silently_updated_profiles_; // A profile in its original state that can be merged with the observed // profile.
diff --git a/components/autofill/core/browser/autofill_profile_import_process_unittest.cc b/components/autofill/core/browser/autofill_profile_import_process_unittest.cc index 4e7a00e..aac2843 100644 --- a/components/autofill/core/browser/autofill_profile_import_process_unittest.cc +++ b/components/autofill/core/browser/autofill_profile_import_process_unittest.cc
@@ -575,7 +575,7 @@ ASSERT_TRUE(import_data.merge_candidate().has_value()); EXPECT_EQ(import_data.merge_candidate(), mergeable_profile); // But there should be no further updates profiles. - EXPECT_EQ(import_data.updated_profiles().size(), 0u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 0u); // Simulate the decline by the user. import_data.Declined(); @@ -621,7 +621,7 @@ // There should be no merge candidate since this is only a silent update. EXPECT_FALSE(import_data.merge_candidate().has_value()); // But there should be one updated profiles. - EXPECT_EQ(import_data.updated_profiles().size(), 1u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 1u); // In this scenario, the user should not be prompted. import_data.AcceptWithoutPrompt(); @@ -667,7 +667,7 @@ ASSERT_TRUE(import_data.merge_candidate().has_value()); EXPECT_EQ(import_data.merge_candidate(), mergeable_profile); // And also an updated profile. - EXPECT_EQ(import_data.updated_profiles().size(), 1u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 1u); // Simulate that the user accepts the prompt without edits. import_data.AcceptWithoutEdits(); @@ -710,7 +710,7 @@ ASSERT_TRUE(import_data.merge_candidate().has_value()); EXPECT_EQ(import_data.merge_candidate(), mergeable_profile); // And also an updated profile. - EXPECT_EQ(import_data.updated_profiles().size(), 1u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 1u); // Simulate that the user declines the merge. import_data.Declined(); @@ -755,7 +755,7 @@ // There should be no merge candidate because the only potential candidate is // blocked but there should be a silent update. EXPECT_FALSE(import_data.merge_candidate().has_value()); - EXPECT_EQ(import_data.updated_profiles().size(), 1u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 1u); // The user should not be asked. import_data.AcceptWithoutPrompt(); @@ -796,7 +796,7 @@ // There should be no merge candidate because the only potential candidate is // blocked and also no silent update. EXPECT_FALSE(import_data.merge_candidate().has_value()); - EXPECT_EQ(import_data.updated_profiles().size(), 0u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 0u); // The user should not be asked. import_data.AcceptWithoutPrompt(); @@ -838,7 +838,7 @@ // There should be no merge candidate since this is only a silent update. EXPECT_FALSE(import_data.merge_candidate().has_value()); // But there should be one updated profiles. - EXPECT_EQ(import_data.updated_profiles().size(), 1u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 1u); // In this scenario, the user should not be prompted. import_data.AcceptWithoutPrompt(); @@ -880,7 +880,7 @@ // There should be no merge candidate since this is only a silent update. EXPECT_FALSE(import_data.merge_candidate().has_value()); // But there should be one updated profiles. - EXPECT_TRUE(import_data.updated_profiles().empty()); + EXPECT_TRUE(import_data.silently_updated_profiles().empty()); // In this scenario, the user should not be prompted. import_data.AcceptWithoutPrompt(); @@ -915,7 +915,7 @@ // There should be no merge candidate because the only potential candidate is // blocked but there should be a silent update. EXPECT_FALSE(import_data.merge_candidate().has_value()); - EXPECT_EQ(import_data.updated_profiles().size(), 1u); + EXPECT_EQ(import_data.silently_updated_profiles().size(), 1u); // The user should not be asked. import_data.AcceptWithoutPrompt();
diff --git a/components/autofill/core/browser/data_model/autofill_profile.cc b/components/autofill/core/browser/data_model/autofill_profile.cc index 5d98876..32d823a 100644 --- a/components/autofill/core/browser/data_model/autofill_profile.cc +++ b/components/autofill/core/browser/data_model/autofill_profile.cc
@@ -220,33 +220,6 @@ } } -#if BUILDFLAG(IS_ANDROID) -void MaybeSetRawInfoWithVerificationStatus( - AutofillProfile* profile, - ServerFieldType type, - const base::android::JavaRef<jstring>& value, - jint status) { - if (value) { - profile->SetRawInfoWithVerificationStatus( - type, ConvertJavaStringToUTF16(value), - static_cast<VerificationStatus>(status)); - } -} - -void MaybeSetInfoWithVerificationStatus( - AutofillProfile* profile, - ServerFieldType type, - const base::android::JavaRef<jstring>& value, - jint status, - const std::string& app_locale) { - if (value) { - profile->SetInfoWithVerificationStatus( - type, ConvertJavaStringToUTF16(value), app_locale, - static_cast<VerificationStatus>(status)); - } -} -#endif // BUILDFLAG(IS_ANDROID) - } // namespace AutofillProfile::AutofillProfile() @@ -356,17 +329,27 @@ // static AutofillProfile AutofillProfile::CreateFromJavaObject( const base::android::JavaParamRef<jobject>& jprofile, + const AutofillProfile* existing_profile, const std::string& app_locale) { JNIEnv* env = base::android::AttachCurrentThread(); - AutofillProfile profile(static_cast<AutofillProfile::Source>( - Java_AutofillProfile_getSource(env, jprofile))); - // Only set the guid if it is an existing profile (java guid not empty). - // Otherwise, keep the generated one. - std::string guid = - ConvertJavaStringToUTF8(Java_AutofillProfile_getGUID(env, jprofile)); - if (!guid.empty()) { - profile.set_guid(guid); + AutofillProfile profile; + if (!existing_profile) { + profile = AutofillProfile(static_cast<AutofillProfile::Source>( + Java_AutofillProfile_getSource(env, jprofile))); + // Only set the guid if it is an existing profile (java guid not empty). + // Otherwise, keep the generated one. + std::string guid = + ConvertJavaStringToUTF8(Java_AutofillProfile_getGUID(env, jprofile)); + // TODO(crbug.com/1484006): `guid` should be always empty when existing + // profile is not set. CHECK should be added when this condition holds. + if (!guid.empty()) { + profile.set_guid(guid); + } + } else { + profile = *existing_profile; + CHECK_EQ(profile.guid(), ConvertJavaStringToUTF8( + Java_AutofillProfile_getGUID(env, jprofile))); } std::vector<int> field_types; @@ -374,20 +357,23 @@ env, Java_AutofillProfile_getFieldTypes(env, jprofile), &field_types); for (int int_field_type : field_types) { - auto field_type = ToSafeServerFieldType(int_field_type, NO_SERVER_DATA); + ServerFieldType field_type = + ToSafeServerFieldType(int_field_type, NO_SERVER_DATA); CHECK(field_type != NO_SERVER_DATA); + VerificationStatus status = static_cast<VerificationStatus>( + Java_AutofillProfile_getInfoStatus(env, jprofile, field_type)); + const base::android::ScopedJavaLocalRef<jstring> value = + Java_AutofillProfile_getInfo(env, jprofile, field_type); + if (!value) { + continue; + } // TODO(crbug.com/1471502): Reconcile usage of GetInfo and GetRawInfo below. if (field_type == NAME_FULL || field_type == ADDRESS_HOME_COUNTRY) { - MaybeSetInfoWithVerificationStatus( - &profile, field_type, - Java_AutofillProfile_getInfo(env, jprofile, field_type), - Java_AutofillProfile_getInfoStatus(env, jprofile, field_type), - app_locale); + profile.SetInfoWithVerificationStatus( + field_type, ConvertJavaStringToUTF16(value), app_locale, status); } else { - MaybeSetRawInfoWithVerificationStatus( - &profile, field_type, - Java_AutofillProfile_getInfo(env, jprofile, field_type), - Java_AutofillProfile_getInfoStatus(env, jprofile, field_type)); + profile.SetRawInfoWithVerificationStatus( + field_type, ConvertJavaStringToUTF16(value), status); } }
diff --git a/components/autofill/core/browser/data_model/autofill_profile.h b/components/autofill/core/browser/data_model/autofill_profile.h index cbbf421a..e69364eb 100644 --- a/components/autofill/core/browser/data_model/autofill_profile.h +++ b/components/autofill/core/browser/data_model/autofill_profile.h
@@ -89,8 +89,16 @@ const std::string& app_locale) const; // Given a Java AutofillProfile object, create an equivalent C++ instance. + // Java profile can represent either a new or an existing address profile + // depending on whether `existing_profile` is set or not. If this is a new + // address profile, Java fields are set to the newly created AutofillProfile. + // Otherwise, `existing_profile` is copied and Java fields are set to it. + // Setting fields to `existing_profile` is done to avoid loosing address + // substructure by creating AutofillProfile from scratch based only on the + // available Java fields. static AutofillProfile CreateFromJavaObject( const base::android::JavaParamRef<jobject>& jprofile, + const AutofillProfile* existing_profile, const std::string& app_locale); #endif // BUILDFLAG(IS_ANDROID)
diff --git a/components/autofill/core/browser/field_filler.cc b/components/autofill/core/browser/field_filler.cc index c9a3382..b4456cf 100644 --- a/components/autofill/core/browser/field_filler.cc +++ b/components/autofill/core/browser/field_filler.cc
@@ -905,6 +905,7 @@ } else { switch (storable_type) { case CREDIT_CARD_VERIFICATION_CODE: + case CREDIT_CARD_STANDALONE_VERIFICATION_CODE: return GetCreditCardVerificationCodeForInput(credit_card, action_persistence, cvc); case CREDIT_CARD_NUMBER: @@ -970,6 +971,7 @@ switch (storable_type) { case CREDIT_CARD_VERIFICATION_CODE: + case CREDIT_CARD_STANDALONE_VERIFICATION_CODE: // For preview virtual card CVC, return three dots unless for American // Express, which uses 4-digit CVCs. return virtual_card.network() == kAmericanExpressCard
diff --git a/components/autofill/core/browser/field_filler_unittest.cc b/components/autofill/core/browser/field_filler_unittest.cc index 6cac920..a3703e43 100644 --- a/components/autofill/core/browser/field_filler_unittest.cc +++ b/components/autofill/core/browser/field_filler_unittest.cc
@@ -11,6 +11,7 @@ #include "base/base_paths.h" #include "base/files/file_path.h" +#include "base/notreached.h" #include "base/path_service.h" #include "base/ranges/algorithm.h" #include "base/stl_util.h" @@ -558,6 +559,60 @@ EXPECT_EQ(kEmptyCvc, field.value); } +// Tests that CVC is correctly previewed and filled for a standalone CVC field. +TEST_P(CreditCardVerificationCodeTest, FillFormField_StandaloneCVCField) { + AutofillField field; + field.SetTypeTo(AutofillType(CREDIT_CARD_STANDALONE_VERIFICATION_CODE)); + + // Credit card related field. + CreditCard credit_card = test::GetMaskedServerCardWithCvc(); + const mojom::AutofillActionPersistence persistence = GetParam(); + FieldFiller filler("en-US", /*address_normalizer=*/nullptr); + filler.FillFormField(field, &credit_card, /*forced_fill_values=*/{}, &field, + /*cvc=*/std::u16string(), persistence); + + switch (persistence) { + case mojom::AutofillActionPersistence::kPreview: + EXPECT_EQ(kMidlineEllipsis3Dots, field.value); + return; + case mojom::AutofillActionPersistence::kFill: + EXPECT_EQ(credit_card.cvc(), field.value); + return; + default: + NOTREACHED(); + } +} + +// Tests that CVC is correctly previewed and filled for a standalone CVC field +// for American Express credit cards, which often use four digit verification +// codes. +TEST_P(CreditCardVerificationCodeTest, + FillFormField_StandaloneCVCField_AmericanExpress) { + AutofillField field; + field.SetTypeTo(AutofillType(CREDIT_CARD_STANDALONE_VERIFICATION_CODE)); + + // Credit card related field. + CreditCard card = test::GetVirtualCard(); + test_api(card).set_network_for_virtual_card(kAmericanExpressCard); + const std::u16string kCvc = u"1111"; + card.set_cvc(kCvc); + const mojom::AutofillActionPersistence persistence = GetParam(); + FieldFiller filler("en-US", /*address_normalizer=*/nullptr); + filler.FillFormField(field, &card, /*forced_fill_values=*/{}, &field, kCvc, + persistence); + + switch (persistence) { + case mojom::AutofillActionPersistence::kPreview: + EXPECT_EQ(kMidlineEllipsis4Dots, field.value); + return; + case mojom::AutofillActionPersistence::kFill: + EXPECT_EQ(kCvc, field.value); + return; + default: + NOTREACHED(); + } +} + INSTANTIATE_TEST_SUITE_P( AutofillFieldFillerTest, CreditCardVerificationCodeTest,
diff --git a/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json b/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json index 4e82ed68..8cbf71e18 100644 --- a/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json +++ b/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json
@@ -158,13 +158,13 @@ ], "es": [ { - "positive_pattern": "n(u|ú)mero.*apartamento|exterior", + "positive_pattern": "exterior", "positive_score": 1.1, "negative_pattern": null, "match_field_attributes": ["LABEL", "NAME"], "match_field_input_types": ["TEXT", "TELEPHONE", "NUMBER"] } - ], + ], "ru": [ { "positive_pattern": "дом|номер.?дома", @@ -1667,7 +1667,7 @@ "CREDIT_CARD_VERIFICATION_CODE": { "en": [ { - "positive_pattern": "verification|card.?identification|security.?code|card.?code|security.?value|security.?number|card.?pin|c-v-v|(cvn|cvv|cvc|csc|cvd|ccv)|\\bcid\\b|cccid", + "positive_pattern": "verification|card.?identification|security.?code|card.?code|security.?value|security.?number|card.?pin|c-v-v|(?:cvn|cvv|cvc|csc|cvd|ccv)|\\bcid\\b|cccid", "positive_score": 1.0, "negative_pattern": null, "match_field_attributes": ["LABEL", "NAME"], @@ -3052,68 +3052,6 @@ } ] }, - "UPI_VIRTUAL_PAYMENT_ADDRESS": { - "en": [ - { - "positive_pattern": "^[\\w.+-_]+@(\\w+\\.ifsc\\.npci|aadhaar\\.npci|mobile\\.npci|rupay\\.npci)$", - "positive_score": 0, - "negative_pattern": null, - "match_field_attributes": ["LABEL", "NAME"], - "match_field_input_types": ["TEXT"] - }, - { - "positive_pattern": "^[\\w.+-_]+@(airtel|airtelpaymentsbank|albk|allahabadbank|allbank|andb|apb|apl|axis|axisbank|axisgo|bandhan|barodampay|birla|boi|cbin|cboi|centralbank|cmsidfc|cnrb|csbcash|csbpay|cub|dbs|dcb|dcbbank|denabank|dlb|eazypay|equitas|ezeepay|fbl|federal|finobank|hdfcbank|hsbc|icici|idbi|idbibank|idfc|idfcbank|idfcnetc|ikwik|imobile|indbank|indianbank|indianbk|indus|iob|jkb|jsb|jsbp|karb|karurvysyabank|kaypay|kbl|kbl052|kmb|kmbl|kotak|kvb|kvbank|lime|lvb|lvbank|mahb|obc|okaxis|okbizaxis|okhdfcbank|okicici|oksbi|paytm|payzapp|pingpay|pnb|pockets|psb|purz|rajgovhdfcbank|rbl|sbi|sc|scb|scbl|scmobile|sib|srcb|synd|syndbank|syndicate|tjsb|tjsp|ubi|uboi|uco|unionbank|unionbankofindia|united|upi|utbi|vijayabank|vijb|vjb|ybl|yesbank|yesbankltd)$", - "positive_score": 0, - "negative_pattern": null, - "match_field_attributes": ["LABEL", "NAME"], - "match_field_input_types": ["TEXT"] - } - ] - }, - "INTERNATIONAL_BANK_ACCOUNT_NUMBER": { - "en": [ - { - "positive_pattern": "^[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}$", - "positive_score": 0, - "negative_pattern": null, - "match_field_attributes": ["LABEL", "NAME"], - "match_field_input_types": ["TEXT"] - } - ] - }, - "VALIDATION_CREDIT_CARD_VERIFICATION_CODE": { - "en": [ - { - "positive_pattern": "^\\d{3,4}$", - "positive_score": 0, - "negative_pattern": null, - "match_field_attributes": ["LABEL", "NAME"], - "match_field_input_types": ["TEXT"] - } - ] - }, - "VALIDATION_CREDIT_CARD_EXP_YEAR": { - "en": [ - { - "positive_pattern": "^[2][0][1-9][0-9]$", - "positive_score": 0, - "negative_pattern": null, - "match_field_attributes": ["LABEL", "NAME"], - "match_field_input_types": ["TEXT"] - } - ] - }, - "URL_SEARCH_ACTION": { - "en": [ - { - "positive_pattern": "/search(/|((\\w*\\.\\w+)?$))", - "positive_score": 0, - "negative_pattern": null, - "match_field_attributes": ["LABEL", "NAME"], - "match_field_input_types": ["TEXT"] - } - ] - }, "MERCHANT_PROMO_CODE": { "en": [ {
diff --git a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc index 638b7a57..12d89c2a 100644 --- a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc +++ b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
@@ -29,7 +29,6 @@ std::make_unique<TestStrikeDatabase>(); strike_database_ = test_strike_database.get(); autofill_client_.set_test_strike_database(std::move(test_strike_database)); - prefs::SetAutofillIbanEnabled(autofill_client_.GetPrefs(), true); personal_data().Init(/*profile_database=*/nullptr, /*account_database=*/nullptr, /*pref_service=*/autofill_client_.GetPrefs(),
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 16eb283..e83fe97 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -924,7 +924,8 @@ } std::string PersonalDataManager::AddIban(const Iban& iban) { - if (!IsAutofillIbanEnabled()) { + // IBAN shares the same pref with payment methods enablement toggle. + if (!IsAutofillCreditCardEnabled()) { return std::string(); } @@ -1655,8 +1656,7 @@ } bool PersonalDataManager::IsAutofillEnabled() const { - return IsAutofillProfileEnabled() || IsAutofillCreditCardEnabled() || - IsAutofillIbanEnabled(); + return IsAutofillProfileEnabled() || IsAutofillCreditCardEnabled(); } bool PersonalDataManager::IsAutofillProfileEnabled() const { @@ -1675,10 +1675,6 @@ prefs::SetAutofillHasSeenIban(pref_service_); } -bool PersonalDataManager::IsAutofillIbanEnabled() const { - return prefs::IsAutofillIbanEnabled(pref_service_); -} - bool PersonalDataManager::IsAutofillWalletImportEnabled() const { if (is_syncing_for_test_) { return true;
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index ddb97b70..3f7f64e 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -554,9 +554,6 @@ // Sets the value of the kAutofillHasSeenIban pref to true. void SetAutofillHasSeenIban(); - // Returns the value of the AutofillIbanEnabled pref. - virtual bool IsAutofillIbanEnabled() const; - // Returns whether sync's integration with payments is on. virtual bool IsAutofillWalletImportEnabled() const;
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index ab4971ae..9b84a297 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -1005,7 +1005,8 @@ #endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) TEST_F(PersonalDataManagerTest, NoIbansAddedIfDisabled) { - prefs::SetAutofillIbanEnabled(prefs_.get(), false); + prefs::SetAutofillCreditCardEnabled(prefs_.get(), false); + personal_data_->AddIban(autofill::test::GetIban()); personal_data_->AddIban(autofill::test::GetIban2()); @@ -1013,7 +1014,6 @@ } TEST_F(PersonalDataManagerTest, AddingIbanUpdatesPref) { - prefs::SetAutofillIbanEnabled(prefs_.get(), true); // The pref should always start disabled. ASSERT_FALSE(personal_data_->IsAutofillHasSeenIbanPrefEnabled()); Iban iban = test::GetIban(); @@ -1025,7 +1025,6 @@ } TEST_F(PersonalDataManagerTest, AddUpdateRemoveIbans) { - prefs::SetAutofillIbanEnabled(prefs_.get(), true); Iban iban0 = autofill::test::GetIban(); Iban iban1 = autofill::test::GetIban2(); @@ -1095,8 +1094,6 @@ // Ensure that new IBANs can be updated and saved via // `OnAcceptedLocalIbanSave()`. TEST_F(PersonalDataManagerTest, OnAcceptedLocalIbanSave) { - prefs::SetAutofillIbanEnabled(prefs_.get(), true); - // Start with a new IBAN. Iban iban0 = autofill::test::GetIban(); // Add the IBAN to the database. @@ -2028,7 +2025,6 @@ // profiles. prefs::SetAutofillProfileEnabled(prefs_.get(), false); prefs::SetAutofillCreditCardEnabled(prefs_.get(), false); - prefs::SetAutofillIbanEnabled(prefs_.get(), false); PersonalDataProfileTaskWaiter(*personal_data_).Wait(); EXPECT_EQ(default_country, personal_data_->GetDefaultCountryCodeForNewAddress());
diff --git a/components/autofill/core/common/autofill_prefs.cc b/components/autofill/core/common/autofill_prefs.cc index 5ed7852..71b6158 100644 --- a/components/autofill/core/common/autofill_prefs.cc +++ b/components/autofill/core/common/autofill_prefs.cc
@@ -155,9 +155,6 @@ prefs::kAutofillCreditCardEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref( - prefs::kAutofillIbanEnabled, true, - user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); - registry->RegisterBooleanPref( prefs::kAutofillPaymentCvcStorage, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); @@ -192,6 +189,7 @@ prefs::kAutofillEnabledDeprecated, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref(prefs::kAutofillOrphanRowsRemoved, false); + registry->RegisterBooleanPref(prefs::kAutofillIbanEnabled, true); #if BUILDFLAG(IS_ANDROID) registry->RegisterBooleanPref(prefs::kAutofillUsingVirtualViewStructure, @@ -204,6 +202,8 @@ pref_service->ClearPref(prefs::kAutofillEnabledDeprecated); // Added 05/2023. pref_service->ClearPref(prefs::kAutofillOrphanRowsRemoved); + // Added 09/2023. + pref_service->ClearPref(prefs::kAutofillIbanEnabled); } bool IsAutocompleteEnabled(const PrefService* prefs) { @@ -236,14 +236,6 @@ prefs->SetBoolean(kAutofillHasSeenIban, true); } -bool IsAutofillIbanEnabled(const PrefService* prefs) { - return prefs->GetBoolean(kAutofillIbanEnabled); -} - -void SetAutofillIbanEnabled(PrefService* prefs, bool enabled) { - prefs->SetBoolean(kAutofillIbanEnabled, enabled); -} - bool IsAutofillManaged(const PrefService* prefs) { return prefs->IsManagedPreference(kAutofillEnabledDeprecated); }
diff --git a/components/autofill/core/common/autofill_prefs.h b/components/autofill/core/common/autofill_prefs.h index ddbdd4b..4bc7e85 100644 --- a/components/autofill/core/common/autofill_prefs.h +++ b/components/autofill/core/common/autofill_prefs.h
@@ -25,8 +25,7 @@ #if BUILDFLAG(IS_ANDROID) extern const char kAutofillCreditCardFidoAuthOfferCheckboxState[]; #endif // BUILDFLAG(IS_ANDROID) -// Please use kAutofillCreditCardEnabled, kAutofillIbanEnabled and -// kAutofillProfileEnabled instead. +// Please use kAutofillCreditCardEnabled and kAutofillProfileEnabled instead. extern const char kAutofillEnabledDeprecated[]; extern const char kAutofillHasSeenIban[]; extern const char kAutofillIbanEnabled[];
diff --git a/components/autofill/core/common/autofill_regex_constants.h b/components/autofill/core/common/autofill_regex_constants.h index a551f56..bcec7a4 100644 --- a/components/autofill/core/common/autofill_regex_constants.h +++ b/components/autofill/core/common/autofill_regex_constants.h
@@ -46,13 +46,13 @@ u"(house.?|street.?|^)(number|no\\.?$)" // en u"|(haus|^)(nummer|nr)" // de u"|^\\*?.?número(.?\\*?$| da residência)" // pt-BR, pt-PT - u"|дом|номер.?дома" // ru - u"|exterior"; // es-MX + u"|exterior" // es + u"|дом|номер.?дома"; // ru inline constexpr char16_t kApartmentNumberRe[] = u"apartment" // en u"|interior|departamento" // es-MX u"|n(u|ú)mero.*app?art(a|e)ment" // es,fr,it - u"|Wohnung" // de + u"|wohnung" // de u"|квартир"; // ru inline constexpr char16_t kAddressLine1Re[] = u"^address$|address[_-]?line(one)?|address1|addr1|street" @@ -508,6 +508,27 @@ u"|便名|航空会社"; // ja-JP ///////////////////////////////////////////////////////////////////////////// +// iban_field.cc +///////////////////////////////////////////////////////////////////////////// +// Used to match the HTML name and label for International Bank Account Number +// (IBAN). +inline constexpr char16_t kIbanRe[] = + u"(\\biban(\\b|_)|international bank account number)"; + +///////////////////////////////////////////////////////////////////////////// +// merchant_promo_code_field.cc +///////////////////////////////////////////////////////////////////////////// +// "promo code", "promotion code", "promotional code" are all acceptable +// keywords. +inline constexpr char16_t kMerchantPromoCodeRe[] = + u"(promo(tion|tional)?|gift|discount|coupon)[-_. ]*code"; + +///////////////////////////////////////////////////////////////////////////// +// All regexes below this point are non-parsing related and thus don't have a +// JSON based definition. +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// // validation.cc ///////////////////////////////////////////////////////////////////////////// @@ -630,11 +651,6 @@ u"yesbankltd" u")$"; -// Used to match the HTML name and label for International Bank Account Number -// (IBAN). -inline constexpr char16_t kIbanRe[] = - u"(\\biban(\\b|_)|international bank account number)"; - // Used to match field value that might be an International Bank Account Number. // TODO(crbug.com/977377): The regex doesn't match IBANs for Saint Lucia (LC), // Kazakhstan (KZ) and Romania (RO). Consider replace the regex with something @@ -663,15 +679,6 @@ inline constexpr char16_t kUrlSearchActionRe[] = u"/search(/|((\\w*\\.\\w+)?$))"; -///////////////////////////////////////////////////////////////////////////// -// merchant_promo_code_field.cc -///////////////////////////////////////////////////////////////////////////// -// "promo code", "promotion code", "promotional code" are all acceptable -// keywords. -inline constexpr char16_t kMerchantPromoCodeRe[] = - u"(promo(tion|tional)?|gift|discount|coupon)[-_. ]*code"; - - } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_REGEX_CONSTANTS_H_
diff --git a/components/browser_ui/bottomsheet/android/internal/BUILD.gn b/components/browser_ui/bottomsheet/android/internal/BUILD.gn index 63810fc4..2bebcca 100644 --- a/components/browser_ui/bottomsheet/android/internal/BUILD.gn +++ b/components/browser_ui/bottomsheet/android/internal/BUILD.gn
@@ -9,7 +9,6 @@ ":*", "../test:*", "//chrome/android:chrome_all_java", - "//weblayer/browser/java:java", ] sources = [
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index 93bc38c..df75a72a 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "24.40", - "log_list_timestamp": "2023-09-18T12:55:42Z", + "version": "25.1", + "log_list_timestamp": "2023-09-19T12:54:42Z", "operators": [ { "name": "Google", @@ -41,6 +41,38 @@ } }, { + "description": "Google 'Argon2025h1' log", + "log_id": "TnWjJ1yaEMM4W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIIKh+WdoqOTblJji4WiH5AltIDUzODyvFKrXCBjw/Rab0/98J4LUh7dOJEY7+66+yCNSICuqRAX+VPnV8R1Fmg==", + "url": "https://ct.googleapis.com/logs/us1/argon2025h1/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-01-01T00:00:00Z", + "end_exclusive": "2025-07-01T00:00:00Z" + } + }, + { + "description": "Google 'Argon2025h2' log", + "log_id": "EvFONL1TckyEBhnDjz96E/jntWKHiJxtMAWE6+WGJjo=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEr+TzlCzfpie1/rJhgxnIITojqKk9VK+8MZoc08HjtsLzD8e5yjsdeWVhIiWCVk6Y6KomKTYeKGBv6xVu93zQug==", + "url": "https://ct.googleapis.com/logs/us1/argon2025h2/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-07-01T00:00:00Z", + "end_exclusive": "2026-01-01T00:00:00Z" + } + }, + { "description": "Google 'Xenon2023' log", "log_id": "rfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgoo=", "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEchY+C+/vzj5g3ZXLY3q5qY1Kb2zcYYCmRV4vg6yU84WI0KV00HuO/8XuQqLwLZPjwtCymeLhQunSxgAnaXSuzg==", @@ -71,6 +103,38 @@ "start_inclusive": "2024-01-01T00:00:00Z", "end_exclusive": "2025-01-01T00:00:00Z" } + }, + { + "description": "Google 'Xenon2025h1' log", + "log_id": "zxFW7tUufK/zh1vZaS6b6RpxZ0qwF+ysAdJbd87MOwg=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEguLOkEA/gQ7f6uEgK14uMFRGgblY7a+9/zanngtfamuRpcGY4fLN6xcgcMoqEuZUeFDc/239HKe2Oh/5JqkbvQ==", + "url": "https://ct.googleapis.com/logs/eu1/xenon2025h1/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-01-01T00:00:00Z", + "end_exclusive": "2025-07-01T00:00:00Z" + } + }, + { + "description": "Google 'Xenon2025h2' log", + "log_id": "3dzKNJXX4RYF55Uy+sef+D0cUN/bADoUEnYKLKy7yCo=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEa+Cv7QZ8Pe/ZDuRYSwTYKkeZkIl6uTaldcgEuMviqiu1aJ2IKaKlz84rmhWboD6dlByyt0ryUexA7WJHpANJhg==", + "url": "https://ct.googleapis.com/logs/eu1/xenon2025h2/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-07-01T00:00:00Z", + "end_exclusive": "2026-01-01T00:00:00Z" + } } ] }, @@ -240,6 +304,70 @@ } }, { + "description": "Sectigo 'Sabre2024h1'", + "log_id": "ouK/1h7eLy8HoNZObTen3GVDsMa1LqLat4r4mm31F9g=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELAH2zjG8qhRhUf5reoeuptObx4ctClrIT7VU3MmToADuyhy5p7Z7RzvlT6psFhxwLsjsU1pMIUx+JwsTFF78hQ==", + "url": "https://sabre2024h1.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2024-01-01T00:00:00Z", + "end_exclusive": "2024-07-01T00:00:00Z" + } + }, + { + "description": "Sectigo 'Sabre2024h2'", + "log_id": "GZgQcQnw1lIuMIDSnj9ku4NuKMz5D1KO7t/OSj8WtMo=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEehBMiucie20quo76a0qB1YWuA+//S/xNUz23jLt1CcnqFn7BdxbSwkV0bY3E4Yg339TzYGX8oHXwIGaOSswZ2g==", + "url": "https://sabre2024h2.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2024-07-01T00:00:00Z", + "end_exclusive": "2025-01-01T00:00:00Z" + } + }, + { + "description": "Sectigo 'Sabre2025h1'", + "log_id": "4JKz/AwdyOdoNh/eYbmWTQpSeBmKctZyxLBNpW1vVAQ=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfi858egjjrMyBK9NV/bbxXSkem07B1EMWvuAMAXGWgzEdtYGqFdN+9/kgpDCQa5wszGi4/o9XyxdBM20nVWrQQ==", + "url": "https://sabre2025h1.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-01-01T00:00:00Z", + "end_exclusive": "2025-07-01T00:00:00Z" + } + }, + { + "description": "Sectigo 'Sabre2025h2'", + "log_id": "GgT/SdBUHUCv9qDDv/HYxGcvTuzuI0BomGsXQC7ciX0=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhRMRLXvzk4HkuXzZZDvntYOZZnlZR2pCXta9Yy63kUuuvFbExW4JoNdkGsjBr4mL9VjYuut7g1Lp9OClzc2SzA==", + "url": "https://sabre2025h2.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-07-01T00:00:00Z", + "end_exclusive": "2026-01-01T00:00:00Z" + } + }, + { "description": "Sectigo 'Mammoth' CT log", "log_id": "b1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RM=", "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7+R9dC4VFbbpuyOL+yy14ceAmEf7QGlo/EmtYU6DRzwat43f/3swtLr/L8ugFOOt1YU/RFmMjGCL17ixv66MZw==", @@ -250,6 +378,70 @@ "timestamp": "2023-01-15T00:00:00Z" } } + }, + { + "description": "Sectigo 'Mammoth2024h1'", + "log_id": "KdA6G7Z0qnEc0wNbZVfBT4qni0/oOJRJ7KRT+US9JGg=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpFmQ83EkJPfDVSdWnKNZHve3n86rThlmTdCK+p1ipCTwOyDkHRRnyPzkN/JLOFRaz59rB5DQDn49TIey6D8HzA==", + "url": "https://mammoth2024h1.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2024-01-01T00:00:00Z", + "end_exclusive": "2024-07-01T00:00:00Z" + } + }, + { + "description": "Sectigo 'Mammoth2024h2'", + "log_id": "3+FW66oFr7WcD4ZxjajAMk6uVtlup/WlagHRwTu+Ulw=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhWYiJG6+UmIKoK/DJRo2LqdgiaJlv6RfvYVqlAWBNZBUMZXnEZ6jLg+F76eIV4tjGoHBQZ197AE627nBJ/RlHg==", + "url": "https://mammoth2024h2.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2024-07-01T00:00:00Z", + "end_exclusive": "2025-01-01T00:00:00Z" + } + }, + { + "description": "Sectigo 'Mammoth2025h1'", + "log_id": "E0rfGrWYQgl4DG/vTHqRpBa3I0nOWFdq367ap8Kr4CI=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEzxBtTB9LkqhqGvSxVdrmP5+79Uh4rpdsLqFEW6U4D2ojm1WjUQCnrCDzFTfm05yYks8DDLdhvvrPmbNd1hb5Q==", + "url": "https://mammoth2025h1.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-01-01T00:00:00Z", + "end_exclusive": "2025-07-01T00:00:00Z" + } + }, + { + "description": "Sectigo 'Mammoth2025h2'", + "log_id": "rxgaKNaMo+CpikycZ6sJ+Lu8IrquvLE4o6Gd0/m2Aw0=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiOLHs9c3o5HXs8XaB1EEK4HtwkQ7daDmZeFKuhuxnKkqhDEprh2L8TOfEi6QsRVnZqB8C1tif2yaajCbaAIWbw==", + "url": "https://mammoth2025h2.ct.sectigo.com/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-07-01T00:00:00Z", + "end_exclusive": "2026-01-01T00:00:00Z" + } } ] }, @@ -306,6 +498,38 @@ "start_inclusive": "2024-06-20T00:00:00Z", "end_exclusive": "2025-01-20T00:00:00Z" } + }, + { + "description": "Let's Encrypt 'Oak2025h1'", + "log_id": "ouMK5EXvva2bfjjtR2d3U9eCW4SU1yteGyzEuVCkR+c=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKeBpU9ejnCaIZeX39EsdF5vDvf8ELTHdLPxikl4y4EiROIQfS4ercpnMHfh8+TxYVFs3ELGr2IP7hPGVPy4vHA==", + "url": "https://oak.ct.letsencrypt.org/2025h1/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2024-12-20T00:00:00Z", + "end_exclusive": "2025-07-20T00:00:00Z" + } + }, + { + "description": "Let's Encrypt 'Oak2025h2'", + "log_id": "DeHyMCvTDcFAYhIJ6lUu/Ed0fLHX6TDvDkIetH5OqjQ=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtXYwB63GyNLkS9L1vqKNnP10+jrW+lldthxg090fY4eG40Xg1RvANWqrJ5GVydc9u8H3cYZp9LNfkAmqrr2NqQ==", + "url": "https://oak.ct.letsencrypt.org/2025h2/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-06-20T00:00:00Z", + "end_exclusive": "2026-01-20T00:00:00Z" + } } ] }, @@ -346,6 +570,38 @@ "start_inclusive": "2024-01-01T00:00:00Z", "end_exclusive": "2025-01-01T00:00:00Z" } + }, + { + "description": "TrustAsia Log2025a", + "log_id": "KOKBOP2DIUXpqdaqdTdtg3eohRKzwH9yQUgh3L3pjGY=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcOWxpAl5K534o6DfGO+VXQNse6GRqbiAfexcAgjibi98MnC9loRfpmLpZbV8kFi6ItX59WlUt6iUTjIJriYRTQ==", + "url": "https://ct2025-a.trustasia.com/log2025a/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-01-01T00:00:00Z", + "end_exclusive": "2026-01-01T00:00:00Z" + } + }, + { + "description": "TrustAsia Log2025b", + "log_id": "KCyL3YEP+QkSCs4W1uDsIBvqgqOkrxnZ7/tZ6D/cQmg=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqqCL22cUXZeJHQiNBtfBlI6w+kxG1VMIeCsEU2zz3rHRU0DakFfmGp48xwO4vS+pz+h7XuFLYOU4Q2CXwVsvZQ==", + "url": "https://ct2025-b.trustasia.com/log2025b/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2023-09-15T23:09:45Z" + } + }, + "temporal_interval": { + "start_inclusive": "2025-01-01T00:00:00Z", + "end_exclusive": "2026-01-01T00:00:00Z" + } } ] }
diff --git a/components/commerce/core/commerce_feature_list.cc b/components/commerce/core/commerce_feature_list.cc index c6b276e..6a3181b 100644 --- a/components/commerce/core/commerce_feature_list.cc +++ b/components/commerce/core/commerce_feature_list.cc
@@ -113,6 +113,10 @@ const char kEnableChromeCart[] = "enable-chrome-cart"; } // namespace switches +BASE_FEATURE(kCommerceAllowChipExpansion, + "CommerceAllowChipExpansion", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kCommerceAllowLocalImages, "CommerceAllowLocalImages", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/commerce/core/commerce_feature_list.h b/components/commerce/core/commerce_feature_list.h index a84f2d1..6ec8295 100644 --- a/components/commerce/core/commerce_feature_list.h +++ b/components/commerce/core/commerce_feature_list.h
@@ -78,6 +78,7 @@ {"Price Tracking Notifications", kCommercePriceTrackingNotifications, std::size(kCommercePriceTrackingNotifications), nullptr}}; +BASE_DECLARE_FEATURE(kCommerceAllowChipExpansion); BASE_DECLARE_FEATURE(kCommerceAllowLocalImages); BASE_DECLARE_FEATURE(kCommerceAllowOnDemandBookmarkUpdates); BASE_DECLARE_FEATURE(kCommerceAllowOnDemandBookmarkBatchUpdates);
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc index 527fbea..77ef943 100644 --- a/components/download/internal/common/download_item_impl.cc +++ b/components/download/internal/common/download_item_impl.cc
@@ -2000,14 +2000,6 @@ } } - // TODO(crbug.com/1372476): Remove these histograms after debugging. - if (!IsTemporary()) { - base::UmaHistogramBoolean("Download.Complete.IsOpenWhenCompleteSet", - GetOpenWhenComplete()); - base::UmaHistogramBoolean( - "Download.Complete.IsShouldOpenFileBasedOnExtensionSet", - ShouldOpenFileBasedOnExtension()); - } if (auto_opened_) { // If it was already handled by the delegate, do nothing. } else if (GetOpenWhenComplete() || ShouldOpenFileBasedOnExtension() ||
diff --git a/components/exo/pointer_unittest.cc b/components/exo/pointer_unittest.cc index 5f37d94..a258ae4a 100644 --- a/components/exo/pointer_unittest.cc +++ b/components/exo/pointer_unittest.cc
@@ -815,13 +815,13 @@ TEST_P(PointerTest, RegisterPointerEventsOnModal) { // Create modal surface. auto shell_surface = test::ShellSurfaceBuilder({5, 5}) + .SetCentered() .SetCanMinimize(false) .SetUseSystemModalContainer() .SetDisableMovement() .BuildShellSurface(); auto* surface = shell_surface->surface_for_testing(); - ash::CenterWindow(shell_surface->GetWidget()->GetNativeWindow()); // Make the window modal. shell_surface->SetSystemModal(true); EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen()); @@ -868,13 +868,13 @@ // Create surface for modal window. auto shell_surface2 = test::ShellSurfaceBuilder({5, 5}) + .SetCentered() .SetCanMinimize(false) .SetUseSystemModalContainer() .SetDisableMovement() .BuildShellSurface(); auto* surface2 = shell_surface->surface_for_testing(); - ash::CenterWindow(shell_surface2->GetWidget()->GetNativeWindow()); // Make the window modal. shell_surface2->SetSystemModal(true); EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen()); @@ -927,13 +927,13 @@ TEST_P(PointerTest, IgnorePointerLeaveOnModal) { // Create modal surface. auto shell_surface = test::ShellSurfaceBuilder({5, 5}) + .SetCentered() .SetCanMinimize(false) .SetUseSystemModalContainer() .SetDisableMovement() .BuildShellSurface(); auto* surface = shell_surface->surface_for_testing(); - ash::CenterWindow(shell_surface->GetWidget()->GetNativeWindow()); // Make the window modal. shell_surface->SetSystemModal(true); EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen()); @@ -972,14 +972,13 @@ // Create another surface for a non-modal window. auto shell_surface2 = test::ShellSurfaceBuilder({5, 5}) + .SetCentered() .SetCanMinimize(false) .SetUseSystemModalContainer() .SetDisableMovement() .BuildShellSurface(); auto* surface2 = shell_surface2->surface_for_testing(); - ash::CenterWindow(shell_surface2->GetWidget()->GetNativeWindow()); - MockPointerDelegate delegate; Seat seat; std::unique_ptr<Pointer> pointer(new Pointer(&delegate, &seat));
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 15e24f0c..354832f 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -25,6 +25,7 @@ #include "base/containers/flat_set.h" #include "base/logging.h" #include "base/memory/raw_ptr.h" +#include "base/notreached.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/traced_value.h" @@ -647,15 +648,13 @@ } void ShellSurfaceBase::UnsetPip() { - if (!widget_) { - pending_pip_ = false; - return; - } - - // Set all the necessary window properties and window state. - auto* window = widget_->GetNativeWindow(); - window->SetProperty(ash::kWindowPipTypeKey, false); - window->SetProperty(aura::client::kZOrderingKey, ui::ZOrderLevel::kNormal); + // Ash does not implement restoring the pip state. Additionally it does not + // make sense for browser pip window to unset pip since the browser(lacros) + // creates a separate window for a pip and once pip is not needed, + // the window is destroyed rather than restoring it to some other state. + // However, ClientControlledShellSurface(Arc++), has a concept of restoring + // from pip state and implements UnsetPip. + NOTIMPLEMENTED(); } void ShellSurfaceBase::SetFloatToLocation(
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc index 77ab90eb..f171074 100644 --- a/components/exo/surface_unittest.cc +++ b/components/exo/surface_unittest.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/functional/bind.h" +#include "base/memory/raw_ref.h" #include "base/strings/stringprintf.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" @@ -1011,7 +1012,7 @@ struct TransformTestcase { Transform transform; - const SkRect& expected_rect; + const raw_ref<const SkRect> expected_rect; constexpr TransformTestcase(Transform transform_in, const SkRect& expected_rect_in) @@ -1031,7 +1032,7 @@ for (const auto& tc : testcases) { SetCropAndBufferTransformHelperTransformAndTest( surface.get(), shell_surface.get(), tc.transform, - gfx::SkRectToRectF(tc.expected_rect), false); + gfx::SkRectToRectF(*tc.expected_rect), false); } surface->SetViewport(gfx::SizeF(128, 64)); @@ -1039,7 +1040,7 @@ for (const auto& tc : testcases) { SetCropAndBufferTransformHelperTransformAndTest( surface.get(), shell_surface.get(), tc.transform, - gfx::SkRectToRectF(tc.expected_rect), true); + gfx::SkRectToRectF(*tc.expected_rect), true); } }
diff --git a/components/exo/test/shell_surface_builder.cc b/components/exo/test/shell_surface_builder.cc index 4aecdc5..7b206fe 100644 --- a/components/exo/test/shell_surface_builder.cc +++ b/components/exo/test/shell_surface_builder.cc
@@ -8,7 +8,6 @@ #include "ash/constants/app_types.h" #include "ash/wm/desks/desks_util.h" -#include "ash/wm/window_positioning_utils.h" #include "base/memory/raw_ptr.h" #include "components/exo/buffer.h" #include "components/exo/display.h" @@ -498,8 +497,14 @@ if (commit_on_build_) { shell_surface->root_surface()->Commit(); - if (centered_) - ash::CenterWindow(shell_surface->GetWidget()->GetNativeWindow()); + if (centered_) { + auto* window = shell_surface->GetWidget()->GetNativeWindow(); + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(window); + gfx::Rect center_bounds = display.work_area(); + center_bounds.ClampToCenteredSize(window->bounds().size()); + window->SetBoundsInScreen(center_bounds, display); + } } else { // 'SetCentered' requires its shell surface to be committed when creatted. DCHECK(!centered_);
diff --git a/components/exo/wayland/protocol/chrome-color-management.xml b/components/exo/wayland/protocol/chrome-color-management.xml index c953f96..7d01661 100644 --- a/components/exo/wayland/protocol/chrome-color-management.xml +++ b/components/exo/wayland/protocol/chrome-color-management.xml
@@ -43,7 +43,7 @@ over the course of our development. </description> - <interface name="zcr_color_manager_v1" version="5"> + <interface name="zcr_color_manager_v1" version="6"> <description summary="color manager singleton"> A global interface used for getting color management surface and color management output objects as well as creating color space objects from @@ -81,6 +81,7 @@ <entry name="scrgb_linear_80_nits" value="18" summary="SCRGB Linear transfer function" since="5"/> <entry name="gamma18" value="19" summary="GAMMA18 transfer function" since="5"/> <entry name="gamma28" value="20" summary="GAMMA28 transfer function" since="5"/> + <entry name="srgb_hdr" value="21" summary="sRGB transfer function" since="6"/> </enum> <enum name="chromaticity_names">
diff --git a/components/exo/wayland/zcr_color_manager.h b/components/exo/wayland/zcr_color_manager.h index b8bac8c7..13bb02d 100644 --- a/components/exo/wayland/zcr_color_manager.h +++ b/components/exo/wayland/zcr_color_manager.h
@@ -12,7 +12,7 @@ namespace exo { namespace wayland { -constexpr uint32_t kZcrColorManagerVersion = 5; +constexpr uint32_t kZcrColorManagerVersion = 6; void bind_zcr_color_manager(wl_client* client, void* data,
diff --git a/components/external_intents/README.md b/components/external_intents/README.md index e0cfda9..46a52f8d 100644 --- a/components/external_intents/README.md +++ b/components/external_intents/README.md
@@ -192,17 +192,11 @@ To embed the component, it's necessary to install InterceptNavigationDelegateImpl for each "tab" of the embedder (where a tab is -the embedder-level object that holds a WebContents). For an example of a -relatively straightforward embedding, look at //weblayer's creation of -InterceptNavigationDelegateImpl. +the embedder-level object that holds a WebContents). There are two interfaces that the embedder must implement in order to embed the component: InterceptNavigationDelegateClient and ExternalNavigationDelegate. -Again, //weblayer's implementation of these interfaces provides a good starting -point to follow. //chrome's implementations are significantly more complex for -several reasons: handling of differences between Chrome browser and Chrome -Custom Tabs, integration with handling of incoming intents, an extended set -of use cases, .... + # Differences between Chrome and WebLayer Embedding
diff --git a/components/heavy_ad_intervention/heavy_ad_helper.cc b/components/heavy_ad_intervention/heavy_ad_helper.cc index df08a49..0c457a6 100644 --- a/components/heavy_ad_intervention/heavy_ad_helper.cc +++ b/components/heavy_ad_intervention/heavy_ad_helper.cc
@@ -19,12 +19,6 @@ namespace heavy_ad_intervention { -// NOTE: If adding usage of more strings/resources here, make sure that they -// are allowlisted in //weblayer/grit_{resources, strings}_allowlist.txt; -// otherwise empty data will be used for the new resources/strings in WebLayer. -// For strings there is a partial safeguard as //weblayer's integration tests -// will crash if a new-but-not-allowlisted string is fetched in a codepath that -// the presentation of the heavy ad page in those tests exercises. std::string PrepareHeavyAdPage(const std::string& application_locale) { int resource_id = IDR_SECURITY_INTERSTITIAL_QUIET_HTML; std::string uncompressed;
diff --git a/components/keyed_service/core/keyed_service_base_factory.h b/components/keyed_service/core/keyed_service_base_factory.h index 1f92330..281d049 100644 --- a/components/keyed_service/core/keyed_service_base_factory.h +++ b/components/keyed_service/core/keyed_service_base_factory.h
@@ -27,8 +27,7 @@ // created in order to work correctly (see crbug.com/1150733). The standard way // to do this in a //content-based embedder is to call FooFactory::GetInstance() // for each factory used by your embedder from your embedder's implementation of -// content::BrowserMainParts::PreMainMessageLoopRun(). See //weblayer's -// browser_main_parts_impl.cc for a straightforward example. +// content::BrowserMainParts::PreMainMessageLoopRun(). class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory : public DependencyNode { public: // The type is used to determine whether a service can depend on another.
diff --git a/components/media_router/browser/android/media_router_android.cc b/components/media_router/browser/android/media_router_android.cc index 9b4dac14..fd95c40 100644 --- a/components/media_router/browser/android/media_router_android.cc +++ b/components/media_router/browser/android/media_router_android.cc
@@ -111,8 +111,7 @@ const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) { + base::TimeDelta timeout) { DCHECK(callback); // TODO(avayvod): Implement timeouts (crbug.com/583036). std::string presentation_id = MediaRouterBase::CreatePresentationId(); @@ -129,8 +128,7 @@ const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) { + base::TimeDelta timeout) { DCHECK(callback); // TODO(avayvod): Implement timeouts (crbug.com/583036). DVLOG(2) << "JoinRoute: " << source_id << ", " << presentation_id << ", "
diff --git a/components/media_router/browser/android/media_router_android.h b/components/media_router/browser/android/media_router_android.h index e992b98..68ef9bb 100644 --- a/components/media_router/browser/android/media_router_android.h +++ b/components/media_router/browser/android/media_router_android.h
@@ -36,15 +36,13 @@ const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) override; + base::TimeDelta timeout) override; void JoinRoute(const MediaSource::Id& source, const std::string& presentation_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) override; + base::TimeDelta timeout) override; void DetachRoute(MediaRoute::Id route_id) override; void TerminateRoute(const MediaRoute::Id& route_id) override; void SendRouteMessage(const MediaRoute::Id& route_id,
diff --git a/components/media_router/browser/android/media_router_android_unittest.cc b/components/media_router/browser/android/media_router_android_unittest.cc index 5690eff..79398d2 100644 --- a/components/media_router/browser/android/media_router_android_unittest.cc +++ b/components/media_router/browser/android/media_router_android_unittest.cc
@@ -87,7 +87,7 @@ .WillOnce(Return()); router_->CreateRoute("source", "sink", url::Origin(), nullptr, - base::DoNothing(), base::TimeDelta(), false); + base::DoNothing(), base::TimeDelta()); router_->OnRouteCreated("route", "sink", 1, false); EXPECT_NE(nullptr, router_->FindRouteBySource("source")); @@ -106,7 +106,7 @@ .WillOnce(Return()); router_->CreateRoute("source", "sink", url::Origin(), nullptr, - base::DoNothing(), base::TimeDelta(), false); + base::DoNothing(), base::TimeDelta()); router_->OnRouteCreated("route", "sink", 1, false); EXPECT_NE(nullptr, router_->FindRouteBySource("source")); @@ -135,7 +135,7 @@ .WillOnce(Return()); router_->CreateRoute("source", "sink", url::Origin(), nullptr, - base::DoNothing(), base::TimeDelta(), false); + base::DoNothing(), base::TimeDelta()); router_->OnRouteCreated("route", "sink", 1, false); EXPECT_NE(nullptr, router_->FindRouteBySource("source")); @@ -163,7 +163,7 @@ .WillOnce(Return()); router_->CreateRoute("source", "sink", url::Origin(), nullptr, - base::DoNothing(), base::TimeDelta(), false); + base::DoNothing(), base::TimeDelta()); router_->OnRouteCreated("route", "sink", 1, false); EXPECT_NE(nullptr, router_->FindRouteBySource("source")); @@ -188,7 +188,7 @@ .WillOnce(Return()); router_->CreateRoute(source_id, sink_id, origin, nullptr, base::DoNothing(), - base::TimeDelta(), false); + base::TimeDelta()); router_->OnRouteCreated(route_id, sink_id, 1, false); EXPECT_NE(nullptr, router_->FindRouteBySource(source_id));
diff --git a/components/media_router/browser/android/media_router_dialog_controller_android.cc b/components/media_router/browser/android/media_router_dialog_controller_android.cc index 9033607e..ae1390e5 100644 --- a/components/media_router/browser/android/media_router_dialog_controller_android.cc +++ b/components/media_router/browser/android/media_router_dialog_controller_android.cc
@@ -71,7 +71,7 @@ presentation_request.frame_origin, initiator(), base::BindOnce(&StartPresentationContext::HandleRouteResponse, std::move(start_presentation_context)), - base::TimeDelta(), browser_context->IsOffTheRecord()); + base::TimeDelta()); MediaRouterMetrics::RecordMediaRouterAndroidDialogAction( MediaRouterAndroidDialogAction::kStartRoute); }
diff --git a/components/media_router/browser/media_router.h b/components/media_router/browser/media_router.h index 41e55bc..902bc4a 100644 --- a/components/media_router/browser/media_router.h +++ b/components/media_router/browser/media_router.h
@@ -89,14 +89,12 @@ // success or failure, in the order they are listed. // If |timeout| is positive, then any un-invoked |callbacks| will be invoked // with a timeout error after the timeout expires. - // If |incognito| is true, the request was made by an incognito profile. virtual void CreateRoute(const MediaSource::Id& source_id, const MediaSink::Id& sink_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) = 0; + base::TimeDelta timeout) = 0; // Joins an existing route identified by |presentation_id|. // |source|: The source to route to the existing route. @@ -108,14 +106,12 @@ // success or failure, in the order they are listed. // If |timeout| is positive, then any un-invoked |callbacks| will be invoked // with a timeout error after the timeout expires. - // If |incognito| is true, the request was made by an incognito profile. virtual void JoinRoute(const MediaSource::Id& source, const std::string& presentation_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) = 0; + base::TimeDelta timeout) = 0; // Terminates the media route specified by |route_id|. virtual void TerminateRoute(const MediaRoute::Id& route_id) = 0;
diff --git a/components/media_router/browser/mirroring_to_flinging_switcher.cc b/components/media_router/browser/mirroring_to_flinging_switcher.cc index 4dc1ff1..c03d19d 100644 --- a/components/media_router/browser/mirroring_to_flinging_switcher.cc +++ b/components/media_router/browser/mirroring_to_flinging_switcher.cc
@@ -43,15 +43,13 @@ const auto source_id = MediaSource::ForPresentationUrl(presentation_request.presentation_urls[0]) .id(); - bool incognito = web_contents->GetBrowserContext()->IsOffTheRecord(); - media_router->JoinRoute( source_id, kAutoJoinPresentationId, presentation_request.frame_origin, web_contents, base::BindOnce(&WebContentsPresentationManager::OnPresentationResponse, std::move(web_contents_presentation_manager), presentation_request), - base::TimeDelta(), incognito); + base::TimeDelta()); } } // namespace media_router
diff --git a/components/media_router/browser/mirroring_to_flinging_switcher_unittest.cc b/components/media_router/browser/mirroring_to_flinging_switcher_unittest.cc index 4b0b947..9d65e6a 100644 --- a/components/media_router/browser/mirroring_to_flinging_switcher_unittest.cc +++ b/components/media_router/browser/mirroring_to_flinging_switcher_unittest.cc
@@ -128,12 +128,10 @@ const auto source_id = MediaSource::ForPresentationUrl(presentation_request.presentation_urls[0]) .id(); - bool incognito = web_contents_->GetBrowserContext()->IsOffTheRecord(); - EXPECT_CALL( - *media_router_, - JoinRouteInternal(source_id, kAutoJoinPresentationId, - presentation_request.frame_origin, web_contents_.get(), - _, base::TimeDelta(), incognito)); + EXPECT_CALL(*media_router_, + JoinRouteInternal(source_id, kAutoJoinPresentationId, + presentation_request.frame_origin, + web_contents_.get(), _, base::TimeDelta())); // Switch to flinging request is expected to be sent. SwitchToFlingingIfPossible(GetNewTabSource());
diff --git a/components/media_router/browser/presentation/local_presentation_manager_factory.h b/components/media_router/browser/presentation/local_presentation_manager_factory.h index 13fd0e0..45335ea 100644 --- a/components/media_router/browser/presentation/local_presentation_manager_factory.h +++ b/components/media_router/browser/presentation/local_presentation_manager_factory.h
@@ -16,15 +16,9 @@ class LocalPresentationManager; -// LocalPresentationManager is shared between a Profile and -// its associated incognito Profiles. class LocalPresentationManagerFactory : public BrowserContextKeyedServiceFactory { public: - // If |web_contents| is normal profile, use it as browser context; - // If |web_contents| is incognito profile, |GetBrowserContextToUse| will - // redirect incognito profile to original profile, and use original one as - // browser context. static LocalPresentationManager* GetOrCreateForWebContents( content::WebContents* web_contents); static LocalPresentationManager* GetOrCreateForBrowserContext(
diff --git a/components/media_router/browser/presentation/presentation_service_delegate_impl.cc b/components/media_router/browser/presentation/presentation_service_delegate_impl.cc index 7b9901d28..5aae3732 100644 --- a/components/media_router/browser/presentation/presentation_service_delegate_impl.cc +++ b/components/media_router/browser/presentation/presentation_service_delegate_impl.cc
@@ -530,7 +530,6 @@ } else { // TODO(crbug.com/1418744): Handle multiple URLs. const GURL& presentation_url = presentation_urls[0]; - bool incognito = GetWebContents().GetBrowserContext()->IsOffTheRecord(); router_->JoinRoute( MediaSource::ForPresentationUrl(presentation_url).id(), presentation_id, request.frame_origin, &GetWebContents(), @@ -538,7 +537,7 @@ weak_factory_.GetWeakPtr(), render_frame_host_id, presentation_url, presentation_id, std::move(success_cb), std::move(error_cb)), - base::TimeDelta(), incognito); + base::TimeDelta()); } }
diff --git a/components/media_router/browser/test/mock_media_router.h b/components/media_router/browser/test/mock_media_router.h index 946560e..f679959d 100644 --- a/components/media_router/browser/test/mock_media_router.h +++ b/components/media_router/browser/test/mock_media_router.h
@@ -53,38 +53,34 @@ const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) override { + base::TimeDelta timeout) override { CreateRouteInternal(source, sink_id, origin, web_contents, callback, - timeout, incognito); + timeout); } - MOCK_METHOD7(CreateRouteInternal, + MOCK_METHOD6(CreateRouteInternal, void(const MediaSource::Id& source, const MediaSink::Id& sink_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback& callback, - base::TimeDelta timeout, - bool incognito)); + base::TimeDelta timeout)); void JoinRoute(const MediaSource::Id& source, const std::string& presentation_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback callback, - base::TimeDelta timeout, - bool incognito) override { + base::TimeDelta timeout) override { JoinRouteInternal(source, presentation_id, origin, web_contents, callback, - timeout, incognito); + timeout); } - MOCK_METHOD7(JoinRouteInternal, + MOCK_METHOD6(JoinRouteInternal, void(const MediaSource::Id& source, const std::string& presentation_id, const url::Origin& origin, content::WebContents* web_contents, MediaRouteResponseCallback& callback, - base::TimeDelta timeout, - bool incognito)); + base::TimeDelta timeout)); MOCK_METHOD1(DetachRoute, void(MediaRoute::Id route_id)); MOCK_METHOD1(TerminateRoute, void(const MediaRoute::Id& route_id));
diff --git a/components/media_router/common/media_route.cc b/components/media_router/common/media_route.cc index c458441..c0a03e5 100644 --- a/components/media_router/common/media_route.cc +++ b/components/media_router/common/media_route.cc
@@ -103,7 +103,6 @@ media_sink_name_ == other.media_sink_name_ && description_ == other.description_ && is_local_ == other.is_local_ && controller_type_ == other.controller_type_ && - is_off_the_record_ == other.is_off_the_record_ && is_local_presentation_ == other.is_local_presentation_ && is_connecting_ == other.is_connecting_; }
diff --git a/components/media_router/common/media_route.h b/components/media_router/common/media_route.h index 251471b5..0ff027a0 100644 --- a/components/media_router/common/media_route.h +++ b/components/media_router/common/media_route.h
@@ -96,11 +96,6 @@ } RouteControllerType controller_type() const { return controller_type_; } - void set_off_the_record(bool is_off_the_record) { - is_off_the_record_ = is_off_the_record; - } - bool is_off_the_record() const { return is_off_the_record_; } - void set_local_presentation(bool is_local_presentation) { is_local_presentation_ = is_local_presentation; } @@ -143,9 +138,6 @@ // The type of MediaRouteController supported by this route. RouteControllerType controller_type_ = RouteControllerType::kNone; - // |true| if the route was created by an OffTheRecord profile. - bool is_off_the_record_ = false; - // |true| if the presentation associated with this route is a local // presentation. // TODO(crbug.com/1309770): Remove |is_local_presentation_|.
diff --git a/components/media_router/common/media_route_unittest.cc b/components/media_router/common/media_route_unittest.cc index c715e4b..f3a00bb 100644 --- a/components/media_router/common/media_route_unittest.cc +++ b/components/media_router/common/media_route_unittest.cc
@@ -47,11 +47,6 @@ // The ID is different from route1's. MediaRoute route5(kRouteId2, media_source, kSinkId, kDescription, false); EXPECT_FALSE(route1 == route5); - - // Same as route1 with different off_the_record. - MediaRoute route6(kRouteId1, media_source, kSinkId, kDescription, true); - route6.set_off_the_record(true); - EXPECT_FALSE(route1 == route6); } TEST(MediaRouteTest, TestParsingMediaRouteId) {
diff --git a/components/media_router/common/mojom/media_router.mojom b/components/media_router/common/mojom/media_router.mojom index 9d4f302..c550760 100644 --- a/components/media_router/common/mojom/media_router.mojom +++ b/components/media_router/common/mojom/media_router.mojom
@@ -107,8 +107,6 @@ // The type of route controller that can be created for this route. See // media_controller.mojom for details. RouteControllerType controller_type; - // Set to true if this route was created by an OffTheRecord profile. - bool is_off_the_record; // Set to true if this route corresponds to a local presentation. bool is_local_presentation; // Set to true if this route has been created by the MRP but is waiting for @@ -217,9 +215,6 @@ // If |timeout| is positive, it will be used in place of the default timeout // defined by Media Route Provider Manager. // - // If |off_the_record| is true, the request was made by an OffTheRecord - // profile. - // // If the operation was successful, |route| will be defined and |error_text| // will be null. If the operation failed, |route| will be null and // |error_text| will be set. If |connection| is set, it should be returned to @@ -234,8 +229,7 @@ string original_presentation_id, url.mojom.Origin origin, int32 frame_tree_node_id, - mojo_base.mojom.TimeDelta timeout, - bool off_the_record) => + mojo_base.mojom.TimeDelta timeout) => (MediaRoute? route, RoutePresentationConnection? connection, string? error_text, @@ -250,9 +244,6 @@ // If |timeout| is positive, it will be used in place of the default timeout // defined by Media Route Provider Manager. // - // If the route request was created by an OffTheRecord profile, - // |off_the_record| must be true. - // // If the operation was successful, |route| will be defined and |error_text| // will be null. If the operation failed, |route| will be null and // |error_text| will be set. If |connection| is set, it should be returned to @@ -266,8 +257,7 @@ string presentation_id, url.mojom.Origin origin, int32 frame_tree_node_id, - mojo_base.mojom.TimeDelta timeout, - bool off_the_record) => + mojo_base.mojom.TimeDelta timeout) => (MediaRoute? route, RoutePresentationConnection? connection, string? error_text,
diff --git a/components/media_router/common/mojom/media_router_mojom_traits.cc b/components/media_router/common/mojom/media_router_mojom_traits.cc index 2eaeb35..86a62dd6 100644 --- a/components/media_router/common/mojom/media_router_mojom_traits.cc +++ b/components/media_router/common/mojom/media_router_mojom_traits.cc
@@ -189,7 +189,6 @@ out->set_controller_type(controller_type); out->set_local(data.is_local()); - out->set_off_the_record(data.is_off_the_record()); out->set_local_presentation(data.is_local_presentation()); out->set_is_connecting(data.is_connecting());
diff --git a/components/media_router/common/mojom/media_router_mojom_traits.h b/components/media_router/common/mojom/media_router_mojom_traits.h index 22c916e..113cf83 100644 --- a/components/media_router/common/mojom/media_router_mojom_traits.h +++ b/components/media_router/common/mojom/media_router_mojom_traits.h
@@ -318,10 +318,6 @@ return route.controller_type(); } - static bool is_off_the_record(const media_router::MediaRoute& route) { - return route.is_off_the_record(); - } - static bool is_local_presentation(const media_router::MediaRoute& route) { return route.is_local_presentation(); }
diff --git a/components/password_manager/core/browser/leak_detection_dialog_utils.cc b/components/password_manager/core/browser/leak_detection_dialog_utils.cc index 0fe0218..907bc76b 100644 --- a/components/password_manager/core/browser/leak_detection_dialog_utils.cc +++ b/components/password_manager/core/browser/leak_detection_dialog_utils.cc
@@ -17,6 +17,10 @@ #include "url/gurl.h" #include "url/origin.h" +#if BUILDFLAG(IS_ANDROID) +#include "base/android/build_info.h" +#endif + namespace password_manager { using metrics_util::LeakDialogType; @@ -97,6 +101,11 @@ } bool ShouldCheckPasswords(CredentialLeakType leak_type) { +#if BUILDFLAG(IS_ANDROID) + if (base::android::BuildInfo::GetInstance()->is_automotive()) { + return false; + } +#endif return password_manager::IsPasswordUsedOnOtherSites(leak_type); }
diff --git a/components/password_manager/core/browser/leak_detection_dialog_utils_unittest.cc b/components/password_manager/core/browser/leak_detection_dialog_utils_unittest.cc index ad89928..687eedf 100644 --- a/components/password_manager/core/browser/leak_detection_dialog_utils_unittest.cc +++ b/components/password_manager/core/browser/leak_detection_dialog_utils_unittest.cc
@@ -5,6 +5,7 @@ #include "components/password_manager/core/browser/leak_detection_dialog_utils.h" #include "base/i18n/message_formatter.h" +#include "base/ranges/algorithm.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "build/branding_buildflags.h" @@ -17,6 +18,10 @@ #include "url/gurl.h" #include "url/origin.h" +#if BUILDFLAG(IS_ANDROID) +#include "base/android/build_info.h" +#endif + using password_manager::CreateLeakType; using password_manager::CredentialLeakFlags; using password_manager::CredentialLeakType; @@ -39,7 +44,7 @@ // Contains information that should be displayed on the leak dialog for // specified `leak_type`. -const struct { +const struct LeakTypeParams { // Specifies the test case. CredentialLeakType leak_type; // The rest of the fields specify what should be displayed for this test case. @@ -49,50 +54,86 @@ int leak_title_id; bool should_show_cancel_button; bool should_check_passwords; -} kLeakTypesTestCases[] = { - {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(false)), IDS_OK, - IDS_CLOSE, GetLeakChangePasswordMessage(), - IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, - {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(true)), IDS_OK, - IDS_CLOSE, GetLeakChangePasswordMessage(), - IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, - {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true)), - IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, +} kLeakTypesTestCases[] = + {{CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(false)), IDS_OK, + IDS_CLOSE, GetLeakChangePasswordMessage(), + IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, + {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(true)), IDS_OK, + IDS_CLOSE, GetLeakChangePasswordMessage(), + IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, + {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(true)), IDS_OK, + IDS_CLOSE, GetLeakChangePasswordMessage(), + IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, + {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(true)), IDS_OK, + IDS_CLOSE, GetLeakChangePasswordMessage(), + IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}}, + kPasswordCheckLeakTypesTestCases[] = + {{CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true)), + IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - IDS_CREDENTIAL_LEAK_CHANGE_AND_CHECK_PASSWORDS_MESSAGE_GPM_BRANDED, + IDS_CREDENTIAL_LEAK_CHANGE_AND_CHECK_PASSWORDS_MESSAGE_GPM_BRANDED, #else - IDS_CREDENTIAL_LEAK_CHANGE_AND_CHECK_PASSWORDS_MESSAGE_GPM_NON_BRANDED, + IDS_CREDENTIAL_LEAK_CHANGE_AND_CHECK_PASSWORDS_MESSAGE_GPM_NON_BRANDED, #endif - IDS_CREDENTIAL_LEAK_TITLE_CHECK_GPM, true, true}, - {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(true)), IDS_OK, - IDS_CLOSE, GetLeakChangePasswordMessage(), - IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, - {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(true)), IDS_OK, - IDS_CLOSE, GetLeakChangePasswordMessage(), - IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, - {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), - IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, + IDS_CREDENTIAL_LEAK_TITLE_CHECK_GPM, true, true}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), + IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, #if BUILDFLAG(GOOGLE_CHROME_BRANDING) - IDS_CREDENTIAL_LEAK_CHECK_PASSWORDS_MESSAGE_GPM_BRANDED, + IDS_CREDENTIAL_LEAK_CHECK_PASSWORDS_MESSAGE_GPM_BRANDED, #else - IDS_CREDENTIAL_LEAK_CHECK_PASSWORDS_MESSAGE_GPM_NON_BRANDED, + IDS_CREDENTIAL_LEAK_CHECK_PASSWORDS_MESSAGE_GPM_NON_BRANDED, #endif - IDS_CREDENTIAL_LEAK_TITLE_CHECK_GPM, true, true}, + IDS_CREDENTIAL_LEAK_TITLE_CHECK_GPM, true, true} +#if BUILDFLAG(IS_ANDROID) +}, + kPasswordCheckLeakTypesTestCasesAndroidAutomotive[] = { + {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true)), IDS_OK, + IDS_CLOSE, +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + IDS_CREDENTIAL_LEAK_CHANGE_PASSWORD_MESSAGE_GPM_BRANDED, +#else + IDS_CREDENTIAL_LEAK_CHANGE_PASSWORD_MESSAGE_GPM_NON_BRANDED, +#endif + IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), IDS_OK, + IDS_CLOSE, +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + IDS_CREDENTIAL_LEAK_CHANGE_PASSWORD_MESSAGE_GPM_BRANDED, +#else + IDS_CREDENTIAL_LEAK_CHANGE_PASSWORD_MESSAGE_GPM_NON_BRANDED, +#endif + IDS_CREDENTIAL_LEAK_TITLE_CHANGE, false, false}, +#endif }; struct BulkCheckParams { // Specifies the test case. CredentialLeakType leak_type; bool should_check_passwords; -} kBulkCheckTestCases[] = { - {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(false)), false}, - {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(false)), false}, - {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(false)), true}, - {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(false)), true}, - {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), true}}; +} kBulkCheckTestCases[] = + { + {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(false)), + false}, + {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(false)), + false}, +}, + kPasswordCheckBulkCheckTestCases[] = + {{CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(false)), true}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(false)), true}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), true} + +#if BUILDFLAG(IS_ANDROID) +}, + kPasswordCheckBulkCheckTestCasesAndroidAutomotive[] = { + {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(false)), false}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(false)), false}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), false} +#endif +}; } // namespace -class CredentialLeakDialogUtilsTest : public testing::Test { +class CredentialLeakDialogUtilsTest + : public testing::TestWithParam<LeakTypeParams> { public: CredentialLeakDialogUtilsTest() { #if BUILDFLAG(IS_ANDROID) @@ -101,117 +142,102 @@ #endif } + static std::vector<LeakTypeParams> GetTestCases() { + std::vector<LeakTypeParams> test_cases; + base::ranges::copy(kLeakTypesTestCases, std::back_inserter(test_cases)); +#if BUILDFLAG(IS_ANDROID) + if (base::android::BuildInfo::GetInstance()->is_automotive()) { + base::ranges::copy(kPasswordCheckLeakTypesTestCasesAndroidAutomotive, + std::back_inserter(test_cases)); + return test_cases; + } +#endif + base::ranges::copy(kPasswordCheckLeakTypesTestCases, + std::back_inserter(test_cases)); + return test_cases; + } + private: base::test::ScopedFeatureList feature_list_; }; -TEST_F(CredentialLeakDialogUtilsTest, GetAcceptButtonLabel) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ( - l10n_util::GetStringUTF16(kLeakTypesTestCases[i].accept_button_id), - GetAcceptButtonLabel(kLeakTypesTestCases[i].leak_type)); - } +TEST_P(CredentialLeakDialogUtilsTest, GetAcceptButtonLabel) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(l10n_util::GetStringUTF16(GetParam().accept_button_id), + GetAcceptButtonLabel(GetParam().leak_type)); } -TEST_F(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetAcceptButtonLabel) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ( - l10n_util::GetStringUTF16(kLeakTypesTestCases[i].accept_button_id), - CreateDialogTraits(kLeakTypesTestCases[i].leak_type) - ->GetAcceptButtonLabel()); - } +TEST_P(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetAcceptButtonLabel) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(l10n_util::GetStringUTF16(GetParam().accept_button_id), + CreateDialogTraits(GetParam().leak_type)->GetAcceptButtonLabel()); } -TEST_F(CredentialLeakDialogUtilsTest, GetCancelButtonLabel) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ( - l10n_util::GetStringUTF16(kLeakTypesTestCases[i].cancel_button_id), - GetCancelButtonLabel(kLeakTypesTestCases[i].leak_type)); - } +TEST_P(CredentialLeakDialogUtilsTest, GetCancelButtonLabel) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(l10n_util::GetStringUTF16(GetParam().cancel_button_id), + GetCancelButtonLabel(GetParam().leak_type)); } -TEST_F(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetCancelButtonLabel) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ( - l10n_util::GetStringUTF16(kLeakTypesTestCases[i].cancel_button_id), - CreateDialogTraits(kLeakTypesTestCases[i].leak_type) - ->GetCancelButtonLabel()); - } +TEST_P(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetCancelButtonLabel) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(l10n_util::GetStringUTF16(GetParam().cancel_button_id), + CreateDialogTraits(GetParam().leak_type)->GetCancelButtonLabel()); } -TEST_F(CredentialLeakDialogUtilsTest, GetDescription) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - std::u16string expected_message = - l10n_util::GetStringUTF16(kLeakTypesTestCases[i].leak_message_id); - EXPECT_EQ(expected_message, - GetDescription(kLeakTypesTestCases[i].leak_type)); - } +TEST_P(CredentialLeakDialogUtilsTest, GetDescription) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + std::u16string expected_message = + l10n_util::GetStringUTF16(GetParam().leak_message_id); + EXPECT_EQ(expected_message, GetDescription(GetParam().leak_type)); } -TEST_F(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetDescription) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ( - l10n_util::GetStringUTF16(kLeakTypesTestCases[i].leak_message_id), - CreateDialogTraits(kLeakTypesTestCases[i].leak_type)->GetDescription()); - } +TEST_P(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetDescription) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(l10n_util::GetStringUTF16(GetParam().leak_message_id), + CreateDialogTraits(GetParam().leak_type)->GetDescription()); } -TEST_F(CredentialLeakDialogUtilsTest, GetTitle) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ(l10n_util::GetStringUTF16(kLeakTypesTestCases[i].leak_title_id), - GetTitle(kLeakTypesTestCases[i].leak_type)); - } +TEST_P(CredentialLeakDialogUtilsTest, GetTitle) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(l10n_util::GetStringUTF16(GetParam().leak_title_id), + GetTitle(GetParam().leak_type)); } -TEST_F(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetTitle) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ(l10n_util::GetStringUTF16(kLeakTypesTestCases[i].leak_title_id), - CreateDialogTraits(kLeakTypesTestCases[i].leak_type)->GetTitle()); - } +TEST_P(CredentialLeakDialogUtilsTest, LeakDialogTraits_GetTitle) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(l10n_util::GetStringUTF16(GetParam().leak_title_id), + CreateDialogTraits(GetParam().leak_type)->GetTitle()); } -TEST_F(CredentialLeakDialogUtilsTest, ShouldCheckPasswords) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ(kLeakTypesTestCases[i].should_check_passwords, - ShouldCheckPasswords(kLeakTypesTestCases[i].leak_type)); - } +TEST_P(CredentialLeakDialogUtilsTest, ShouldCheckPasswords) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(GetParam().should_check_passwords, + ShouldCheckPasswords(GetParam().leak_type)); } -TEST_F(CredentialLeakDialogUtilsTest, LeakDialogTraits_ShouldCheckPasswords) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ(kLeakTypesTestCases[i].should_check_passwords, - CreateDialogTraits(kLeakTypesTestCases[i].leak_type) - ->ShouldCheckPasswords()); - } +TEST_P(CredentialLeakDialogUtilsTest, LeakDialogTraits_ShouldCheckPasswords) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(GetParam().should_check_passwords, + CreateDialogTraits(GetParam().leak_type)->ShouldCheckPasswords()); } -TEST_F(CredentialLeakDialogUtilsTest, ShouldShowCancelButton) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ(kLeakTypesTestCases[i].should_show_cancel_button, - ShouldShowCancelButton(kLeakTypesTestCases[i].leak_type)); - } +TEST_P(CredentialLeakDialogUtilsTest, ShouldShowCancelButton) { + EXPECT_EQ(GetParam().should_show_cancel_button, + ShouldShowCancelButton(GetParam().leak_type)); } -TEST_F(CredentialLeakDialogUtilsTest, LeakDialogTraits_ShouldShowCancelButton) { - for (size_t i = 0; i < std::size(kLeakTypesTestCases); ++i) { - SCOPED_TRACE(testing::Message() << i); - EXPECT_EQ(kLeakTypesTestCases[i].should_show_cancel_button, - CreateDialogTraits(kLeakTypesTestCases[i].leak_type) - ->ShouldShowCancelButton()); - } +TEST_P(CredentialLeakDialogUtilsTest, LeakDialogTraits_ShouldShowCancelButton) { + SCOPED_TRACE(testing::Message() << GetParam().leak_type); + EXPECT_EQ(GetParam().should_show_cancel_button, + CreateDialogTraits(GetParam().leak_type)->ShouldShowCancelButton()); } +INSTANTIATE_TEST_SUITE_P( + InstantiationName, + CredentialLeakDialogUtilsTest, + testing::ValuesIn(CredentialLeakDialogUtilsTest::GetTestCases())); + class BulkCheckCredentialLeakDialogUtilsTest : public testing::TestWithParam<BulkCheckParams> { public: @@ -222,6 +248,21 @@ #endif } + static std::vector<BulkCheckParams> GetTestCases() { + std::vector<BulkCheckParams> test_cases; + base::ranges::copy(kBulkCheckTestCases, std::back_inserter(test_cases)); +#if BUILDFLAG(IS_ANDROID) + if (base::android::BuildInfo::GetInstance()->is_automotive()) { + base::ranges::copy(kPasswordCheckBulkCheckTestCasesAndroidAutomotive, + std::back_inserter(test_cases)); + return test_cases; + } +#endif + base::ranges::copy(kPasswordCheckBulkCheckTestCases, + std::back_inserter(test_cases)); + return test_cases; + } + private: base::test::ScopedFeatureList feature_list_; }; @@ -252,9 +293,10 @@ GetTitle(GetParam().leak_type)); } -INSTANTIATE_TEST_SUITE_P(InstantiationName, - BulkCheckCredentialLeakDialogUtilsTest, - testing::ValuesIn(kBulkCheckTestCases)); +INSTANTIATE_TEST_SUITE_P( + InstantiationName, + BulkCheckCredentialLeakDialogUtilsTest, + testing::ValuesIn(BulkCheckCredentialLeakDialogUtilsTest::GetTestCases())); #if BUILDFLAG(IS_ANDROID) struct PasswordChangeParams { @@ -265,28 +307,56 @@ int cancel_button_id; bool should_show_cancel_button; bool should_show_change_password_button; -} kPasswordChangeTestCases[] = { - {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(false)), IDS_OK, - 0, false, false}, - {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(true)), IDS_OK, - 0, false, false}, - {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(false)), - IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, false}, - {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true)), - IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, false}, - {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(false)), IDS_OK, - 0, false, false}, - {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(true)), IDS_OK, - IDS_CLOSE, false, true}, - {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(false)), - IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, false}, - {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), - IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, true}}; +} kPasswordChangeTestCases[] = + {{CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(false)), IDS_OK, + 0, false, false}, + {CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(true)), IDS_OK, + 0, false, false}, + {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(false)), IDS_OK, + 0, false, false}}, + kPasswordChangeTestCasesNonAuto[] = + {{CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(false)), + IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, false}, + {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true)), + IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, false}, + {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(true)), IDS_OK, + IDS_CLOSE, false, true}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(false)), + IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, false}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), + IDS_LEAK_CHECK_CREDENTIALS, IDS_CLOSE, true, true}}, + kPasswordChangeTestCasesAuto[] = { + {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(false)), IDS_OK, + 0, false, false}, + {CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true)), IDS_OK, + 0, false, false}, + {CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(true)), IDS_OK, + 0, false, false}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(false)), IDS_OK, + 0, false, false}, + {CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true)), IDS_OK, + 0, false, false}}; class PasswordChangeCredentialLeakDialogUtilsTest : public testing::TestWithParam<PasswordChangeParams> { public: PasswordChangeCredentialLeakDialogUtilsTest() = default; + + static std::vector<PasswordChangeParams> GetTestCases() { + std::vector<PasswordChangeParams> test_cases; + base::ranges::copy(kPasswordChangeTestCases, + std::back_inserter(test_cases)); + + if (base::android::BuildInfo::GetInstance()->is_automotive()) { + base::ranges::copy(kPasswordChangeTestCasesAuto, + std::back_inserter(test_cases)); + return test_cases; + } + + base::ranges::copy(kPasswordChangeTestCasesNonAuto, + std::back_inserter(test_cases)); + return test_cases; + } }; TEST_P(PasswordChangeCredentialLeakDialogUtilsTest, ShouldShowCancelButton) { @@ -309,8 +379,10 @@ } } -INSTANTIATE_TEST_SUITE_P(InstantiationName, - PasswordChangeCredentialLeakDialogUtilsTest, - testing::ValuesIn(kPasswordChangeTestCases)); +INSTANTIATE_TEST_SUITE_P( + InstantiationName, + PasswordChangeCredentialLeakDialogUtilsTest, + testing::ValuesIn( + PasswordChangeCredentialLeakDialogUtilsTest::GetTestCases())); #endif } // namespace password_manager
diff --git a/components/password_manager/core/browser/sync/password_proto_utils.cc b/components/password_manager/core/browser/sync/password_proto_utils.cc index 3388b7eb..ed532dfd 100644 --- a/components/password_manager/core/browser/sync/password_proto_utils.cc +++ b/components/password_manager/core/browser/sync/password_proto_utils.cc
@@ -305,6 +305,7 @@ *password_metadata.mutable_password_issues() = PasswordIssuesMapToProto(password_form.password_issues); } + password_metadata.set_type(static_cast<int>(password_form.type)); return password_metadata; }
diff --git a/components/password_manager/core/browser/sync/password_proto_utils_unittest.cc b/components/password_manager/core/browser/sync/password_proto_utils_unittest.cc index c44dd316..7655066 100644 --- a/components/password_manager/core/browser/sync/password_proto_utils_unittest.cc +++ b/components/password_manager/core/browser/sync/password_proto_utils_unittest.cc
@@ -104,6 +104,7 @@ password_specifics_data.date_last_used()); *password_specifics_metadata.mutable_password_issues() = password_specifics_data.password_issues(); + password_specifics_metadata.set_type(password_specifics_data.type()); return password_specifics_metadata; }
diff --git a/components/performance_manager/features.cc b/components/performance_manager/features.cc index dcd5a97..9efc7877 100644 --- a/components/performance_manager/features.cc +++ b/components/performance_manager/features.cc
@@ -166,4 +166,7 @@ const base::FeatureParam<base::TimeDelta> kPageTimelineStateIntervalTime{ &kPageTimelineMonitor, "time_between_collect_slice", base::Minutes(5)}; +const base::FeatureParam<bool> kUseResourceAttributionCPUMonitor{ + &kPageTimelineMonitor, "use_resource_attribution_cpu_monitor", false}; + } // namespace performance_manager::features
diff --git a/components/performance_manager/public/features.h b/components/performance_manager/public/features.h index b613d236..4fc8585 100644 --- a/components/performance_manager/public/features.h +++ b/components/performance_manager/public/features.h
@@ -226,6 +226,10 @@ // PageTimelineMonitor::CollectSlice() extern const base::FeatureParam<base::TimeDelta> kPageTimelineStateIntervalTime; +// Whether to use the resource_attribution::CPUMeasurementMonitor for logging +// UKM. +extern const base::FeatureParam<bool> kUseResourceAttributionCPUMonitor; + } // namespace performance_manager::features #endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_FEATURES_H_
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/DisableSafeBrowsingProceedAnyway.yaml b/components/policy/resources/templates/policy_definitions/SafeBrowsing/DisableSafeBrowsingProceedAnyway.yaml similarity index 100% rename from components/policy/resources/templates/policy_definitions/Miscellaneous/DisableSafeBrowsingProceedAnyway.yaml rename to components/policy/resources/templates/policy_definitions/SafeBrowsing/DisableSafeBrowsingProceedAnyway.yaml
diff --git a/components/policy/resources/templates/policy_definitions/SafeBrowsing/policy_atomic_groups.yaml b/components/policy/resources/templates/policy_definitions/SafeBrowsing/policy_atomic_groups.yaml index 97c58ee..463896bd 100644 --- a/components/policy/resources/templates/policy_definitions/SafeBrowsing/policy_atomic_groups.yaml +++ b/components/policy/resources/templates/policy_definitions/SafeBrowsing/policy_atomic_groups.yaml
@@ -17,3 +17,4 @@ - SafeBrowsingProxiedRealTimeChecksAllowed - SafeBrowsingSurveysEnabled - SafeBrowsingDeepScanningEnabled + - DisableSafeBrowsingProceedAnyway
diff --git a/components/privacy_sandbox/mock_privacy_sandbox_settings.h b/components/privacy_sandbox/mock_privacy_sandbox_settings.h index f5af978..b5290f9 100644 --- a/components/privacy_sandbox/mock_privacy_sandbox_settings.h +++ b/components/privacy_sandbox/mock_privacy_sandbox_settings.h
@@ -86,6 +86,10 @@ IsPrivateAggregationDebugModeAllowed, (const url::Origin&, const url::Origin&), (override, const)); + MOCK_METHOD(bool, + IsCookieDeprecationExperimentCurrentlyEligible, + (), + (override, const)); MOCK_METHOD(bool, IsCookieDeprecationLabelAllowed, (), (override, const)); MOCK_METHOD(bool, IsCookieDeprecationLabelAllowedForContext,
diff --git a/components/privacy_sandbox/privacy_sandbox_prefs.cc b/components/privacy_sandbox/privacy_sandbox_prefs.cc index ae07f23f..a0d172e 100644 --- a/components/privacy_sandbox/privacy_sandbox_prefs.cc +++ b/components/privacy_sandbox/privacy_sandbox_prefs.cc
@@ -72,6 +72,8 @@ prefs::kPrivacySandboxTopicsConsentTextAtLastUpdate, ""); registry->RegisterBooleanPref(prefs::kPrivacySandboxAntiAbuseInitialized, false); + registry->RegisterBooleanPref( + prefs::kPrivacySandboxCookieDeprecationExperimentEligible, false); // Register prefs for tracking protection. tracking_protection::RegisterProfilePrefs(registry);
diff --git a/components/privacy_sandbox/privacy_sandbox_prefs.h b/components/privacy_sandbox/privacy_sandbox_prefs.h index c6c8cef..2623758 100644 --- a/components/privacy_sandbox/privacy_sandbox_prefs.h +++ b/components/privacy_sandbox/privacy_sandbox_prefs.h
@@ -181,6 +181,11 @@ inline constexpr char kPrivacySandboxAntiAbuseInitialized[] = "privacy_sandbox.anti_abuse_initialized"; +// Boolean that indicates whether the profile is eligible for cookie deprecation +// experiments. +inline constexpr char kPrivacySandboxCookieDeprecationExperimentEligible[] = + "privacy_sandbox.cookie_deprecation_experiment_eligible"; + } // namespace prefs namespace privacy_sandbox {
diff --git a/components/privacy_sandbox/privacy_sandbox_settings.h b/components/privacy_sandbox/privacy_sandbox_settings.h index 6451849..fe105f23 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings.h +++ b/components/privacy_sandbox/privacy_sandbox_settings.h
@@ -84,6 +84,16 @@ // Whether the profile is subject to being given notice of restrictions to // the standard set of Privacy Sandbox APIs. virtual bool IsSubjectToM1NoticeRestricted() const = 0; + + // Whether the profile is eligible for 3PCD experiment. The eligibility + // applies for both mode A and mode B experiments. + virtual bool IsCookieDeprecationExperimentEligible() const = 0; + + // Whether the profile is currently eligible for 3PCD experiment. The + // eligibility applies for both mode A and mode B experiments. Unlike + // `IsCookieDeprecationExperimentEligible` this method returns the real time + // eligibility. + virtual bool IsCookieDeprecationExperimentCurrentlyEligible() const = 0; }; // Returns whether the Topics API is allowed at all. If false, Topics API @@ -222,9 +232,13 @@ const url::Origin& top_frame_origin, const url::Origin& reporting_origin) const = 0; - // Determines whether cookie deprecation label is allowable. This consults the - // delegate to check whether the sandbox is restricted, as well as the cookie - // settings to check whether third party cookies is blocked. If true, the more + // Returns whether the profile is currently eligible for 3PCD experiments. + // This consults the delegate for the real time eligibility of the profile. + // The eligibility applies for both mode A and mode B experiments. + virtual bool IsCookieDeprecationExperimentCurrentlyEligible() const = 0; + + // Determines whether cookie deprecation label is allowable. This consults + // whether the profile is eligible for 3PCD experiments. If true, the more // specific function, IsCookieDeprecationLabelAllowed(), should be consulted // for the relevant context. virtual bool IsCookieDeprecationLabelAllowed() const = 0;
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_impl.cc b/components/privacy_sandbox/privacy_sandbox_settings_impl.cc index 3630215..e9cd059 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings_impl.cc +++ b/components/privacy_sandbox/privacy_sandbox_settings_impl.cc
@@ -858,9 +858,13 @@ return status; } +bool PrivacySandboxSettingsImpl:: + IsCookieDeprecationExperimentCurrentlyEligible() const { + return delegate_->IsCookieDeprecationExperimentCurrentlyEligible(); +} + bool PrivacySandboxSettingsImpl::IsCookieDeprecationLabelAllowed() const { - return !IsPrivacySandboxRestricted() && - !cookie_settings_->ShouldBlockThirdPartyCookies(); + return delegate_->IsCookieDeprecationExperimentEligible(); } bool PrivacySandboxSettingsImpl::IsCookieDeprecationLabelAllowedForContext( @@ -870,13 +874,8 @@ return false; } - if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) { - return IsAllowed( - GetSiteAccessAllowedStatus(top_frame_origin, context_origin.GetURL())); - } - - return IsPrivacySandboxEnabledForContext(top_frame_origin, - context_origin.GetURL()); + return IsAllowed( + GetSiteAccessAllowedStatus(top_frame_origin, context_origin.GetURL())); } void PrivacySandboxSettingsImpl::OnBlockAllThirdPartyCookiesChanged() {
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_impl.h b/components/privacy_sandbox/privacy_sandbox_settings_impl.h index d3a15051..fb54ffc8 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings_impl.h +++ b/components/privacy_sandbox/privacy_sandbox_settings_impl.h
@@ -88,6 +88,7 @@ bool IsPrivateAggregationDebugModeAllowed( const url::Origin& top_frame_origin, const url::Origin& reporting_origin) const override; + bool IsCookieDeprecationExperimentCurrentlyEligible() const override; bool IsCookieDeprecationLabelAllowed() const override; bool IsCookieDeprecationLabelAllowedForContext( const url::Origin& top_frame_origin,
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc b/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc index 8f21665d..dab3f3c 100644 --- a/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc +++ b/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc
@@ -206,6 +206,11 @@ mock_delegate()->SetUpIsIncognitoProfileResponse(/*incognito=*/false); mock_delegate()->SetUpHasAppropriateTopicsConsentResponse( /*has_appropriate_consent=*/true); + mock_delegate()->SetUpIsCookieDeprecationExperimentEligibleResponse( + /*eligible=*/true); + mock_delegate() + ->SetUpIsCookieDeprecationExperimentCurrentlyEligibleResponse( + /*eligible=*/true); } privacy_sandbox_test_util::MockPrivacySandboxSettingsDelegate* @@ -694,7 +699,7 @@ url::Origin::Create(GURL("https://test.com")), url::Origin::Create(GURL("https://embedded.com")))); - EXPECT_FALSE( + EXPECT_TRUE( privacy_sandbox_settings()->IsCookieDeprecationLabelAllowedForContext( url::Origin::Create(GURL("https://test.com")), url::Origin::Create(GURL("https://embedded.com")))); @@ -787,7 +792,7 @@ url::Origin::Create(GURL("https://test.com")), url::Origin::Create(GURL("https://embedded.com")))); - EXPECT_FALSE( + EXPECT_TRUE( privacy_sandbox_settings()->IsCookieDeprecationLabelAllowedForContext( url::Origin::Create(GURL("https://test.com")), url::Origin::Create(GURL("https://embedded.com")))); @@ -1173,44 +1178,33 @@ EXPECT_TRUE(privacy_sandbox_settings()->IsTopicAllowed(topic_c)); } +TEST_F(PrivacySandboxSettingsTest, + IsCookieDeprecationExperimentCurrentlyEligible) { + EXPECT_CALL(*mock_delegate(), + IsCookieDeprecationExperimentCurrentlyEligible()) + .Times(1) + .WillOnce(testing::Return(false)); + EXPECT_FALSE(privacy_sandbox_settings() + ->IsCookieDeprecationExperimentCurrentlyEligible()); + + EXPECT_CALL(*mock_delegate(), + IsCookieDeprecationExperimentCurrentlyEligible()) + .Times(1) + .WillOnce(testing::Return(true)); + EXPECT_TRUE(privacy_sandbox_settings() + ->IsCookieDeprecationExperimentCurrentlyEligible()); +} + TEST_F(PrivacySandboxSettingsTest, IsCookieDeprecationLabelAllowed) { - privacy_sandbox_test_util::SetupTestState( - prefs(), host_content_settings_map(), - /*privacy_sandbox_enabled=*/true, - /*block_third_party_cookies=*/false, - /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, - /*user_cookie_exceptions=*/{}, - /*managed_cookie_setting=*/privacy_sandbox_test_util::kNoSetting, - /*managed_cookie_exceptions=*/{}); - - EXPECT_CALL(*mock_delegate(), IsPrivacySandboxRestricted()) - .Times(1) - .WillOnce(testing::Return(true)); - EXPECT_FALSE(privacy_sandbox_settings()->IsCookieDeprecationLabelAllowed()); - - EXPECT_CALL(*mock_delegate(), IsPrivacySandboxRestricted()) + EXPECT_CALL(*mock_delegate(), IsCookieDeprecationExperimentEligible()) .Times(1) .WillOnce(testing::Return(false)); + EXPECT_FALSE(privacy_sandbox_settings()->IsCookieDeprecationLabelAllowed()); + + EXPECT_CALL(*mock_delegate(), IsCookieDeprecationExperimentEligible()) + .Times(1) + .WillOnce(testing::Return(true)); EXPECT_TRUE(privacy_sandbox_settings()->IsCookieDeprecationLabelAllowed()); - - privacy_sandbox_test_util::SetupTestState( - prefs(), host_content_settings_map(), - /*privacy_sandbox_enabled=*/true, - /*block_third_party_cookies=*/true, - /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW, - /*user_cookie_exceptions=*/{}, - /*managed_cookie_setting=*/privacy_sandbox_test_util::kNoSetting, - /*managed_cookie_exceptions=*/{}); - - EXPECT_CALL(*mock_delegate(), IsPrivacySandboxRestricted()) - .Times(1) - .WillOnce(testing::Return(true)); - EXPECT_FALSE(privacy_sandbox_settings()->IsCookieDeprecationLabelAllowed()); - - EXPECT_CALL(*mock_delegate(), IsPrivacySandboxRestricted()) - .Times(1) - .WillOnce(testing::Return(false)); - EXPECT_FALSE(privacy_sandbox_settings()->IsCookieDeprecationLabelAllowed()); } class PrivacySandboxSettingsTestCookiesClearOnExitTurnedOff @@ -1831,8 +1825,7 @@ kIsAttributionReportingAllowed, kMaySendAttributionReport, kIsSharedStorageAllowed, kIsSharedStorageSelectURLAllowed, kIsPrivateAggregationAllowed, - kIsPrivateAggregationDebugModeAllowed, - kIsCookieDeprecationLabelAllowedForContext}, + kIsPrivateAggregationDebugModeAllowed}, false}, {MultipleOutputKeys{ kIsTopicsAllowedMetric, kIsTopicsAllowedForContextMetric,
diff --git a/components/privacy_sandbox/privacy_sandbox_test_util.h b/components/privacy_sandbox/privacy_sandbox_test_util.h index 8e3ad5d..ba13418 100644 --- a/components/privacy_sandbox/privacy_sandbox_test_util.h +++ b/components/privacy_sandbox/privacy_sandbox_test_util.h
@@ -87,6 +87,18 @@ }); } + void SetUpIsCookieDeprecationExperimentEligibleResponse(bool eligible) { + ON_CALL(*this, IsCookieDeprecationExperimentEligible).WillByDefault([=]() { + return eligible; + }); + } + + void SetUpIsCookieDeprecationExperimentCurrentlyEligibleResponse( + bool eligible) { + ON_CALL(*this, IsCookieDeprecationExperimentCurrentlyEligible) + .WillByDefault([=]() { return eligible; }); + } + MOCK_METHOD(bool, IsPrivacySandboxRestricted, (), (const, override)); MOCK_METHOD(bool, IsPrivacySandboxCurrentlyUnrestricted, @@ -96,6 +108,14 @@ MOCK_METHOD(bool, IsIncognitoProfile, (), (const, override)); MOCK_METHOD(bool, HasAppropriateTopicsConsent, (), (const, override)); MOCK_METHOD(bool, IsSubjectToM1NoticeRestricted, (), (const, override)); + MOCK_METHOD(bool, + IsCookieDeprecationExperimentEligible, + (), + (const, override)); + MOCK_METHOD(bool, + IsCookieDeprecationExperimentCurrentlyEligible, + (), + (const, override)); }; // A declarative test case is a collection of key value pairs, which each define
diff --git a/components/reading_list/core/reading_list_sync_bridge.cc b/components/reading_list/core/reading_list_sync_bridge.cc index 55bb50f..28d412e2 100644 --- a/components/reading_list/core/reading_list_sync_bridge.cc +++ b/components/reading_list/core/reading_list_sync_bridge.cc
@@ -230,8 +230,14 @@ const sync_pb::ReadingListSpecifics& specifics = change->data().specifics.reading_list(); - // The specifics validity is guaranteed by IsEntityDataValid(). - CHECK(ReadingListEntry::IsSpecificsValid(specifics)); + // TODO(crbug.com/1484570): Ignoring the invalid specifics is just a + // workaround, the specifics validity should be checked here via CHECK() + // as the invalid specifics is supposed to be filtered earlier by + // IsEntityDataValid(). + if (!ReadingListEntry::IsSpecificsValid(specifics)) { + continue; + } + scoped_refptr<ReadingListEntry> entry( ReadingListEntry::FromReadingListValidSpecifics(specifics, clock_->Now()));
diff --git a/components/reading_list/core/reading_list_sync_bridge_unittest.cc b/components/reading_list/core/reading_list_sync_bridge_unittest.cc index 0626b3a..666075e 100644 --- a/components/reading_list/core/reading_list_sync_bridge_unittest.cc +++ b/components/reading_list/core/reading_list_sync_bridge_unittest.cc
@@ -580,7 +580,7 @@ EXPECT_TRUE(bridge()->IsEntityDataValid(data)); } -TEST_F(ReadingListSyncBridgeTest, EntityDataShouldBeNotValid) { +TEST_F(ReadingListSyncBridgeTest, EntityDataShouldBeNotValidIfItHasEmptyUrl) { auto entry = base::MakeRefCounted<ReadingListEntry>( GURL("http://example.com/"), "example title", AdvanceAndGetTime(&clock_)); std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = @@ -591,3 +591,87 @@ EXPECT_FALSE(bridge()->IsEntityDataValid(data)); } + +TEST_F(ReadingListSyncBridgeTest, EntityDataShouldBeNotValidIfItHasInvalidUrl) { + auto entry = base::MakeRefCounted<ReadingListEntry>( + GURL("http://example.com/"), "example title", AdvanceAndGetTime(&clock_)); + std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = + entry->AsReadingListSpecifics(); + *specifics->mutable_url() = "InvalidUrl"; + syncer::EntityData data; + *data.specifics.mutable_reading_list() = *specifics; + + EXPECT_FALSE(bridge()->IsEntityDataValid(data)); +} + +TEST_F(ReadingListSyncBridgeTest, + EntityDataShouldBeNotValidIfTitleContainsNonUTF8) { + auto entry = base::MakeRefCounted<ReadingListEntry>( + GURL("http://example.com/"), "example title", AdvanceAndGetTime(&clock_)); + std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = + entry->AsReadingListSpecifics(); + *specifics->mutable_title() = "\xFC\x9C\xBF\x80\xBF\x80"; + syncer::EntityData data; + *data.specifics.mutable_reading_list() = *specifics; + + EXPECT_FALSE(bridge()->IsEntityDataValid(data)); +} + +// TODO(crbug.com/1484570): The below tests should be removed once the invalid +// specifics get filtered earlier before reaching the bridge. +TEST_F(ReadingListSyncBridgeTest, + ShouldIgnoreEmptyUrlInIncrementalSyncChanges) { + auto entry = base::MakeRefCounted<ReadingListEntry>( + GURL("http://example.com/"), "example title", AdvanceAndGetTime(&clock_)); + std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = + entry->AsReadingListSpecifics(); + *specifics->mutable_url() = ""; + syncer::EntityData data; + *data.specifics.mutable_reading_list() = *specifics; + + syncer::EntityChangeList add_changes; + add_changes.push_back(syncer::EntityChange::CreateAdd("", std::move(data))); + + ASSERT_EQ(0ul, model_->size()); + bridge()->ApplyIncrementalSyncChanges(bridge()->CreateMetadataChangeList(), + std::move(add_changes)); + EXPECT_EQ(0ul, model_->size()); +} + +TEST_F(ReadingListSyncBridgeTest, + ShouldIgnoreInvalidUrlInIncrementalSyncChanges) { + auto entry = base::MakeRefCounted<ReadingListEntry>( + GURL("http://example.com/"), "example title", AdvanceAndGetTime(&clock_)); + std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = + entry->AsReadingListSpecifics(); + *specifics->mutable_url() = "InvalidUrl"; + syncer::EntityData data; + *data.specifics.mutable_reading_list() = *specifics; + + syncer::EntityChangeList add_changes; + add_changes.push_back(syncer::EntityChange::CreateAdd("", std::move(data))); + + ASSERT_EQ(0ul, model_->size()); + bridge()->ApplyIncrementalSyncChanges(bridge()->CreateMetadataChangeList(), + std::move(add_changes)); + EXPECT_EQ(0ul, model_->size()); +} + +TEST_F(ReadingListSyncBridgeTest, + ShouldIgnoreTitleContainsNonUTF8InIncrementalSyncChanges) { + auto entry = base::MakeRefCounted<ReadingListEntry>( + GURL("http://example.com/"), "example title", AdvanceAndGetTime(&clock_)); + std::unique_ptr<sync_pb::ReadingListSpecifics> specifics = + entry->AsReadingListSpecifics(); + *specifics->mutable_title() = "\xFC\x9C\xBF\x80\xBF\x80"; + syncer::EntityData data; + *data.specifics.mutable_reading_list() = *specifics; + + syncer::EntityChangeList add_changes; + add_changes.push_back(syncer::EntityChange::CreateAdd("", std::move(data))); + + ASSERT_EQ(0ul, model_->size()); + bridge()->ApplyIncrementalSyncChanges(bridge()->CreateMetadataChangeList(), + std::move(add_changes)); + EXPECT_EQ(0ul, model_->size()); +}
diff --git a/components/reporting/client/BUILD.gn b/components/reporting/client/BUILD.gn index 6ff43f82..6e6d7b2 100644 --- a/components/reporting/client/BUILD.gn +++ b/components/reporting/client/BUILD.gn
@@ -54,6 +54,7 @@ ":report_queue_configuration", "//base", "//components/reporting/encryption:encryption_module", + "//components/reporting/proto:metric_data_proto", "//components/reporting/proto:record_constants", "//components/reporting/proto:record_proto", "//components/reporting/storage:storage_module",
diff --git a/components/reporting/client/report_queue_impl.cc b/components/reporting/client/report_queue_impl.cc index b8c5eea7..9cde17d 100644 --- a/components/reporting/client/report_queue_impl.cc +++ b/components/reporting/client/report_queue_impl.cc
@@ -25,6 +25,7 @@ #include "base/task/thread_pool.h" #include "base/time/time.h" #include "components/reporting/client/report_queue_configuration.h" +#include "components/reporting/proto/synced/metric_data.pb.h" #include "components/reporting/proto/synced/record.pb.h" #include "components/reporting/proto/synced/record_constants.pb.h" #include "components/reporting/storage/storage_module_interface.h" @@ -39,9 +40,31 @@ // microseconds. constexpr int64_t kTime2122 = 4'796'668'800'000'000; +// Returns true if record is allowed to go to `destination`. Returns false +// otherwise. +static bool RecordMayGoToDestination(const std::string& record_data, + Destination destination) { + // All records sent to destination *_METRIC must be MetricData + // protos due to the way the server is implemented. + if (destination == Destination::EVENT_METRIC || + destination == Destination::TELEMETRY_METRIC || + destination == Destination::INFO_METRIC) { + MetricData metric_data; + const bool is_metric_data = + metric_data.ParseFromString(record_data) && + (metric_data.has_event_data() || metric_data.has_telemetry_data() || + metric_data.has_info_data()); + LOG_IF(ERROR, !is_metric_data) + << "Only MetricData records may be enqueued with destinations: " + "EVENT_METRIC, TELEMETRY_METRIC, or INFO_METRIC"; + return is_metric_data; + } + return true; +} + // Calls |record_producer|, checks the result and in case of success, forwards -// it to the storage. In production code should be invoked asynchronously, on a -// thread pool (no synchronization expected). +// it to the storage. In production code should be invoked asynchronously, on +// a thread pool (no synchronization expected). void AddRecordToStorage(scoped_refptr<StorageModuleInterface> storage, Priority priority, WrappedRateLimiter::AsyncAcquireCb acquire_cb, @@ -52,12 +75,14 @@ ReportQueue::RecordProducer record_producer, StorageModuleInterface::EnqueueCallback callback) { // Generate record data. - auto record_result = std::move(record_producer).Run(); + const auto record_result = std::move(record_producer).Run(); if (!record_result.ok()) { std::move(callback).Run(record_result.status()); return; } + CHECK(RecordMayGoToDestination(record_result.ValueOrDie(), destination)); + // Augment data. Record record; *record.mutable_data() = std::move(record_result.ValueOrDie()); @@ -80,7 +105,8 @@ break; } - // |record| with no DM token is assumed to be associated with device DM token + // |record| with no DM token is assumed to be associated with device DM + // token. if (!dm_token.empty()) { *record.mutable_dm_token() = std::move(dm_token); } @@ -97,10 +123,10 @@ // Unusual timestamp. Reject the record even though the record is good // otherwise, because we can't obtain a reasonable timestamp. We have this // code block here because server very occasionally detects very large - // timestamps. The reason could come from occasional irregular system time. - // Filtering out irregular timestamps here should address the problem - // without leaving timestamp-related bugs in the ERP undiscovered (should - // there be any). + // timestamps. The reason could come from occasional irregular system + // time. Filtering out irregular timestamps here should address the + // problem without leaving timestamp-related bugs in the ERP undiscovered + // (should there be any). base::UmaHistogramBoolean("Browser.ERP.UnusualEnqueueTimestamp", true); std::move(callback).Run(Status( error::FAILED_PRECONDITION,
diff --git a/components/reporting/client/report_queue_impl_unittest.cc b/components/reporting/client/report_queue_impl_unittest.cc index 8c3526b..9efac53be 100644 --- a/components/reporting/client/report_queue_impl_unittest.cc +++ b/components/reporting/client/report_queue_impl_unittest.cc
@@ -12,6 +12,7 @@ #include "base/json/json_reader.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" +#include "base/test/gtest_util.h" #include "base/test/task_environment.h" #include "base/values.h" #include "components/reporting/client/mock_report_queue.h" @@ -89,6 +90,23 @@ report_queue_ = std::move(report_queue_result.ValueOrDie()); } + Status EnqueueTestRecord( + std::unique_ptr<reporting::ReportQueueConfiguration> config, + test::TestMessage test_message) { + test::TestEvent<StatusOr<std::unique_ptr<ReportQueue>>> report_queue_event; + ReportQueueImpl::Create(std::move(config), storage_module_, + report_queue_event.cb()); + auto report_queue_result = report_queue_event.result(); + CHECK(report_queue_result.ok()) << report_queue_result.status(); + + report_queue_ = std::move(report_queue_result.ValueOrDie()); + + test::TestEvent<Status> a; + report_queue_->Enqueue(std::make_unique<test::TestMessage>(test_message), + priority_, a.cb()); + return a.result(); + } + TestStorageModule* test_storage_module() const { TestStorageModule* const test_storage_module = google::protobuf::down_cast<TestStorageModule*>(storage_module_.get()); @@ -162,6 +180,54 @@ ASSERT_EQ(result_message.test(), test_message.test()); } +// Verifies that records sent to `Destination::EVENT_METRIC` are `MetricData` +// protos. +TEST_F(ReportQueueImplTest, + NonMetricDataFailsToEnqueueToEventMetricDestination) { + auto config_result = ReportQueueConfiguration::Create( + {.destination = Destination::EVENT_METRIC}) + .SetDMToken(dm_token_) + .SetPolicyCheckCallback(policy_check_callback_) + .Build(); + ASSERT_OK(config_result) << config_result.status(); + + // Test records are not MetricData so they should trigger CHECK. + EXPECT_CHECK_DEATH(static_cast<void>(EnqueueTestRecord( + std::move(config_result.ValueOrDie()), test::TestMessage()))); +} + +// Verifies that records sent to `Destination::TELEMETRY_METRIC` are +// `MetricData` protos. +TEST_F(ReportQueueImplTest, + NonMetricDataFailsToEnqueueToTelemetryMetricDestination) { + auto config_result = ReportQueueConfiguration::Create( + {.destination = Destination::TELEMETRY_METRIC}) + .SetDMToken(dm_token_) + .SetPolicyCheckCallback(policy_check_callback_) + .Build(); + ASSERT_OK(config_result) << config_result.status(); + + // Test records are not MetricData so they should trigger CHECK. + EXPECT_CHECK_DEATH(static_cast<void>(EnqueueTestRecord( + std::move(config_result.ValueOrDie()), test::TestMessage()))); +} + +// Verifies that records sent to `Destination::INFO_METRIC` are +// `MetricData` protos. +TEST_F(ReportQueueImplTest, + NonMetricDataFailsToEnqueueToInfoMetricDestination) { + auto config_result = ReportQueueConfiguration::Create( + {.destination = Destination::INFO_METRIC}) + .SetDMToken(dm_token_) + .SetPolicyCheckCallback(policy_check_callback_) + .Build(); + ASSERT_OK(config_result) << config_result.status(); + + // Test records are not MetricData so they should trigger CHECK. + EXPECT_CHECK_DEATH(static_cast<void>(EnqueueTestRecord( + std::move(config_result.ValueOrDie()), test::TestMessage()))); +} + TEST_F(ReportQueueImplTest, SuccessfulProtoRecordWithRateLimiter) { auto rate_limiter = std::make_unique<MockRateLimiter>(); auto* const mock_rate_limiter = rate_limiter.get(); @@ -224,20 +290,11 @@ .Build(); ASSERT_OK(config_result) << config_result.status(); - test::TestEvent<StatusOr<std::unique_ptr<ReportQueue>>> report_queue_event; - ReportQueueImpl::Create(std::move(config_result.ValueOrDie()), - storage_module_, report_queue_event.cb()); - auto report_queue_result = report_queue_event.result(); - ASSERT_OK(report_queue_result) << report_queue_result.status(); - - report_queue_ = std::move(report_queue_result.ValueOrDie()); - test::TestMessage test_message; test_message.set_test(kTestMessage); - test::TestEvent<Status> a; - report_queue_->Enqueue(std::make_unique<test::TestMessage>(test_message), - priority_, a.cb()); - const auto a_result = a.result(); + + const auto a_result = + EnqueueTestRecord(std::move(config_result.ValueOrDie()), test_message); EXPECT_OK(a_result) << a_result; EXPECT_THAT(test_storage_module()->priority(), Eq(priority_)); @@ -261,19 +318,10 @@ .Build(); ASSERT_OK(config_result) << config_result.status(); - test::TestEvent<StatusOr<std::unique_ptr<ReportQueue>>> report_queue_event; - ReportQueueImpl::Create(std::move(config_result.ValueOrDie()), - storage_module_, report_queue_event.cb()); - auto report_queue_result = report_queue_event.result(); - ASSERT_OK(report_queue_result) << report_queue_result.status(); - report_queue_ = std::move(report_queue_result.ValueOrDie()); - test::TestMessage test_message; test_message.set_test(kTestMessage); - test::TestEvent<Status> a; - report_queue_->Enqueue(std::make_unique<test::TestMessage>(test_message), - priority_, a.cb()); - const auto a_result = a.result(); + const auto a_result = + EnqueueTestRecord(std::move(config_result.ValueOrDie()), test_message); EXPECT_OK(a_result) << a_result; EXPECT_THAT(test_storage_module()->priority(), Eq(priority_)); @@ -299,19 +347,10 @@ .Build(); ASSERT_OK(config_result) << config_result.status(); - test::TestEvent<StatusOr<std::unique_ptr<ReportQueue>>> report_queue_event; - ReportQueueImpl::Create(std::move(config_result.ValueOrDie()), - storage_module_, report_queue_event.cb()); - auto report_queue_result = report_queue_event.result(); - ASSERT_OK(report_queue_result) << report_queue_result.status(); - report_queue_ = std::move(report_queue_result.ValueOrDie()); - test::TestMessage test_message; test_message.set_test(kTestMessage); - test::TestEvent<Status> a; - report_queue_->Enqueue(std::make_unique<test::TestMessage>(test_message), - priority_, a.cb()); - const auto a_result = a.result(); + const auto a_result = + EnqueueTestRecord(std::move(config_result.ValueOrDie()), test_message); EXPECT_OK(a_result) << a_result; EXPECT_THAT(test_storage_module()->priority(), Eq(priority_));
diff --git a/components/resources/default_200_percent/google_chrome b/components/resources/default_200_percent/google_chrome index 66e7e3c..753a08f 160000 --- a/components/resources/default_200_percent/google_chrome +++ b/components/resources/default_200_percent/google_chrome
@@ -1 +1 @@ -Subproject commit 66e7e3c423b0a795a3706ab63d3e9adfd8c5a646 +Subproject commit 753a08f83909054e694a46f0ca1b06408aee8bd1
diff --git a/components/search_engines/OWNERS b/components/search_engines/OWNERS index ace8b8e..4c57f36 100644 --- a/components/search_engines/OWNERS +++ b/components/search_engines/OWNERS
@@ -1 +1,3 @@ -file://components/omnibox/OWNERS \ No newline at end of file +file://components/omnibox/OWNERS + +per-file search_engine_choice*=file://chrome/browser/search_engine_choice/OWNERS
diff --git a/components/segmentation_platform/embedder/default_model/shopping_user_model.cc b/components/segmentation_platform/embedder/default_model/shopping_user_model.cc index 9da5ebe..0ffa313 100644 --- a/components/segmentation_platform/embedder/default_model/shopping_user_model.cc +++ b/components/segmentation_platform/embedder/default_model/shopping_user_model.cc
@@ -24,9 +24,7 @@ SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHOPPING_USER; constexpr int64_t kShoppingUserSignalStorageLength = 28; constexpr int64_t kShoppingUserMinSignalCollectionLength = 1; -constexpr int64_t kModelVersion = 1; -constexpr int kShoppingUserDefaultSelectionTTLDays = 7; -constexpr int kShoppingUserDefaultUnknownSelectionTTLDays = 7; +constexpr int64_t kModelVersion = 2; // InputFeatures. @@ -55,10 +53,6 @@ config->AddSegmentId( SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHOPPING_USER, std::make_unique<ShoppingUserModel>()); - config->segment_selection_ttl = - base::Days(kShoppingUserDefaultSelectionTTLDays); - config->unknown_selection_ttl = - base::Days(kShoppingUserDefaultUnknownSelectionTTLDays); config->is_boolean_segment = true; return config; } @@ -73,12 +67,20 @@ writer.SetDefaultSegmentationMetadataConfig( kShoppingUserMinSignalCollectionLength, kShoppingUserSignalStorageLength); - // Set discrete mapping. - writer.AddBooleanSegmentDiscreteMapping(kShoppingUserSegmentationKey); - // Set features. writer.AddUmaFeatures(kShoppingUserUMAFeatures.data(), kShoppingUserUMAFeatures.size()); + + // Set OutputConfig. + writer.AddOutputConfigForBinaryClassifier( + /*threshold=*/0.5f, + /*positive_label=*/kShoppingUserUmaName, + /*negative_label=*/kLegacyNegativeLabel); + + writer.AddPredictedResultTTLInOutputConfig( + /*top_label_to_ttl_list=*/{}, /*default_ttl=*/7, + /*time_unit=*/proto::TimeUnit::DAY); + return std::make_unique<ModelConfig>(std::move(shopping_user_metadata), kModelVersion); }
diff --git a/components/segmentation_platform/embedder/default_model/shopping_user_model_unittest.cc b/components/segmentation_platform/embedder/default_model/shopping_user_model_unittest.cc index 5e5e456..42be882 100644 --- a/components/segmentation_platform/embedder/default_model/shopping_user_model_unittest.cc +++ b/components/segmentation_platform/embedder/default_model/shopping_user_model_unittest.cc
@@ -17,24 +17,25 @@ TEST_F(ShoppingUserModelTest, InitAndFetchModel) { ExpectInitAndFetchModel(); + ASSERT_TRUE(fetched_metadata_); } TEST_F(ShoppingUserModelTest, ExecuteModelWithInput) { + ExpectInitAndFetchModel(); + ASSERT_TRUE(fetched_metadata_); + + EXPECT_FALSE(ExecuteWithInput(/*inputs=*/{})); + // When shopping related features count is less than or equal to 1, // the user shouldn't be considered a shopping user. - ExpectExecutionWithInput(/*inputs=*/{0, 0}, /*expected_error=*/false, - /*expected_result=*/{0}); - ExpectExecutionWithInput(/*inputs=*/{1, 0}, /*expected_error=*/false, - /*expected_result=*/{0}); - ExpectExecutionWithInput(/*inputs=*/{1, 1}, /*expected_error=*/false, - /*expected_result=*/{0}); + ExpectClassifierResults(/*input=*/{0, 0}, {kLegacyNegativeLabel}); + ExpectClassifierResults(/*input=*/{1, 0}, {kLegacyNegativeLabel}); + ExpectClassifierResults(/*input=*/{1, 1}, {kLegacyNegativeLabel}); // When shopping related features count is greater than or equal to 1, // the user should be considered shopping user. - ExpectExecutionWithInput(/*inputs=*/{1, 2}, /*expected_error=*/false, - /*expected_result=*/{1}); - ExpectExecutionWithInput(/*inputs=*/{2, 2}, /*expected_error=*/false, - /*expected_result=*/{1}); + ExpectClassifierResults(/*input=*/{1, 2}, {kShoppingUserUmaName}); + ExpectClassifierResults(/*input=*/{2, 2}, {kShoppingUserUmaName}); // Invalid input ExpectExecutionWithInput(/*inputs=*/{1, 1, 1, 1, 1}, /*expected_error=*/true,
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc index 49fa06ac..3fde4f03 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl_unittest.cc
@@ -57,7 +57,7 @@ ::ukm::builders::Segmentation_ModelExecution; constexpr auto kTestOptimizationTarget0 = - SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHOPPING_USER; + SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB; constexpr auto kTestOptimizationTarget1 = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SEARCH_USER; constexpr auto kTestOptimizationTarget2 = @@ -910,10 +910,9 @@ base::DoNothing()); ExpectUkmCount(0u); // A histogram should have been recorded. - EXPECT_EQ( - 1, tester.GetBucketCount( - "SegmentationPlatform.TrainingDataCollectionEvents.ShoppingUser", - stats::TrainingDataCollectionEvent::kGetInputTensorsFailed)); + EXPECT_EQ(1, tester.GetBucketCount( + "SegmentationPlatform.TrainingDataCollectionEvents.NewTab", + stats::TrainingDataCollectionEvent::kGetInputTensorsFailed)); } } // namespace
diff --git a/components/segmentation_platform/internal/metadata/metadata_utils.cc b/components/segmentation_platform/internal/metadata/metadata_utils.cc index b6a5a0f..31c4b8c 100644 --- a/components/segmentation_platform/internal/metadata/metadata_utils.cc +++ b/components/segmentation_platform/internal/metadata/metadata_utils.cc
@@ -528,7 +528,6 @@ SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_QUERY_TILES, SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_CHROME_LOW_USER_ENGAGEMENT, SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_FEED_USER, - SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHOPPING_USER, SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_CHROME_START_ANDROID_V2, SegmentId::POWER_USER_SEGMENT, SegmentId::CROSS_DEVICE_USER_SEGMENT,
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc index 0108ff9f..fb557ba 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl_unittest.cc
@@ -315,23 +315,6 @@ } TEST_F(SegmentationPlatformServiceImplTest, - GetSelectedSegmentOnDemandIfDbInitialized) { - EXPECT_FALSE(segmentation_platform_service_impl_->IsPlatformInitialized()); - int pending_queue_size = GetPendingActionsQueueSize(); - // Initialize the platform - TestInitializationFlow(); - // Platform is initialized, so the API call to get the selected - // segment on demand is executed. - EXPECT_TRUE(segmentation_platform_service_impl_->IsPlatformInitialized()); - EXPECT_EQ(pending_queue_size, GetPendingActionsQueueSize()); - SetUpDefaultModelProviders(); - AssertSelectedSegmentOnDemand( - kTestSegmentationKey4, /*is_ready=*/true, - SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHOPPING_USER); - EXPECT_EQ(pending_queue_size, GetPendingActionsQueueSize()); -} - -TEST_F(SegmentationPlatformServiceImplTest, GetSelectedSegmentOnDemandIfDbFailed) { EXPECT_FALSE(segmentation_platform_service_impl_->IsPlatformInitialized()); int pending_queue_size = GetPendingActionsQueueSize();
diff --git a/components/signin/features.gni b/components/signin/features.gni index f0aa1518..df5e995 100644 --- a/components/signin/features.gni +++ b/components/signin/features.gni
@@ -11,8 +11,8 @@ } # Warning: The feature is still under development. See b/280753754. -enable_search_engine_choice = - (is_linux || is_mac || is_win || is_chromeos) && !is_chrome_for_testing +enable_search_engine_choice = (is_linux || is_mac || is_win || is_chromeos || + is_ios) && !is_chrome_for_testing # Dice is supported on the platform (but not necessarily enabled). enable_dice_support = is_linux || is_mac || is_win || is_fuchsia
diff --git a/components/sync/protocol/password_specifics.proto b/components/sync/protocol/password_specifics.proto index b08ab4f..f9319b1 100644 --- a/components/sync/protocol/password_specifics.proto +++ b/components/sync/protocol/password_specifics.proto
@@ -319,6 +319,9 @@ // Copy from PasswordSpecificsData.password_issues. Introduced in M114. optional PasswordIssues password_issues = 4; + + // Copy from PasswordSpecificsData.type. Introduced in M119. + optional int32 type = 13; } // Properties of password sync objects.
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index 3be99d0..55e5c5f5 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -998,6 +998,7 @@ VISIT(blacklisted); VISIT(date_last_used_windows_epoch_micros); VISIT(password_issues); + VISIT(type); } VISIT_PROTO_FIELDS(const sync_pb::PowerBookmarkSpecifics& proto) {
diff --git a/components/sync_preferences/common_syncable_prefs_database.cc b/components/sync_preferences/common_syncable_prefs_database.cc index 95e1d5f8..8b7f978 100644 --- a/components/sync_preferences/common_syncable_prefs_database.cc +++ b/components/sync_preferences/common_syncable_prefs_database.cc
@@ -46,7 +46,7 @@ kAutofillCreditCardEnabled = 1, kAutofillEnabledDeprecated = 2, kAutofillHasSeenIban = 3, - kAutofillIbanEnabled = 4, + kAutofillIbanEnabled = 4, // Obsolete. kAutofillLastVersionDeduped = 5, kAutofillLastVersionDisusedAddressesDeleted = 6, kAutofillProfileEnabled = 7, @@ -129,9 +129,6 @@ {autofill::prefs::kAutofillHasSeenIban, {syncable_prefs_ids::kAutofillHasSeenIban, syncer::PREFERENCES, false}}, - {autofill::prefs::kAutofillIbanEnabled, - {syncable_prefs_ids::kAutofillIbanEnabled, syncer::PREFERENCES, - false}}, {autofill::prefs::kAutofillLastVersionDeduped, {syncable_prefs_ids::kAutofillLastVersionDeduped, syncer::PREFERENCES, false}},
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index c13e020e..242644e 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -111,26 +111,27 @@ return false; } + // Take the bounds of the sqs filter and apply clipping rect as it may + // make current mask fit the |mask_filter_info|'s bounds. Not doing so may + // result in marking this mask not suitable for merging while it never + // spans outside another mask. + auto rounded_corner_bounds = sqs->mask_filter_info.bounds(); + if (sqs->clip_rect.has_value()) { + rounded_corner_bounds.Intersect(gfx::RectF(*sqs->clip_rect)); + } + // Before checking if current mask's rounded corners do not intersect with // the upper level rounded corner mask, its system coordinate must be // transformed to that target's system coordinate. - gfx::MaskFilterInfo sqs_filter = sqs->mask_filter_info; - sqs_filter.ApplyTransform(parent_target_transform); + rounded_corner_bounds = + parent_target_transform.MapRect(rounded_corner_bounds); - // Also apply clipping rect as it may make current mask fit the - // |mask_filter_info|'s bounds. Not doing so may result in marking this - // mask not suitable for merging while it never spans outside another - // mask. - auto clip_bounds = sqs_filter.bounds(); - if (sqs->clip_rect.has_value()) { - clip_bounds.Intersect(gfx::RectF(*sqs->clip_rect)); - } - - // This is the only case when quads of this render pass with a mask + // This is the only case when quads of this render pass with the mask // filter info that has fast rounded corners set can be merged into the // embedding render pass. So, if they don't intersect with the "toplevel" // rounded corners, we can merge. - if (!mask_filter_info.rounded_corner_bounds().Contains(clip_bounds)) { + if (!mask_filter_info.rounded_corner_bounds().Contains( + rounded_corner_bounds)) { return false; } }
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index dfef187..1607775 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -2966,7 +2966,15 @@ gfx::RRectF(31, 319, 888, 743, 14)); constexpr gfx::Size kSurfaceSize1(950, 875); - const std::vector<std::pair<bool, absl::optional<gfx::Rect>>> kTestData = { + struct AuxiliaryTestData { + // Helps to set correct expectation. + bool mask_will_merge = false; + // Sets additional clipping. + absl::optional<gfx::Rect> clip_rect = absl::nullopt; + // Transform from parent to target that the second SurfaceQuad's SQS must + // apply for correctness of its position. + gfx::Transform parent_target_transform; + } kAuxiliaryTestData[] = { {/*mask_will_merge=*/true, gfx::Rect(0, 0, 350, 750)}, {/*mask_will_merge=*/true, gfx::Rect(0, 0, 900, 750)}, {/*mask_will_merge=*/true, gfx::Rect(0, 0, 899, 799)}, @@ -2974,9 +2982,11 @@ {/*mask_will_merge=*/false, gfx::Rect(0, 0, 901, 799)}, {/*mask_will_merge=*/false, absl::nullopt}, {/*mask_will_merge=*/false, gfx::Rect(0, 0, 899, 801)}, + {/*mask_will_merge=*/true, gfx::Rect(31, 319, 70, 80), + gfx::Transform::MakeTranslation(0, 100)}, }; - for (auto& test_data : kTestData) { + for (auto& test_data : kAuxiliaryTestData) { auto child_root_support = std::make_unique<CompositorFrameSinkSupport>( nullptr, &manager_, kArbitraryFrameSinkId1, /*is_root=*/false); auto child_one_support = std::make_unique<CompositorFrameSinkSupport>( @@ -2992,7 +3002,7 @@ auto child_one_pass = RenderPassBuilder(kSurfaceSize1) .AddSolidColorQuad(gfx::Rect(kSurfaceSize1), SkColors::kGreen) - .SetQuadClipRect(test_data.second) + .SetQuadClipRect(test_data.clip_rect) .SetMaskFilter(kMaskFilterInfoWithFastRoundedCorners2, /*is_fast_rounded_corner=*/true) .Build(); @@ -3017,6 +3027,7 @@ .SetQuadClipRect(gfx::Rect({0, 0}, kSurfaceSize1)) .SetMaskFilter(kMaskFilterInfoWithFastRoundedCorners1, /*is_fast_rounded_corner=*/true) + .SetQuadToTargetTransform(test_data.parent_target_transform) .Build(); QueuePassAsFrame(std::move(root_pass), root_surface_id_.local_surface_id(), device_scale_factor, root_sink_.get()); @@ -3025,7 +3036,7 @@ const auto& aggregated_pass_list = aggregated_frame.render_pass_list; - if (/*mask_will_merge=*/test_data.first) { + if (test_data.mask_will_merge) { // Given clipping makes kMaskFilterInfoWithFastRoundedCorners2 fit // kMaskFilterInfoWithFastRoundedCorners1, there must be only a root // render pass. @@ -3033,11 +3044,14 @@ const auto& root_aggregated_quad_list_of_surface = aggregated_pass_list[0]->quad_list; - EXPECT_THAT( - root_aggregated_quad_list_of_surface, - ElementsAre( - HasMaskFilterInfo(kMaskFilterInfoWithFastRoundedCorners2), - HasMaskFilterInfo(kMaskFilterInfoWithFastRoundedCorners1))); + + gfx::MaskFilterInfo expected_second_mask = + kMaskFilterInfoWithFastRoundedCorners2; + expected_second_mask.ApplyTransform(test_data.parent_target_transform); + EXPECT_THAT(root_aggregated_quad_list_of_surface, + ElementsAre(HasMaskFilterInfo(expected_second_mask), + HasMaskFilterInfo( + kMaskFilterInfoWithFastRoundedCorners1))); } else { // The kMaskFilterInfoWithFastRoundedCorners2 doesn't fit // kMaskFilterInfoWithFastRoundedCorners1 and there is no clipping that
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 974af03..e4a29a97 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -3457,7 +3457,9 @@ RunHtmlTest(FILE_PATH_LITERAL("button-with-listbox-popup.html")); } -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DeleteSelectionCrash) { +// TODO(https://crbug.com/1483778): Re-enable once the test is no longer flaky. +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, + DISABLED_DeleteSelectionCrash) { RunHtmlTest(FILE_PATH_LITERAL("delete-selection-crash.html")); }
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 6a526c3..df2ec1b 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -1143,7 +1143,7 @@ &EmptyBinderForFrame<blink::mojom::EnvironmentIntegrityService>)); } if (base::FeatureList::IsEnabled( - net::features::kCookieDeprecationFacilitatedTestingLabels)) { + features::kCookieDeprecationFacilitatedTesting)) { map->Add<blink::mojom::CookieDeprecationLabelDocumentService>( base::BindRepeating( &CookieDeprecationLabelDocumentService::CreateMojoService));
diff --git a/content/browser/cookie_deprecation_label/cookie_deprecation_label_browsertest.cc b/content/browser/cookie_deprecation_label/cookie_deprecation_label_browsertest.cc index adadc75..b2e110a 100644 --- a/content/browser/cookie_deprecation_label/cookie_deprecation_label_browsertest.cc +++ b/content/browser/cookie_deprecation_label/cookie_deprecation_label_browsertest.cc
@@ -9,13 +9,13 @@ #include "base/test/scoped_feature_list.h" #include "content/browser/cookie_deprecation_label/cookie_deprecation_label_test_utils.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_content_browser_client.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" -#include "net/base/features.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_status_code.h" #include "net/test/embedded_test_server/controllable_http_response.h" @@ -127,7 +127,7 @@ public: CookieDeprecationLabelEnabledBrowserTest() { scoped_feature_list_.InitAndEnableFeatureWithParameters( - net::features::kCookieDeprecationFacilitatedTestingLabels, + features::kCookieDeprecationFacilitatedTesting, {{"label", "label_test"}}); }
diff --git a/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl.cc b/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl.cc index 34933a4..4af0ec83 100644 --- a/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl.cc +++ b/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl.cc
@@ -10,7 +10,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" -#include "net/base/features.h" +#include "content/public/common/content_features.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace content { @@ -18,7 +18,7 @@ namespace { const base::FeatureParam<std::string> kCookieDeprecationLabel{ - &net::features::kCookieDeprecationFacilitatedTestingLabels, "label", ""}; + &features::kCookieDeprecationFacilitatedTesting, "label", ""}; } // namespace
diff --git a/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl_unittest.cc b/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl_unittest.cc index 57abdf4..4f7853f5 100644 --- a/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl_unittest.cc +++ b/content/browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl_unittest.cc
@@ -6,11 +6,11 @@ #include "base/test/scoped_feature_list.h" #include "content/browser/cookie_deprecation_label/cookie_deprecation_label_test_utils.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_utils.h" #include "content/test/test_content_browser_client.h" -#include "net/base/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,7 +21,7 @@ public: CookieDeprecationLabelManagerImplTest() : label_manager_(&browser_context_) { scoped_feature_list_.InitAndEnableFeatureWithParameters( - net::features::kCookieDeprecationFacilitatedTestingLabels, + features::kCookieDeprecationFacilitatedTesting, {{"label", "label_test"}}); }
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 39cf06e..ee5dd47 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -784,6 +784,11 @@ Network::SetCookieBlockedReasonEnum::ThirdPartyBlockedInFirstPartySet); } if (status.HasExclusionReason( + net::CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT)) { + blockedReasons->push_back( + Network::SetCookieBlockedReasonEnum::ThirdPartyPhaseout); + } + if (status.HasExclusionReason( net::CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE)) { blockedReasons->push_back(Network::SetCookieBlockedReasonEnum::SyntaxError); } @@ -889,6 +894,11 @@ blockedReasons->push_back( Network::CookieBlockedReasonEnum::ThirdPartyBlockedInFirstPartySet); } + if (status.HasExclusionReason( + net::CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT)) { + blockedReasons->push_back( + Network::CookieBlockedReasonEnum::ThirdPartyPhaseout); + } if (status.HasExclusionReason(net::CookieInclusionStatus:: EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE)) { blockedReasons->push_back(
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 09922b47..158460d 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -1030,9 +1030,15 @@ case AccessType::kBid: type_enum = Storage::InterestGroupAccessTypeEnum::Bid; break; + case AccessType::kAdditionalBid: + type_enum = Storage::InterestGroupAccessTypeEnum::AdditionalBid; + break; case AccessType::kWin: type_enum = Storage::InterestGroupAccessTypeEnum::Win; break; + case AccessType::kAdditionalBidWin: + type_enum = Storage::InterestGroupAccessTypeEnum::AdditionalBidWin; + break; }; frontend_->InterestGroupAccessed(access_time.ToDoubleT(), type_enum, owner_origin.Serialize(), name);
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc index 613358b..2003a39 100644 --- a/content/browser/interest_group/auction_runner_unittest.cc +++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -496,7 +496,7 @@ 'click', {bucket: 30n, value: 40 + bid}); } - reportContextualWin = reportWin; + reportAdditionalBidWin = reportWin; )"; return base::StringPrintf( kBidScript, seller.Serialize().c_str(), bid.c_str(), render_url.c_str(), @@ -4752,9 +4752,24 @@ ElementsAreRequests( BuildPrivateAggregationRequest(/*bucket=*/10, /*value=*/23), BuildPrivateAggregationRequest(/*bucket=*/30, /*value=*/43))))); + // Bid count should only be incremented by 1. + base::RunLoop run_loop; + interest_group_manager_->GetInterestGroup( + kBidder1Key, + base::BindLambdaForTesting( + [&](absl::optional<StorageInterestGroup> interest_group) { + ASSERT_TRUE(interest_group); + // MakeInterestGroup() set `bid_count` to 5, so it should be 6 + // (not 7). + EXPECT_EQ(6, interest_group->bidding_browser_signals->bid_count); + run_loop.Quit(); + })); + run_loop.Run(); + + // Both uses should get reported to the observer, however. EXPECT_THAT(result_.interest_groups_that_bid, - testing::UnorderedElementsAre(kBidder1Key)); + testing::UnorderedElementsAre(kBidder1Key, kBidder1Key)); EXPECT_EQ(R"({"renderURL":"https://component2-bid.test/"})", result_.winning_group_ad_metadata); // Currently an interest group participating twice in an auction is counted @@ -19992,8 +20007,8 @@ browserSignals.interestGroupName); } - function reportContextualWin(auctionSignals, perBuyerSignals, sellerSignals, - browserSignals) { + function reportAdditionalBidWin(auctionSignals, perBuyerSignals, + sellerSignals, browserSignals) { sendReportTo("https://contextual.test/?" + browserSignals.interestGroupName); }
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc index ba6b351..6b1e9e6 100644 --- a/content/browser/interest_group/interest_group_auction.cc +++ b/content/browser/interest_group/interest_group_auction.cc
@@ -976,6 +976,10 @@ if (bid_state->made_bid) { interest_groups.emplace(bid_state->bidder->interest_group.owner, bid_state->bidder->interest_group.name); + auction_->interest_group_manager_->NotifyInterestGroupAccessed( + InterestGroupManagerImpl::InterestGroupObserver::kBid, + bid_state->bidder->interest_group.owner, + bid_state->bidder->interest_group.name); bid_count++; } } @@ -2646,6 +2650,12 @@ if (saved_response_) { interest_groups.insert(saved_response_->bidding_groups.begin(), saved_response_->bidding_groups.end()); + for (const auto& ig_bid : interest_groups) { + interest_group_manager_->NotifyInterestGroupAccessed( + InterestGroupManagerImpl::InterestGroupObserver:: + InterestGroupObserver::kBid, + ig_bid.owner, ig_bid.name); + } return; } @@ -2653,13 +2663,16 @@ buyer_helper->GetInterestGroupsThatBidAndReportBidCounts(interest_groups); } - // TODO(http://crbug.com/1464874, https://crbug.com/1475640): Report - // additional bids to devtools as well, similar to what - // BuyerHelper::GetInterestGroupsThatBidAndReportBidCounts does for things - // from interest groups. Likely will need to untangle - // InterestGroupManagerImpl::RecordInterestGroupBids doing both DB recording - // and debugging notification (and reporting is the wrong time for the debug - // info, too). + // Notify devtools of additional bids. These don't go into `interest_groups`, + // that's only things in the database. + for (const auto& bid_state : bid_states_for_additional_bids_) { + DCHECK(bid_state->made_bid); + interest_group_manager_->NotifyInterestGroupAccessed( + InterestGroupManagerImpl::InterestGroupObserver::InterestGroupObserver:: + kAdditionalBid, + bid_state->bidder->interest_group.owner, + bid_state->bidder->interest_group.name); + } // Retrieve data from component auctions as well. for (const auto& component_auction_info : component_auctions_) { @@ -3305,14 +3318,10 @@ } // Ignore interest groups with no bidding script or no ads. - interest_groups.erase( - std::remove_if(interest_groups.begin(), interest_groups.end(), - [](const StorageInterestGroup& bidder) { - return !bidder.interest_group.bidding_url || - !bidder.interest_group.ads || - bidder.interest_group.ads->empty(); - }), - interest_groups.end()); + base::EraseIf(interest_groups, [](const StorageInterestGroup& bidder) { + return !bidder.interest_group.bidding_url || !bidder.interest_group.ads || + bidder.interest_group.ads->empty(); + }); // Ignore interest groups that don't provide the requested seller // capabilities.
diff --git a/content/browser/interest_group/interest_group_auction.h b/content/browser/interest_group/interest_group_auction.h index ecf80c1..75d4bfb4 100644 --- a/content/browser/interest_group/interest_group_auction.h +++ b/content/browser/interest_group/interest_group_auction.h
@@ -590,9 +590,11 @@ // Returns all interest groups that bid in an auction. Expected to be called // after the bidding and scoring phase completes. Returns an empty set if the // auction failed for any reason other than the seller rejecting all bids. - // Bids from additional bids are not included, since they do not really have + // Bids from additional bids are not returned, since they do not really have // interest groups (and we don't want to attribute them to database IGs with // aliasing names). + // + // All bids (including additional bids) are also reported to the observer. void GetInterestGroupsThatBidAndReportBidCounts( blink::InterestGroupSet& interest_groups) const;
diff --git a/content/browser/interest_group/interest_group_auction_reporter.cc b/content/browser/interest_group/interest_group_auction_reporter.cc index 9a7b680..06828fe 100644 --- a/content/browser/interest_group/interest_group_auction_reporter.cc +++ b/content/browser/interest_group/interest_group_auction_reporter.cc
@@ -934,6 +934,13 @@ interest_group_manager_->RecordInterestGroupWin( blink::InterestGroupKey(winning_group.owner, winning_group.name), winning_bid_info_.ad_metadata); + interest_group_manager_->NotifyInterestGroupAccessed( + InterestGroupManagerImpl::InterestGroupObserver::kWin, + winning_group.owner, winning_group.name); + } else { + interest_group_manager_->NotifyInterestGroupAccessed( + InterestGroupManagerImpl::InterestGroupObserver::kAdditionalBidWin, + winning_group.owner, winning_group.name); } interest_group_manager_->RegisterAdKeysAsJoined(
diff --git a/content/browser/interest_group/interest_group_auction_reporter_unittest.cc b/content/browser/interest_group/interest_group_auction_reporter_unittest.cc index 67c4ab0..ad1db767 100644 --- a/content/browser/interest_group/interest_group_auction_reporter_unittest.cc +++ b/content/browser/interest_group/interest_group_auction_reporter_unittest.cc
@@ -145,14 +145,24 @@ "\"This be metadata\""}}}) .Build(); - // Join the interest group that "won" the auction - this matters for tests - // that make sure the interest group is updated correctly. + // Join the interest groups that "won" and "lost" the auction - this matters + // for tests that make sure the interest group is updated correctly. const blink::InterestGroup& interest_group = winning_bid_info_.storage_interest_group->interest_group; interest_group_manager_impl_->JoinInterestGroup( interest_group, /*joining_url=*/kWinningBidderOrigin.GetURL()); + auto losing_interest_group = + blink::TestInterestGroupBuilder(kLosingBidderOrigin, kLosingBidderName) + .SetBiddingUrl(kLosingBidderScriptUrl) + // A non-empty ad list is needed by KAnonKeyForAdBid(). + .SetAds({{{GURL("https://ad.render.url.test/"), "null"}}}) + .Build(); + interest_group_manager_impl_->JoinInterestGroup( + losing_interest_group, + /*joining_url=*/kLosingBidderOrigin.GetURL()); + winning_bid_info_.render_url = (*interest_group.ads)[0].render_url; winning_bid_info_.ad_metadata = kWinningAdMetadata; @@ -347,6 +357,26 @@ EXPECT_EQ((*prev_wins)[0]->ad_json, kWinningAdMetadata); } + void ExpectBidsForKey(const url::Origin& origin, + const std::string& name, + int expected_bids) { + absl::optional<StorageInterestGroup> interest_group = + interest_group_manager_impl_->BlockingGetInterestGroup(origin, name); + ASSERT_TRUE(interest_group); + EXPECT_EQ(expected_bids, interest_group->bidding_browser_signals->bid_count) + << origin << "," << name; + } + + void ExpectNoBidsRecorded() { + ExpectBidsForKey(kWinningBidderOrigin, kWinningBidderName, 0); + ExpectBidsForKey(kLosingBidderOrigin, kLosingBidderName, 0); + } + + void ExpectBidsRecordedOnce() { + ExpectBidsForKey(kWinningBidderOrigin, kWinningBidderName, 1); + ExpectBidsForKey(kLosingBidderOrigin, kLosingBidderName, 1); + } + // AuctionWorkletManager::Delegate implementation. // // Note that none of these matter for these tests, as the the mock worklet @@ -420,6 +450,8 @@ const std::string kWinningBidderName = "winning interest group name"; const std::string kWinningAdMetadata = R"({"render_url": "https://foo/"})"; + const GURL kLosingBidderScriptUrl = + GURL("https://losing.bidder.origin.test/bidder_script.js"); const url::Origin kLosingBidderOrigin = url::Origin::Create(GURL("https://losing.bidder.origin.test/")); const std::string kLosingBidderName = "losing interest group name"; @@ -433,10 +465,6 @@ const url::Origin kComponentSellerOrigin = url::Origin::Create(kComponentSellerScriptUrl); - const std::vector<blink::InterestGroupKey> kExpectedInterestGroupsThatBid{ - {kWinningBidderOrigin, kWinningBidderName}, - {kLosingBidderOrigin, kLosingBidderName}}; - // Private aggregation requests. Their values don't matter, beyond that // they're different from each other. const auction_worklet::mojom::PrivateAggregationRequestPtr @@ -1236,15 +1264,12 @@ TEST_F(InterestGroupAuctionReporterTest, RecordWinAndBids) { SetUpAndStartSingleSellerAuction(); ExpectNoWinsRecorded(); - EXPECT_THAT(interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAre()); + ExpectNoBidsRecorded(); // The win and bids should be recorded immediately upon navigation. interest_group_auction_reporter_->OnNavigateToWinningAdCallback().Run(); ExpectWinRecordedOnce(); - EXPECT_THAT( - interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAreArray(kExpectedInterestGroupsThatBid)); + ExpectBidsRecordedOnce(); WaitForReportResultAndRunCallback(kSellerScriptUrl, absl::nullopt); WaitForReportWinAndRunCallback(absl::nullopt); @@ -1252,8 +1277,7 @@ // The win and bids should have been recorded only once. ExpectWinRecordedOnce(); - EXPECT_THAT(interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAre()); + ExpectBidsRecordedOnce(); } // Check that the winning interest group and bids are reported to the @@ -1261,8 +1285,7 @@ // after all reporting scripts have been run. TEST_F(InterestGroupAuctionReporterTest, RecordWinAndBidsLateNavigation) { SetUpAndStartSingleSellerAuction(); - EXPECT_THAT(interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAre()); + ExpectNoBidsRecorded(); WaitForReportResultAndRunCallback(kSellerScriptUrl, absl::nullopt); WaitForReportWinAndRunCallback(absl::nullopt); @@ -1270,22 +1293,18 @@ // Running reporting scripts should not cause the win or any bids to be // recorded. ExpectNoWinsRecorded(); - EXPECT_THAT(interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAre()); + ExpectNoBidsRecorded(); // The bids should be recorded immediately upon navigation. interest_group_auction_reporter_->OnNavigateToWinningAdCallback().Run(); ExpectWinRecordedOnce(); - EXPECT_THAT( - interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAreArray(kExpectedInterestGroupsThatBid)); + ExpectBidsRecordedOnce(); WaitForCompletion(); // The win and bids should have been recorded only once. ExpectWinRecordedOnce(); - EXPECT_THAT(interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAre()); + ExpectBidsRecordedOnce(); } // Check that the passed in `k_anon_keys_to_join` are reported to the @@ -1696,8 +1715,7 @@ EXPECT_THAT(interest_group_manager_impl_->TakeJoinedKAnonSets(), testing::UnorderedElementsAre()); ExpectNoWinsRecorded(); - EXPECT_THAT(interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAre()); + ExpectNoBidsRecorded(); EXPECT_THAT(private_aggregation_manager_.TakePrivateAggregationRequests(), testing::UnorderedElementsAre()); EXPECT_TRUE( @@ -1764,9 +1782,7 @@ EXPECT_THAT(interest_group_manager_impl_->TakeJoinedKAnonSets(), testing::UnorderedElementsAreArray(k_anon_keys_to_join_)); ExpectWinRecordedOnce(); - EXPECT_THAT( - interest_group_manager_impl_->TakeInterestGroupsThatBid(), - testing::UnorderedElementsAreArray(kExpectedInterestGroupsThatBid)); + ExpectBidsRecordedOnce(); // Private aggregation data should have been passed along only once. EXPECT_THAT(
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index eb9e276..1ed0a74 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -1222,8 +1222,8 @@ auto result = RunAuctionAndWait(auction_config_json, /*execution_target=*/absl::nullopt); GURL urn_url = GURL(result.ExtractString()); - EXPECT_TRUE(urn_url.is_valid()); - EXPECT_EQ(url::kUrnScheme, urn_url.scheme_piece()); + EXPECT_TRUE(urn_url.is_valid()) << result; + EXPECT_EQ(url::kUrnScheme, urn_url.scheme_piece()) << result; TestFencedFrameURLMappingResultObserver observer; ConvertFencedFrameURNToURL(urn_url, &observer); @@ -16440,12 +16440,15 @@ for (bool should_win : {true, false}) { SCOPED_TRACE(should_win); + AttachInterestGroupObserver(); ClearReceivedRequests(); ASSERT_TRUE(NavigateToURL(shell(), test_url)); std::string auction_nonce = CreateAuctionNonceAndWait(); GURL additional_bid_logic_url = https_server_->GetURL( "b.test", "/interest_group/bidding_logic_additional_bid.js"); + url::Origin additional_bid_origin = + url::Origin::Create(additional_bid_logic_url); std::string auction_config = JsReplace( R"({ @@ -16470,7 +16473,7 @@ test_origin, https_server_->GetURL("a.test", "/interest_group/decision_logic.js"), auction_nonce, additional_bid_ad_url, additional_bid_logic_url, - url::Origin::Create(additional_bid_logic_url), should_win ? 1.99 : 0.1); + additional_bid_origin, should_win ? 1.99 : 0.1); RunAuctionAndWaitForURLAndNavigateIframe( auction_config, should_win ? additional_bid_ad_url : ad_url); @@ -16480,10 +16483,24 @@ https_server_->GetURL("a.test", "/echoall?report_bidder_additional")); EXPECT_FALSE(HasServerSeenUrl( https_server_->GetURL("a.test", "/echoall?report_bidder"))); + WaitForAccessObserved({ + {TestInterestGroupObserver::kLoaded, test_origin, "cars"}, + {TestInterestGroupObserver::kBid, test_origin, "cars"}, + {TestInterestGroupObserver::kAdditionalBid, additional_bid_origin, + "campaign123"}, + {TestInterestGroupObserver::kAdditionalBidWin, additional_bid_origin, + "campaign123"}, + }); } else { WaitForUrl(https_server_->GetURL("a.test", "/echoall?report_bidder")); EXPECT_FALSE(HasServerSeenUrl(https_server_->GetURL( "a.test", "/echoall?report_bidder_additional"))); + WaitForAccessObserved( + {{TestInterestGroupObserver::kLoaded, test_origin, "cars"}, + {TestInterestGroupObserver::kBid, test_origin, "cars"}, + {TestInterestGroupObserver::kAdditionalBid, additional_bid_origin, + "campaign123"}, + {TestInterestGroupObserver::kWin, test_origin, "cars"}}); } } } @@ -17992,6 +18009,218 @@ https_server_->GetURL(kTestOrigin, "/echoall?report_bidder"))); } +// No additional bids is also fine. The additional bid always participates. +IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, + AdditionalBidWithNoNegativeIGSAlwaysBids) { + URLLoaderMonitor url_loader_monitor; + + constexpr char kTestOrigin[] = "a.test"; + GURL test_url = https_server_->GetURL(kTestOrigin, "/page_with_iframe.html"); + GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars"); + GURL additional_bid_ad_url = + https_server_->GetURL("c.test", "/echo?render_horses"); + constexpr char kNegativeInterestGroupName[] = "current-horse-owner"; + + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + EXPECT_EQ(kSuccess, + JoinInterestGroupAndVerify( + blink::TestInterestGroupBuilder( + /*owner=*/url::Origin::Create(test_url), + /*name=*/"cars") + .SetBiddingUrl(https_server_->GetURL( + kTestOrigin, "/interest_group/bidding_logic.js")) + .SetAds(/*ads=*/{{{ad_url, /*metadata=*/absl::nullopt}}}) + .Build())); + + std::string auction_nonce = CreateAuctionNonceAndWait(); + + GURL additional_bid_logic_url = https_server_->GetURL( + kTestOrigin, "/interest_group/bidding_logic_additional_bid.js"); + + std::string auction_config = JsReplace( + R"({ + seller: $1, + decisionLogicUrl: $2, + interestGroupBuyers: [$1], + auctionNonce: $3, + additionalBids: provideAdditionalBids($1, $3, [JSON.stringify({ + interestGroup: { + name: 'campaign123', + biddingLogicURL: $5, + owner:$6 + }, + bid: { + ad: ['ad'], + bid: 1.99, + render: $4, + }, + auctionNonce: $3, + seller: $1, + })]) + })", + url::Origin::Create(test_url), + https_server_->GetURL(kTestOrigin, "/interest_group/decision_logic.js"), + auction_nonce, additional_bid_ad_url, additional_bid_logic_url, + url::Origin::Create(additional_bid_logic_url), + kNegativeInterestGroupName); + + RunAuctionAndWaitForURLAndNavigateIframe(auction_config, + additional_bid_ad_url); + WaitForUrl(https_server_->GetURL(kTestOrigin, "/echoall?report_seller")); + WaitForUrl( + https_server_->GetURL(kTestOrigin, "/echoall?report_bidder_additional")); + EXPECT_FALSE(HasServerSeenUrl( + https_server_->GetURL(kTestOrigin, "/echoall?report_bidder"))); +} + +// If the additional bid is missing a topLevelSeller in a component auction, it +// does not bid. +IN_PROC_BROWSER_TEST_F( + InterestGroupBrowserTest, + AdditionalBidOnComponentAuctionMissingTopLevelSellerDoesNotBid) { + URLLoaderMonitor url_loader_monitor; + + constexpr char kTestOrigin[] = "a.test"; + GURL test_url = https_server_->GetURL(kTestOrigin, "/page_with_iframe.html"); + GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars"); + GURL additional_bid_ad_url = + https_server_->GetURL("c.test", "/echo?render_horses"); + + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + EXPECT_EQ(kSuccess, + JoinInterestGroupAndVerify( + blink::TestInterestGroupBuilder( + /*owner=*/url::Origin::Create(test_url), + /*name=*/"cars") + .SetBiddingUrl(https_server_->GetURL( + kTestOrigin, "/interest_group/bidding_logic.js")) + .SetAds(/*ads=*/{{{ad_url, /*metadata=*/absl::nullopt}}}) + .Build())); + + std::string auction_nonce = CreateAuctionNonceAndWait(); + + GURL additional_bid_logic_url = https_server_->GetURL( + kTestOrigin, "/interest_group/bidding_logic_additional_bid.js"); + + std::string auction_config = JsReplace( + R"({ + seller: $1, + decisionLogicURL: $2, + // Signal to the top-level seller to allow participation in a component + // auction. + auctionSignals: "sellerAllowsComponentAuction", + componentAuctions: [{ + seller: $1, + decisionLogicURL: $2, + interestGroupBuyers: [$1], + // Signal to the bidder and component seller to allow participation in + // a component auction. + auctionSignals: "bidderAllowsComponentAuction,"+ + "sellerAllowsComponentAuction", + auctionNonce: $3, + additionalBids: provideAdditionalBids($1, $3, [JSON.stringify({ + interestGroup: { + name: 'campaign123', + biddingLogicURL: $5, + owner:$6 + }, + bid: { + ad: ['ad'], + bid: 1.99, + render: $4, + }, + auctionNonce: $3, + seller: $1, + })]) + }] + })", + url::Origin::Create(test_url), + https_server_->GetURL(kTestOrigin, "/interest_group/decision_logic.js"), + auction_nonce, additional_bid_ad_url, additional_bid_logic_url, + url::Origin::Create(additional_bid_logic_url)); + + RunAuctionAndWaitForURLAndNavigateIframe(auction_config, ad_url); + WaitForUrl(https_server_->GetURL(kTestOrigin, "/echoall?report_seller")); + WaitForUrl(https_server_->GetURL(kTestOrigin, "/echoall?report_bidder")); + EXPECT_FALSE(HasServerSeenUrl( + https_server_->GetURL(kTestOrigin, "/echoall?report_bidder_additional"))); +} + +// Here, the additional bid is on a component auction, and has no negative IG, +// so it does bid and win. +IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, + AdditionalBidOnComponentAuctionWithNoNegativeIGDoesBid) { + URLLoaderMonitor url_loader_monitor; + + constexpr char kTestOrigin[] = "a.test"; + GURL test_url = https_server_->GetURL(kTestOrigin, "/page_with_iframe.html"); + GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars"); + GURL additional_bid_ad_url = + https_server_->GetURL("c.test", "/echo?render_horses"); + + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + EXPECT_EQ(kSuccess, + JoinInterestGroupAndVerify( + blink::TestInterestGroupBuilder( + /*owner=*/url::Origin::Create(test_url), + /*name=*/"cars") + .SetBiddingUrl(https_server_->GetURL( + kTestOrigin, "/interest_group/bidding_logic.js")) + .SetAds(/*ads=*/{{{ad_url, /*metadata=*/absl::nullopt}}}) + .Build())); + + std::string auction_nonce = CreateAuctionNonceAndWait(); + + GURL additional_bid_logic_url = https_server_->GetURL( + kTestOrigin, "/interest_group/bidding_logic_additional_bid.js"); + + std::string auction_config = JsReplace( + R"({ + seller: $1, + decisionLogicURL: $2, + // Signal to the top-level seller to allow participation in a component + // auction. + auctionSignals: "sellerAllowsComponentAuction", + componentAuctions: [{ + seller: $1, + decisionLogicURL: $2, + interestGroupBuyers: [$1], + // Signal to the bidder and component seller to allow participation in + // a component auction. + auctionSignals: "bidderAllowsComponentAuction,"+ + "sellerAllowsComponentAuction", + auctionNonce: $3, + additionalBids: provideAdditionalBids($1, $3, [JSON.stringify({ + interestGroup: { + name: 'campaign123', + biddingLogicURL: $5, + owner:$6 + }, + bid: { + ad: ['ad'], + bid: 1.99, + render: $4, + }, + auctionNonce: $3, + seller: $1, + topLevelSeller: $1, + })]) + }] + })", + url::Origin::Create(test_url), + https_server_->GetURL(kTestOrigin, "/interest_group/decision_logic.js"), + auction_nonce, additional_bid_ad_url, additional_bid_logic_url, + url::Origin::Create(additional_bid_logic_url)); + + RunAuctionAndWaitForURLAndNavigateIframe(auction_config, + additional_bid_ad_url); + WaitForUrl(https_server_->GetURL(kTestOrigin, "/echoall?report_seller")); + WaitForUrl( + https_server_->GetURL(kTestOrigin, "/echoall?report_bidder_additional")); + EXPECT_FALSE(HasServerSeenUrl( + https_server_->GetURL(kTestOrigin, "/echoall?report_bidder"))); +} + } // namespace } // namespace content
diff --git a/content/browser/interest_group/interest_group_manager_impl.cc b/content/browser/interest_group/interest_group_manager_impl.cc index b9522f1..33e03a93 100644 --- a/content/browser/interest_group/interest_group_manager_impl.cc +++ b/content/browser/interest_group/interest_group_manager_impl.cc
@@ -249,10 +249,6 @@ if (group_keys.empty()) { return; } - for (const auto& group_key : group_keys) { - NotifyInterestGroupAccessed(InterestGroupObserver::kBid, group_key.owner, - group_key.name); - } impl_.AsyncCall(&InterestGroupStorage::RecordInterestGroupBids) .WithArgs(group_keys); } @@ -260,8 +256,6 @@ void InterestGroupManagerImpl::RecordInterestGroupWin( const blink::InterestGroupKey& group_key, const std::string& ad_json) { - NotifyInterestGroupAccessed(InterestGroupObserver::kWin, group_key.owner, - group_key.name); impl_.AsyncCall(&InterestGroupStorage::RecordInterestGroupWin) .WithArgs(group_key, std::move(ad_json)); }
diff --git a/content/browser/interest_group/interest_group_manager_impl.h b/content/browser/interest_group/interest_group_manager_impl.h index ed0e34c..f86bc74 100644 --- a/content/browser/interest_group/interest_group_manager_impl.h +++ b/content/browser/interest_group/interest_group_manager_impl.h
@@ -90,7 +90,16 @@ class CONTENT_EXPORT InterestGroupObserver : public base::CheckedObserver { public: - enum AccessType { kJoin, kLeave, kUpdate, kLoaded, kBid, kWin }; + enum AccessType { + kJoin, + kLeave, + kUpdate, + kLoaded, + kBid, + kAdditionalBid, + kWin, + kAdditionalBidWin + }; virtual void OnInterestGroupAccessed(const base::Time& access_time, AccessType type, const url::Origin& owner_origin, @@ -190,6 +199,7 @@ // Adds an entry to the bidding history for this interest group. void RecordInterestGroupBids(const blink::InterestGroupSet& groups); + // Adds an entry to the win history for this interest group. `ad_json` is a // piece of opaque data to identify the winning ad. void RecordInterestGroupWin(const blink::InterestGroupKey& group_key, @@ -341,6 +351,10 @@ k_anonymity_manager_ = std::move(k_anonymity_manager); } + void NotifyInterestGroupAccessed(InterestGroupObserver::AccessType type, + const url::Origin& owner_origin, + const std::string& name); + private: // InterestGroupUpdateManager calls private members to write updates to the // database. @@ -419,9 +433,6 @@ // To be called only by `update_manager_`. void ReportUpdateFailed(const blink::InterestGroupKey& group_key, bool parse_failure); - void NotifyInterestGroupAccessed(InterestGroupObserver::AccessType type, - const url::Origin& owner_origin, - const std::string& name); void OnGetInterestGroupsComplete( base::OnceCallback<void(std::vector<StorageInterestGroup>)> callback,
diff --git a/content/browser/interest_group/test_interest_group_manager_impl.h b/content/browser/interest_group/test_interest_group_manager_impl.h index 85975374..1475283 100644 --- a/content/browser/interest_group/test_interest_group_manager_impl.h +++ b/content/browser/interest_group/test_interest_group_manager_impl.h
@@ -97,7 +97,7 @@ std::vector<GURL> TakeReportUrlsOfType(ReportType report_type); // Returns all interest groups that bid, removing them from the internal list - // in the process. + // in the process. This is based on observer events, not database ones. std::vector<blink::InterestGroupKey> TakeInterestGroupsThatBid(); // Returns all K-anon sets that have been joined, removing them from the
diff --git a/content/browser/interest_group/test_interest_group_observer.cc b/content/browser/interest_group/test_interest_group_observer.cc index 16e89c5..a19bfa0 100644 --- a/content/browser/interest_group/test_interest_group_observer.cc +++ b/content/browser/interest_group/test_interest_group_observer.cc
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "content/browser/interest_group/interest_group_manager_impl.h" #include "content/common/content_export.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/origin.h" @@ -43,7 +44,7 @@ run_loop_->Run(); run_loop_.reset(); } - EXPECT_EQ(expected, accesses_); + EXPECT_THAT(accesses_, ::testing::UnorderedElementsAreArray(expected)); // Clear accesses so can be reused. accesses_.clear();
diff --git a/content/browser/media/capture/desktop_capture_device_mac.cc b/content/browser/media/capture/desktop_capture_device_mac.cc index 2fd521c9..b2fd6413 100644 --- a/content/browser/media/capture/desktop_capture_device_mac.cc +++ b/content/browser/media/capture/desktop_capture_device_mac.cc
@@ -6,7 +6,6 @@ #include <CoreGraphics/CoreGraphics.h> -#include "base/mac/wrap_cg_display.h" #include "base/task/single_thread_task_runner.h" #include "content/browser/media/capture/io_surface_capture_device_base_mac.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h" @@ -74,11 +73,9 @@ const size_t kNumKeys = 5; const void* keys[kNumKeys] = { - wrapkCGDisplayStreamShowCursor(), - wrapkCGDisplayStreamPreserveAspectRatio(), - wrapkCGDisplayStreamMinimumFrameTime(), - wrapkCGDisplayStreamColorSpace(), - wrapkCGDisplayStreamDestinationRect(), + kCGDisplayStreamShowCursor, kCGDisplayStreamPreserveAspectRatio, + kCGDisplayStreamMinimumFrameTime, kCGDisplayStreamColorSpace, + kCGDisplayStreamDestinationRect, }; const void* values[kNumKeys] = { kCFBooleanTrue, @@ -92,7 +89,7 @@ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); } - display_stream_.reset(wrapCGDisplayStreamCreate( + display_stream_.reset(CGDisplayStreamCreate( display_id_, requested_format_.frame_size.width(), requested_format_.frame_size.height(), kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, properties, handler)); @@ -102,7 +99,7 @@ FROM_HERE, "CGDisplayStreamCreate failed"); return; } - CGError error = wrapCGDisplayStreamStart(display_stream_); + CGError error = CGDisplayStreamStart(display_stream_); if (error != kCGErrorSuccess) { client()->OnError( media::VideoCaptureError::kDesktopCaptureDeviceMacFailedStreamStart, @@ -114,18 +111,17 @@ // worker thread where the CFRunLoop does not get serviced. // https://crbug.com/1185388 CFRunLoopAddSource(CFRunLoopGetMain(), - wrapCGDisplayStreamGetRunLoopSource(display_stream_), + CGDisplayStreamGetRunLoopSource(display_stream_), kCFRunLoopCommonModes); client()->OnStarted(); } void OnStop() override { weak_factory_.InvalidateWeakPtrs(); if (display_stream_) { - CFRunLoopRemoveSource( - CFRunLoopGetMain(), - wrapCGDisplayStreamGetRunLoopSource(display_stream_), - kCFRunLoopCommonModes); - wrapCGDisplayStreamStop(display_stream_); + CFRunLoopRemoveSource(CFRunLoopGetMain(), + CGDisplayStreamGetRunLoopSource(display_stream_), + kCFRunLoopCommonModes); + CGDisplayStreamStop(display_stream_); } display_stream_.reset(); }
diff --git a/content/browser/preloading/prerenderer_impl.cc b/content/browser/preloading/prerenderer_impl.cc index 59442c5..f7a55a5b 100644 --- a/content/browser/preloading/prerenderer_impl.cc +++ b/content/browser/preloading/prerenderer_impl.cc
@@ -179,13 +179,9 @@ // requests rejected by PrerenderHostRegistry can be filtered out. But // ideally PrerenderHostRegistry should implement the history management // mechanism by itself. - started_prerenders_.erase( - std::remove_if(started_prerenders_.begin(), started_prerenders_.end(), - [&](const PrerenderInfo& x) { - return base::Contains(removed_prerender_rules_set, - x.prerender_host_id); - }), - started_prerenders_.end()); + base::EraseIf(started_prerenders_, [&](const PrerenderInfo& x) { + return base::Contains(removed_prerender_rules_set, x.prerender_host_id); + }); } // Actually start the candidates once the diffing is done.
diff --git a/content/browser/renderer_host/cookie_utils.cc b/content/browser/renderer_host/cookie_utils.cc index 4770731..f4bd86f 100644 --- a/content/browser/renderer_host/cookie_utils.cc +++ b/content/browser/renderer_host/cookie_utils.cc
@@ -108,7 +108,9 @@ net::CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII) || status.HasExclusionReason( net::CookieInclusionStatus:: - EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET); + EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET) || + status.HasExclusionReason( + net::CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT); } } // namespace
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 7f31039..2b803d2 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -354,8 +354,6 @@ return GetContentClient()->browser()->GetUserAgentBasedOnPolicy(context); } -// TODO(clamy): This should match what's happening in -// blink::FrameFetchContext::addAdditionalRequestHeaders. void AddAdditionalRequestHeaders( net::HttpRequestHeaders* headers, const GURL& url,
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 8be5b50..9b55d24 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -1453,7 +1453,7 @@ // Must be initialized before the `url_loader_factory_getter_`. if (base::FeatureList::IsEnabled( - net::features::kCookieDeprecationFacilitatedTestingLabels)) { + features::kCookieDeprecationFacilitatedTesting)) { cookie_deprecation_label_manager_ = std::make_unique<CookieDeprecationLabelManagerImpl>(browser_context_); }
diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h index 09464fc..42adb68a 100644 --- a/content/browser/web_contents/web_contents_view_mac.h +++ b/content/browser/web_contents/web_contents_view_mac.h
@@ -216,6 +216,12 @@ // The id that may be used to look up this NSView. const uint64_t ns_view_id_; + // Bounding rect for the part at the top of the WebContents that is not + // covered by window controls when window controls overlay is enabled. + // This is cached here in case this rect is set before the web contents has + // been attached to a remote view. + gfx::Rect window_controls_overlay_bounding_rect_; + // The WebContentsViewCocoa that lives in the NSView hierarchy in this // process. This is always non-null, even when the view is being displayed // in another process.
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index fb3f42f..aac4d25 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -146,6 +146,7 @@ void WebContentsViewMac::UpdateWindowControlsOverlay( const gfx::Rect& bounding_rect) { + window_controls_overlay_bounding_rect_ = bounding_rect; if (remote_ns_view_) { remote_ns_view_->UpdateWindowControlsOverlay(bounding_rect); } else { @@ -641,6 +642,10 @@ remote_cocoa_application->CreateWebContentsNSView( ns_view_id_, std::move(stub_host), std::move(stub_ns_view_receiver)); remote_ns_view_->SetParentNSView(views_host_->GetNSViewId()); + if (!window_controls_overlay_bounding_rect_.IsEmpty()) { + remote_ns_view_->UpdateWindowControlsOverlay( + window_controls_overlay_bounding_rect_); + } // Because this view is being displayed from a remote process, reset the // in-process NSView's client pointer, so that the in-process NSView will
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 7645fbc..ae4626e7 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -363,8 +363,8 @@ raw_ref(network::features::kCompressionDictionaryTransport)}, {"CompressionDictionaryTransportBackend", raw_ref(network::features::kCompressionDictionaryTransportBackend)}, - {"CookieDeprecationFacilitatedTestingLabels", - raw_ref(net::features::kCookieDeprecationFacilitatedTestingLabels)}, + {"CookieDeprecationFacilitatedTesting", + raw_ref(features::kCookieDeprecationFacilitatedTesting)}, {"Database", raw_ref(blink::features::kWebSQLAccess), kSetOnlyIfOverridden}, {"Fledge", raw_ref(blink::features::kFledge), kSetOnlyIfOverridden}, {"Fledge", raw_ref(features::kPrivacySandboxAdsAPIsOverride),
diff --git a/content/public/README.md b/content/public/README.md index 2556133..0a6e99b 100644 --- a/content/public/README.md +++ b/content/public/README.md
@@ -77,9 +77,9 @@ ## Dependencies on content Large parts of the Chromium codebase depend on `//content/public`. Some notable -directories that depend on it are (parts of) `//extensions`, `//chrome`, -and `//weblayer`. Some directories in `//components` also depend on it, while -conversely `//content` depends on some components. +directories that depend on it are (parts of) `//extensions`, and `//chrome`. +Some directories in `//components` also depend on it, while conversely +`//content` depends on some components. Directories that do not depend on content include `//third_party/blink` and `//services`.
diff --git a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java index 16481eb..83875a98 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java
@@ -348,14 +348,12 @@ /** * Asserts that library process type is one of the supported types. * @param libraryProcessType the type of process the shared library is loaded. It must be - * LibraryProcessType.PROCESS_BROWSER, - * LibraryProcessType.PROCESS_WEBVIEW or - * LibraryProcessType.PROCESS_WEBLAYER. + * LibraryProcessType.PROCESS_BROWSER or + * LibraryProcessType.PROCESS_WEBVIEW. */ private void assertProcessTypeSupported(@LibraryProcessType int libraryProcessType) { assert LibraryProcessType.PROCESS_BROWSER == libraryProcessType - || LibraryProcessType.PROCESS_WEBVIEW == libraryProcessType - || LibraryProcessType.PROCESS_WEBLAYER == libraryProcessType; + || LibraryProcessType.PROCESS_WEBVIEW == libraryProcessType; LibraryLoader.getInstance().assertCompatibleProcessType(libraryProcessType); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/BrowserStartupController.java b/content/public/android/java/src/org/chromium/content_public/browser/BrowserStartupController.java index 54a8f00..cc9f3be 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/BrowserStartupController.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/BrowserStartupController.java
@@ -43,9 +43,8 @@ * Note that this can only be called on the UI thread. * * @param libraryProcessType the type of process the shared library is loaded. It must be - * LibraryProcessType.PROCESS_BROWSER, - * LibraryProcessType.PROCESS_WEBVIEW or - * LibraryProcessType.PROCESS_WEBLAYER. + * LibraryProcessType.PROCESS_BROWSER or + * LibraryProcessType.PROCESS_WEBVIEW. * @param startGpuProcess Whether to start the GPU process if it is not started. Only has * effect if browser isn't already started. * @param startMinimalBrowser Whether browser startup will be paused after a minimal environment @@ -63,9 +62,8 @@ * Note that this can only be called on the UI thread. * * @param libraryProcessType the type of process the shared library is loaded. It must be - * LibraryProcessType.PROCESS_BROWSER, - * LibraryProcessType.PROCESS_WEBVIEW or - * LibraryProcessType.PROCESS_WEBLAYER. + * LibraryProcessType.PROCESS_BROWSER or + * LibraryProcessType.PROCESS_WEBVIEW. * @param singleProcess true iff the browser should run single-process, ie. keep renderers in * the browser process * @param startGpuProcess Whether to start the GPU process if it is not started. Only has
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index b98e13c3..8c04d9642 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -163,6 +163,13 @@ "CompositeBGColorAnimation", base::FEATURE_DISABLED_BY_DEFAULT); +// Gate access to cookie deprecation API which allows developers to opt in +// server side testing without cookies. +// (See https://developer.chrome.com/en/docs/privacy-sandbox/chrome-testing) +BASE_FEATURE(kCookieDeprecationFacilitatedTesting, + "CookieDeprecationFacilitatedTesting", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables Blink cooperative scheduling. BASE_FEATURE(kCooperativeScheduling, "CooperativeScheduling",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 728bf12..f6e890d 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -48,6 +48,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE( kClearCrossSiteCrossBrowsingContextGroupWindowName); CONTENT_EXPORT BASE_DECLARE_FEATURE(kCompositeBGColorAnimation); +CONTENT_EXPORT BASE_DECLARE_FEATURE(kCookieDeprecationFacilitatedTesting); CONTENT_EXPORT BASE_DECLARE_FEATURE(kCooperativeScheduling); CONTENT_EXPORT BASE_DECLARE_FEATURE(kCrashReporting); CONTENT_EXPORT BASE_DECLARE_FEATURE(kDevicePosture);
diff --git a/content/services/auction_worklet/bidder_worklet.cc b/content/services/auction_worklet/bidder_worklet.cc index 1c8f35a..0b2f8f74 100644 --- a/content/services/auction_worklet/bidder_worklet.cc +++ b/content/services/auction_worklet/bidder_worklet.cc
@@ -927,8 +927,8 @@ ->CallFunction( context, debug_id_.get(), v8_helper_->FormatScriptName(unbound_worklet_script), - is_for_additional_bid ? "reportContextualWin" : "reportWin", args, - total_timeout.get(), errors_out) + is_for_additional_bid ? "reportAdditionalBidWin" : "reportWin", + args, total_timeout.get(), errors_out) .IsEmpty(); TRACE_EVENT_NESTABLE_ASYNC_END0("fledge", "report_win", trace_id);
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc index ca23de2..6cda9c4 100644 --- a/content/services/auction_worklet/bidder_worklet_unittest.cc +++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -5348,8 +5348,8 @@ sendReportTo("https://report-win.test/"); } - function reportContextualWin() { - sendReportTo("https://report-contextual-win.test/"); + function reportAdditionalBidWin() { + sendReportTo("https://report-additional-bid-win.test/"); } )"; @@ -5359,7 +5359,7 @@ is_for_additional_bid_ = true; RunReportWinWithJavascriptExpectingResult( - kScript, GURL("https://report-contextual-win.test/")); + kScript, GURL("https://report-additional-bid-win.test/")); } TEST_F(BidderWorkletTest, ReportWinReportingId) {
diff --git a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom index 2e6b6fe..f024d3f 100644 --- a/content/services/auction_worklet/public/mojom/bidder_worklet.mojom +++ b/content/services/auction_worklet/public/mojom/bidder_worklet.mojom
@@ -458,7 +458,7 @@ // be loaded first, if needed. // // Arguments: - // `is_for_additional_bid` If true, this will call reportContextualWin() + // `is_for_additional_bid` If true, this will call reportAdditionalBidWin() // rather than reportWin(). // // `reporting_id_field` Describes which kind of ad campaign identification
diff --git a/content/test/data/interest_group/bidding_logic_additional_bid.js b/content/test/data/interest_group/bidding_logic_additional_bid.js index 32cce6a0..36c8c28 100644 --- a/content/test/data/interest_group/bidding_logic_additional_bid.js +++ b/content/test/data/interest_group/bidding_logic_additional_bid.js
@@ -8,8 +8,8 @@ '/echoall?report_bidder_regular'); } -function reportContextualWin(auctionSignals, perBuyerSignals, sellerSignals, - browserSignals) { +function reportAdditionalBidWin(auctionSignals, perBuyerSignals, sellerSignals, + browserSignals) { sendReportTo(browserSignals.interestGroupOwner + '/echoall?report_bidder_additional'); }
diff --git a/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js b/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js index 658b0ba..e89b9ca 100644 --- a/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js +++ b/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js
@@ -9,8 +9,8 @@ '/echoall?report_bidder_regular'); } -function reportContextualWin(auctionSignals, perBuyerSignals, sellerSignals, - browserSignals) { +function reportAdditionalBidWin(auctionSignals, perBuyerSignals, sellerSignals, + browserSignals) { sendReportTo(browserSignals.interestGroupOwner + '/echoall?report_bidder_additional'); }
diff --git a/content/web_test/browser/test_info_extractor.cc b/content/web_test/browser/test_info_extractor.cc index 46da926..e94c6d6 100644 --- a/content/web_test/browser/test_info_extractor.cc +++ b/content/web_test/browser/test_info_extractor.cc
@@ -17,52 +17,10 @@ #include "content/web_test/common/web_test_switches.h" #include "net/base/filename_util.h" -#if BUILDFLAG(IS_IOS) -#include <filesystem> -#include <fstream> - -#include "base/files/file_util.h" -#include "base/threading/platform_thread.h" -#endif - namespace content { namespace { -#if BUILDFLAG(IS_IOS) -constexpr char kWebTestTestName[] = "webtest_test_name"; - -bool GetTempDirectory(base::FilePath& temp_dir) { - if (!base::GetTempDir(&temp_dir)) { - LOG(ERROR) << "GetTempDir failed."; - return false; - } - return true; -} - -std::fstream GetFileStreamToReadTestFileName() { - base::FilePath temp_dir; - if (!GetTempDirectory(temp_dir)) { - return std::fstream(); - } - - std::string test_input_file_path = - temp_dir.AppendASCII(kWebTestTestName).value(); - return std::fstream(test_input_file_path); -} - -void ClearFileNameInFileStream() { - base::FilePath temp_dir; - if (!GetTempDirectory(temp_dir)) { - return; - } - - // Truncate file. - std::filesystem::resize_file(temp_dir.AppendASCII(kWebTestTestName).value(), - 0); -} -#endif - std::unique_ptr<TestInfo> GetTestInfoFromWebTestName( const std::string& test_name, bool protocol_mode) { @@ -147,37 +105,11 @@ std::string test_string; bool protocol_mode = false; if (cmdline_args_[cmdline_position_] == FILE_PATH_LITERAL("-")) { -#if BUILDFLAG(IS_IOS) - // TODO(crbug.com/1421239): iOS port reads the test file through a file - // stream until using sockets for the communication between run_web_tests.py - // and content_shell. - std::fstream file_name_input = GetFileStreamToReadTestFileName(); - if (!file_name_input.is_open()) { - return nullptr; - } - do { - // Need to wait for a while to wait until write function of - // |server_process.py| writes a test name in the file. - base::PlatformThread::Sleep(base::Milliseconds(10)); - bool success = !!std::getline(file_name_input, test_string, '\n'); - if (!success) { - return nullptr; - } - } while (test_string.empty()); - // Clear the content of the file_name_input stream to ensure that the caller - // of GetNextTest doesn't repeatedly read the same test name until the next - // file name is written by the run_web_tests script. Since run_web_tests.py - // always writes a test name using 'wb' mode, clearing the content of the - // file stream is sufficient. - ClearFileNameInFileStream(); - file_name_input.close(); -#else do { bool success = !!std::getline(std::cin, test_string, '\n'); if (!success) return nullptr; } while (test_string.empty()); -#endif // BUILDFLAG(IS_IOS) protocol_mode = true; } else { #if BUILDFLAG(IS_WIN)
diff --git a/content/web_test/browser/web_test_browser_main_runner.cc b/content/web_test/browser/web_test_browser_main_runner.cc index a7fbd637f..2d0f3b5a 100644 --- a/content/web_test/browser/web_test_browser_main_runner.cc +++ b/content/web_test/browser/web_test_browser_main_runner.cc
@@ -52,10 +52,13 @@ #include "content/public/test/ppapi_test_utils.h" #endif -#if BUILDFLAG(IS_FUCHSIA) -#include <lib/sys/cpp/component_context.h> +#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_IOS) #include <sys/socket.h> #include <unistd.h> +#endif + +#if BUILDFLAG(IS_FUCHSIA) +#include <lib/sys/cpp/component_context.h> #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/process_context.h" @@ -66,7 +69,7 @@ namespace { -#if BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_IOS) // Fuchsia doesn't support stdin stream for packaged apps, and stdout from // run-test-suite not only has extra emissions from the Fuchsia test // infrastructure, it also merges stderr and stdout together. Combined, these @@ -75,6 +78,10 @@ // workaround this issue for web tests we redirect stdin and stdout to a TCP // socket connected to the web test runner. The runner uses --stdio-redirect to // specify address and port for stdin and stdout redirection. +// +// iOS is in a similar situation where the simulator does not support the use of +// the stdin stream for applications. Therefore, iOS also redirects stdin and +// stdout to a TCP socket that is connected to the web test runner. constexpr char kStdioRedirectSwitch[] = "stdio-redirect"; void ConnectStdioSocket(const std::string& host_and_port) { @@ -124,7 +131,7 @@ } void RunTests(content::BrowserMainRunner* main_runner) { -#if BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_IOS) if (auto& cmd_line = *base::CommandLine::ForCurrentProcess(); cmd_line.HasSwitch(kStdioRedirectSwitch)) { ConnectStdioSocket(cmd_line.GetSwitchValueASCII(kStdioRedirectSwitch));
diff --git a/docs/linux/chromium_packages.md b/docs/linux/chromium_packages.md index a8b1674..01b8d795 100644 --- a/docs/linux/chromium_packages.md +++ b/docs/linux/chromium_packages.md
@@ -11,7 +11,7 @@ |:-----------|:------------|:---------------------|:------------------------------------| | Ubuntu | Olivier Tilloy `olivier.tilloy@canonical.com` | https://launchpad.net/ubuntu/+source/chromium-browser | https://code.launchpad.net/~chromium-team | | Debian | chromium@packages.debian.org | https://tracker.debian.org/pkg/chromium | https://sources.debian.org/patches/chromium/ | -| openSUSE | Raymond Wooninck `tittiatcoke@gmail.com` | http://software.opensuse.org/search?baseproject=ALL&p=1&q=chromium | n/a | +| openSUSE | https://bugzilla.opensuse.org | https://software.opensuse.org/package/chromium | https://build.opensuse.org/package/show/openSUSE:Factory/chromium | | Arch | Evangelos Foutras `evangelos@foutrelis.com` | http://www.archlinux.org/packages/extra/x86_64/chromium/ | https://github.com/archlinux/svntogit-packages/tree/master/chromium/trunk | | Gentoo | http://www.gentoo.org/proj/en/desktop/chromium/index.xml | http://packages.gentoo.org/package/www-client/chromium | https://gitweb.gentoo.org/proj/chromium-tools.git/ | | ALT Linux | Andrey Cherepanov (Андрей Черепанов) `cas@altlinux.org` | http://packages.altlinux.org/en/Sisyphus/srpms/chromium | http://git.altlinux.org/gears/c/chromium.git?a=tree |
diff --git a/extensions/renderer/api/runtime_hooks_delegate.cc b/extensions/renderer/api/runtime_hooks_delegate.cc index e10dc94..85ca70b 100644 --- a/extensions/renderer/api/runtime_hooks_delegate.cc +++ b/extensions/renderer/api/runtime_hooks_delegate.cc
@@ -484,7 +484,8 @@ absl::optional<ModuleSystem::NativesEnabledScope> background_page_natives; if (background_page && background_page != script_context->GetRenderFrame() && - blink::WebFrame::ScriptCanAccess(background_page->GetWebFrame())) { + blink::WebFrame::ScriptCanAccess(isolate, + background_page->GetWebFrame())) { ScriptContext* background_page_script_context = GetScriptContextFromV8Context( background_page->GetWebFrame()->MainWorldScriptContext());
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc index f079d8e..6aeb131e 100644 --- a/extensions/renderer/extension_frame_helper.cc +++ b/extensions/renderer/extension_frame_helper.cc
@@ -180,8 +180,9 @@ if (!web_frame->IsOutermostMainFrame()) continue; - if (!blink::WebFrame::ScriptCanAccess(web_frame)) + if (!blink::WebFrame::ScriptCanAccess(context->GetIsolate(), web_frame)) { continue; + } v8::Local<v8::Context> frame_context = web_frame->MainWorldScriptContext(); if (!frame_context.IsEmpty()) { @@ -217,16 +218,13 @@ v8::Isolate* isolate, const std::string& extension_id) { content::RenderFrame* main_frame = GetBackgroundPageFrame(extension_id); - - v8::Local<v8::Value> background_page; blink::WebLocalFrame* web_frame = main_frame ? main_frame->GetWebFrame() : nullptr; - if (web_frame && blink::WebFrame::ScriptCanAccess(web_frame)) - background_page = web_frame->MainWorldScriptContext()->Global(); - else - background_page = v8::Undefined(isolate); - - return background_page; + if (web_frame && blink::WebFrame::ScriptCanAccess(isolate, web_frame)) { + return web_frame->MainWorldScriptContext()->Global(); + } else { + return v8::Undefined(isolate); + } } // static
diff --git a/extensions/renderer/object_backed_native_handler.cc b/extensions/renderer/object_backed_native_handler.cc index b9c51f6..57dc35f1c 100644 --- a/extensions/renderer/object_backed_native_handler.cc +++ b/extensions/renderer/object_backed_native_handler.cc
@@ -217,7 +217,8 @@ if (!other_script_context || !other_script_context->web_frame()) return allow_null_context; - return blink::WebFrame::ScriptCanAccess(other_script_context->web_frame()); + return blink::WebFrame::ScriptCanAccess(other_script_context->isolate(), + other_script_context->web_frame()); } bool ObjectBackedNativeHandler::SetPrivate(v8::Local<v8::Object> obj,
diff --git a/extensions/renderer/v8_context_native_handler.cc b/extensions/renderer/v8_context_native_handler.cc index 4b45455..2c5230ab 100644 --- a/extensions/renderer/v8_context_native_handler.cc +++ b/extensions/renderer/v8_context_native_handler.cc
@@ -69,8 +69,10 @@ CHECK(args[0]->IsObject()); ScriptContext* context = ScriptContextSet::GetContextByObject( v8::Local<v8::Object>::Cast(args[0])); - if (context && blink::WebFrame::ScriptCanAccess(context->web_frame())) + if (context && blink::WebFrame::ScriptCanAccess(args.GetIsolate(), + context->web_frame())) { args.GetReturnValue().Set(context->module_system()->NewInstance()); + } } } // namespace extensions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 31c445d6..01acc60 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3892,16 +3892,12 @@ driver_bug_workarounds.scalarizeVecAndMatConstructorArgs = true; if (workarounds().regenerate_struct_names) driver_bug_workarounds.regenerateStructNames = true; - if (workarounds().emulate_abs_int_function) - driver_bug_workarounds.emulateAbsIntFunction = true; if (workarounds().rewrite_texelfetchoffset_to_texelfetch) driver_bug_workarounds.rewriteTexelFetchOffsetToTexelFetch = true; if (workarounds().add_and_true_to_loop_condition) driver_bug_workarounds.addAndTrueToLoopCondition = true; if (workarounds().rewrite_do_while_loops) driver_bug_workarounds.rewriteDoWhileLoops = true; - if (workarounds().emulate_isnan_on_float) - driver_bug_workarounds.emulateIsnanFloatFunction = true; if (workarounds().use_unused_standard_shared_blocks) driver_bug_workarounds.useUnusedStandardSharedBlocks = true; if (workarounds().remove_invariant_and_centroid_for_essl3) @@ -14588,30 +14584,6 @@ } } } else { - if (workarounds().init_two_cube_map_levels_before_copyteximage && - texture->target() == GL_TEXTURE_CUBE_MAP && - target != GL_TEXTURE_CUBE_MAP_POSITIVE_X) { - for (int i = 0; i < 2; ++i) { - TextureManager::DoTexImageArguments args = { - target, - i, - final_internal_format, - width, - height, - 1, - border, - format, - type, - nullptr, - pixels_size, - 0, - TextureManager::DoTexImageArguments::CommandType::kTexImage2D}; - texture_manager()->WorkaroundCopyTexImageCubeMap( - &texture_state_, &state_, error_state_.get(), &framebuffer_state_, - texture_ref, func_name, args); - } - } - if (requires_luma_blit) { copy_tex_image_blit_->DoCopyTexImage2DToLUMACompatibilityTexture( this, texture->service_id(), texture->target(), target, format, type, @@ -14619,27 +14591,6 @@ GetBoundReadFramebufferServiceId(), GetBoundReadFramebufferInternalFormat()); } else { - if (workarounds().init_one_cube_map_level_before_copyteximage && - texture->target() == GL_TEXTURE_CUBE_MAP && - target != GL_TEXTURE_CUBE_MAP_POSITIVE_X) { - TextureManager::DoTexImageArguments args = { - target, - level, - final_internal_format, - width, - height, - 1, - border, - format, - type, - nullptr, - pixels_size, - 0, - TextureManager::DoTexImageArguments::CommandType::kTexImage2D}; - texture_manager()->WorkaroundCopyTexImageCubeMap( - &texture_state_, &state_, error_state_.get(), &framebuffer_state_, - texture_ref, func_name, args); - } if (workarounds().clear_pixel_unpack_buffer_before_copyteximage) state_.PushTextureUnpackState(); api()->glCopyTexImage2DFn(target, level, final_internal_format, x, y,
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm index af91028..07e16a5 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -662,18 +662,21 @@ // with other backings). texture_.Destroy(); - if (gl::GetANGLEImplementation() != gl::ANGLEImplementation::kMetal) { - // macOS has a global GPU command queue so synchronization between APIs and - // devices is automatic. However on Metal, wgpuQueueSubmit "commits" the - // Metal command buffers but they aren't "scheduled" in the global queue - // immediately. (that work seems offloaded to a different thread?) - // Wait for all the previous submitted commands to be scheduled to have - // scheduling races between commands using the IOSurface on different APIs. - // This isn't needed for ANGLE's Metal backend since it uses the above - // MTLSharedEvent to synchronize instead. - TRACE_EVENT0("gpu", "DawnIOSurfaceRepresentation::EndAccess"); - dawn::native::metal::WaitForCommandsToBeScheduled(device_.Get()); - } + // TODO(b/252731382): the following WaitForCommandsToBeScheduled call should + // no longer be necessary, but for some reason it is. Removing it + // reintroduces intermittent renders of black frames to the WebGPU canvas. + // This points to another synchronization bug not resolved by the use of + // MTLSharedEvent between Dawn and ANGLE's Metal backend. + // + // macOS has a global GPU command queue so synchronization between APIs and + // devices is automatic. However on Metal, wgpuQueueSubmit "commits" the + // Metal command buffers but they aren't "scheduled" in the global queue + // immediately. (that work seems offloaded to a different thread?) + // Wait for all the previous submitted commands to be scheduled to have + // scheduling races between commands using the IOSurface on different APIs. + // This is a blocking call but should be almost instant. + TRACE_EVENT0("gpu", "DawnIOSurfaceRepresentation::EndAccess"); + dawn::native::metal::WaitForCommandsToBeScheduled(device_.Get()); texture_ = nullptr; }
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index f46d0a0..952f981e 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -969,7 +969,6 @@ "vendor_id": "0x1002", "device_id": ["0x9440", "0x944a", "0x9488", "0x9490"], "features": [ - "disable_overlay_ca_layers", "disable_post_sub_buffers_for_onscreen_surfaces" ] }, @@ -1163,23 +1162,6 @@ ] }, { - "id": 158, - "description": "IOSurface use becomes pathologically slow over time on 10.10.", - "cr_bugs": [580616], - "os": { - "type": "macosx", - "version": { - "op": "=", - "value": "10.10" - } - }, - "vendor_id": "0x10de", - "device_id": ["0x0fd5"], - "features": [ - "disable_overlay_ca_layers" - ] - }, - { "id": 159, "cr_bugs": [570897], "description": "Framebuffer discarding can hurt performance on non-tilers", @@ -1411,18 +1393,6 @@ ] }, { - "id": 183, - "description": "Result of abs(i) where i is an integer in vertex shader is wrong", - "cr_bugs": [642227], - "os": { - "type": "macosx" - }, - "vendor_id": "0x8086", - "features": [ - "emulate_abs_int_function" - ] - }, - { "id": 184, "description": "Rewrite texelFetchOffset to texelFetch for Intel Mac", "cr_bugs": [642605], @@ -1478,22 +1448,6 @@ ] }, { - "id": 189, - "description": "Do TexImage2D first before CopyTexImage2D for cube map texture on Intel Mac 10.11", - "cr_bugs": [648197], - "os": { - "type": "macosx", - "version": { - "op": "<=", - "value": "10.11" - } - }, - "vendor_id": "0x8086", - "features": [ - "init_one_cube_map_level_before_copyteximage" - ] - }, - { "id": 190, "description": "Disable partial swaps on Mesa drivers (detected with GL_VERSION)", "cr_bugs": [339493], @@ -1507,24 +1461,6 @@ ] }, { - "id": 191, - "description": "Emulate GLSL function isnan() on Intel Mac", - "cr_bugs": [650547], - "os": { - "type": "macosx", - "version": { - "op": "<", - "value": "10.13.2" - } - }, - "intel_gpu_series" : [ - "skylake" - ], - "features" : [ - "emulate_isnan_on_float" - ] - }, - { "id": 192, "description": "Decode and encode before generateMipmap for srgb format textures on os except macosx", "cr_bugs": [634519], @@ -1556,22 +1492,6 @@ ] }, { - "id": 194, - "description": "Init first two levels before CopyTexImage2D for cube map texture on Intel Mac 10.12", - "cr_bugs": [648197], - "os": { - "type": "macosx", - "version": { - "op": ">=", - "value": "10.12" - } - }, - "vendor_id": "0x8086", - "features": [ - "init_two_cube_map_levels_before_copyteximage" - ] - }, - { "id": 195, "description": "Insert statements to reference all members in unused std140/shared blocks on Mac", "cr_bugs": [618464], @@ -2417,19 +2337,6 @@ ] }, { - "id": 279, - "description": "WindowServer crashes on VMWare bots using CA renderer", - "cr_bugs": [828031], - "os": { - "type": "macosx" - }, - "vendor_id": "0x15ad", - "multi_gpu_category": "any", - "features": [ - "disable_overlay_ca_layers" - ] - }, - { "id": 280, "description": "ReadPixels is broken with EXT_multisampled_render_to_texture on recent Adreno drivers.", "cr_bugs": [890002],
diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt index 07e5880..e70eafd 100644 --- a/gpu/config/gpu_workaround_list.txt +++ b/gpu/config/gpu_workaround_list.txt
@@ -49,7 +49,6 @@ disable_multisampling_color_mask_usage disable_nv12_dxgi_video disable_nv12_dynamic_textures -disable_overlay_ca_layers disable_post_sub_buffers_for_onscreen_surfaces disable_program_cache disable_program_caching_for_transform_feedback @@ -68,8 +67,6 @@ dont_initialize_uninitialized_locals dont_use_eglclientwaitsync_with_timeout dont_use_loops_to_initialize_variables -emulate_abs_int_function -emulate_isnan_on_float enable_bgra8_overlays_with_yuv_overlay_support enable_webgl_timer_query_extensions etc1_power_of_two_only @@ -90,9 +87,7 @@ force_update_scissor_state_when_binding_fbo0 gl_clear_broken init_gl_position_in_vertex_shader -init_one_cube_map_level_before_copyteximage init_texture_max_anisotropy -init_two_cube_map_levels_before_copyteximage init_vertex_attributes limit_d3d11_video_decoder_to_11_0 max_3d_array_texture_size_1024
diff --git a/infra/config/generated/builders/ci/CFI Linux CF/properties.json b/infra/config/generated/builders/ci/CFI Linux CF/properties.json index 257f84c..a8e6d4f 100644 --- a/infra/config/generated/builders/ci/CFI Linux CF/properties.json +++ b/infra/config/generated/builders/ci/CFI Linux CF/properties.json
@@ -1,4 +1,47 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "CFI Linux CF", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "clusterfuzz_archive": { + "archive_name_prefix": "cfi", + "gs_acl": "public-read", + "gs_bucket": "chromium-browser-cfi" + }, + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium", + "target_bits": 64 + }, + "legacy_gclient_config": { + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "CFI Linux CF", + "project": "chromium" + } + ] + } + }, "$build/reclient": { "instance": "rbe-chromium-trusted", "jobs": 250,
diff --git a/infra/config/generated/builders/ci/CFI Linux ToT/properties.json b/infra/config/generated/builders/ci/CFI Linux ToT/properties.json index 3fa5f41e..2aa18cb 100644 --- a/infra/config/generated/builders/ci/CFI Linux ToT/properties.json +++ b/infra/config/generated/builders/ci/CFI Linux ToT/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "CFI Linux ToT", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "CFI Linux ToT", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/CrWinAsan\050dll\051/properties.json" "b/infra/config/generated/builders/ci/CrWinAsan\050dll\051/properties.json" index 3fa5f41e..765445d1 100644 --- "a/infra/config/generated/builders/ci/CrWinAsan\050dll\051/properties.json" +++ "b/infra/config/generated/builders/ci/CrWinAsan\050dll\051/properties.json"
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "CrWinAsan(dll)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_asan_tot", + "target_bits": 32 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "CrWinAsan(dll)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/CrWinAsan/properties.json b/infra/config/generated/builders/ci/CrWinAsan/properties.json index 3fa5f41e..e01f7de 100644 --- a/infra/config/generated/builders/ci/CrWinAsan/properties.json +++ b/infra/config/generated/builders/ci/CrWinAsan/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "CrWinAsan", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_asan_tot", + "target_bits": 32 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "CrWinAsan", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTAndroid \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/ToTAndroid \050dbg\051/properties.json" index 3fa5f41e..69e4b63 100644 --- "a/infra/config/generated/builders/ci/ToTAndroid \050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTAndroid \050dbg\051/properties.json"
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroid (dbg)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "clang_builder_mb_x64" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "clang_tot_android", + "target_arch": "arm", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroid (dbg)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTAndroid x64/properties.json b/infra/config/generated/builders/ci/ToTAndroid x64/properties.json index 3fa5f41e..91ff7ac 100644 --- a/infra/config/generated/builders/ci/ToTAndroid x64/properties.json +++ b/infra/config/generated/builders/ci/ToTAndroid x64/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroid x64", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "clang_builder_mb_x64" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_android", + "target_arch": "intel", + "target_bits": 64, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroid x64", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTAndroid x86/properties.json b/infra/config/generated/builders/ci/ToTAndroid x86/properties.json index 3fa5f41e..780b963b 100644 --- a/infra/config/generated/builders/ci/ToTAndroid x86/properties.json +++ b/infra/config/generated/builders/ci/ToTAndroid x86/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroid x86", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "clang_builder_mb_x64" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_android", + "target_arch": "intel", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroid x86", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTAndroid/properties.json b/infra/config/generated/builders/ci/ToTAndroid/properties.json index 3fa5f41e..41ce904e 100644 --- a/infra/config/generated/builders/ci/ToTAndroid/properties.json +++ b/infra/config/generated/builders/ci/ToTAndroid/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroid", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "clang_builder_mb_x64" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_android", + "target_arch": "arm", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroid", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTAndroid64/properties.json b/infra/config/generated/builders/ci/ToTAndroid64/properties.json index 3fa5f41e..570d6398 100644 --- a/infra/config/generated/builders/ci/ToTAndroid64/properties.json +++ b/infra/config/generated/builders/ci/ToTAndroid64/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroid64", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "clang_builder_mb_x64" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_android", + "target_arch": "arm", + "target_bits": 64, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroid64", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTAndroidASan/properties.json b/infra/config/generated/builders/ci/ToTAndroidASan/properties.json index 3fa5f41e..4674fe0 100644 --- a/infra/config/generated/builders/ci/ToTAndroidASan/properties.json +++ b/infra/config/generated/builders/ci/ToTAndroidASan/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroidASan", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "asan_symbolize" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_android_asan", + "target_arch": "arm", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroidASan", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTAndroidCoverage x86/properties.json b/infra/config/generated/builders/ci/ToTAndroidCoverage x86/properties.json index 3fa5f41e..874e804 100644 --- a/infra/config/generated/builders/ci/ToTAndroidCoverage x86/properties.json +++ b/infra/config/generated/builders/ci/ToTAndroidCoverage x86/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroidCoverage x86", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "clang_builder_mb_x64" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_android", + "target_arch": "intel", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroidCoverage x86", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTAndroidOfficial/properties.json b/infra/config/generated/builders/ci/ToTAndroidOfficial/properties.json index 3fa5f41e..2dc20ca 100644 --- a/infra/config/generated/builders/ci/ToTAndroidOfficial/properties.json +++ b/infra/config/generated/builders/ci/ToTAndroidOfficial/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTAndroidOfficial", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "clang_builder_mb_x64" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_android", + "target_arch": "arm", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTAndroidOfficial", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTChromeOS \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/ToTChromeOS \050dbg\051/properties.json" index 3fa5f41e..6344e62 100644 --- "a/infra/config/generated/builders/ci/ToTChromeOS \050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTChromeOS \050dbg\051/properties.json"
@@ -1,4 +1,47 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTChromeOS (dbg)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "clang_tot_chromeos", + "target_bits": 64, + "target_platform": "chromeos" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "chromeos" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTChromeOS (dbg)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTChromeOS/properties.json b/infra/config/generated/builders/ci/ToTChromeOS/properties.json index 3fa5f41e..c5d3124 100644 --- a/infra/config/generated/builders/ci/ToTChromeOS/properties.json +++ b/infra/config/generated/builders/ci/ToTChromeOS/properties.json
@@ -1,4 +1,47 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTChromeOS", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_chromeos", + "target_bits": 64, + "target_platform": "chromeos" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "chromeos" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTChromeOS", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTFuchsia x64/properties.json b/infra/config/generated/builders/ci/ToTFuchsia x64/properties.json index 3fa5f41e..6e608d47 100644 --- a/infra/config/generated/builders/ci/ToTFuchsia x64/properties.json +++ b/infra/config/generated/builders/ci/ToTFuchsia x64/properties.json
@@ -1,4 +1,49 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTFuchsia x64", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_fuchsia", + "target_bits": 64, + "target_platform": "fuchsia" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "fuchsia_x64", + "fuchsia_no_hooks" + ], + "config": "chromium" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTFuchsia x64", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTFuchsiaOfficial arm64/properties.json b/infra/config/generated/builders/ci/ToTFuchsiaOfficial arm64/properties.json index 3fa5f41e..45174f34 100644 --- a/infra/config/generated/builders/ci/ToTFuchsiaOfficial arm64/properties.json +++ b/infra/config/generated/builders/ci/ToTFuchsiaOfficial arm64/properties.json
@@ -1,4 +1,51 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTFuchsiaOfficial arm64", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_fuchsia", + "target_bits": 64, + "target_platform": "fuchsia" + }, + "legacy_gclient_config": { + "apply_configs": [ + "checkout_pgo_profiles", + "clang_tot", + "fuchsia_arm64", + "fuchsia_arm64_host", + "fuchsia_no_hooks" + ], + "config": "chromium" + }, + "run_tests_serially": true + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTFuchsiaOfficial arm64", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTLinux \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/ToTLinux \050dbg\051/properties.json" index 3fa5f41e..2a72e02 100644 --- "a/infra/config/generated/builders/ci/ToTLinux \050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTLinux \050dbg\051/properties.json"
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinux (dbg)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "clang_tot_linux", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinux (dbg)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTLinux/properties.json b/infra/config/generated/builders/ci/ToTLinux/properties.json index 3fa5f41e..074e141 100644 --- a/infra/config/generated/builders/ci/ToTLinux/properties.json +++ b/infra/config/generated/builders/ci/ToTLinux/properties.json
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinux", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinux", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTLinuxASan/properties.json b/infra/config/generated/builders/ci/ToTLinuxASan/properties.json index 3fa5f41e..2b9e5f15 100644 --- a/infra/config/generated/builders/ci/ToTLinuxASan/properties.json +++ b/infra/config/generated/builders/ci/ToTLinuxASan/properties.json
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinuxASan", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux_asan", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinuxASan", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTLinuxASanLibfuzzer/properties.json b/infra/config/generated/builders/ci/ToTLinuxASanLibfuzzer/properties.json index 3fa5f41e..e14fa87 100644 --- a/infra/config/generated/builders/ci/ToTLinuxASanLibfuzzer/properties.json +++ b/infra/config/generated/builders/ci/ToTLinuxASanLibfuzzer/properties.json
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinuxASanLibfuzzer", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux_asan", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinuxASanLibfuzzer", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTLinuxMSan/properties.json b/infra/config/generated/builders/ci/ToTLinuxMSan/properties.json index 3fa5f41e..1a37422 100644 --- a/infra/config/generated/builders/ci/ToTLinuxMSan/properties.json +++ b/infra/config/generated/builders/ci/ToTLinuxMSan/properties.json
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinuxMSan", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinuxMSan", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTLinuxPGO/properties.json b/infra/config/generated/builders/ci/ToTLinuxPGO/properties.json index 3fa5f41e..106a70c7 100644 --- a/infra/config/generated/builders/ci/ToTLinuxPGO/properties.json +++ b/infra/config/generated/builders/ci/ToTLinuxPGO/properties.json
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinuxPGO", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinuxPGO", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTLinuxTSan/properties.json b/infra/config/generated/builders/ci/ToTLinuxTSan/properties.json index 3fa5f41e..75fcee1 100644 --- a/infra/config/generated/builders/ci/ToTLinuxTSan/properties.json +++ b/infra/config/generated/builders/ci/ToTLinuxTSan/properties.json
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinuxTSan", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinuxTSan", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTLinuxUBSanVptr/properties.json b/infra/config/generated/builders/ci/ToTLinuxUBSanVptr/properties.json index 3fa5f41e..534f025 100644 --- a/infra/config/generated/builders/ci/ToTLinuxUBSanVptr/properties.json +++ b/infra/config/generated/builders/ci/ToTLinuxUBSanVptr/properties.json
@@ -1,4 +1,46 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTLinuxUBSanVptr", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_linux_ubsan_vptr", + "target_arch": "intel", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTLinuxUBSanVptr", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTMac \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/ToTMac \050dbg\051/properties.json" index 9ae3aa63..d10883c 100644 --- "a/infra/config/generated/builders/ci/ToTMac \050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTMac \050dbg\051/properties.json"
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTMac (dbg)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "clang_tot_mac", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTMac (dbg)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTMac/properties.json b/infra/config/generated/builders/ci/ToTMac/properties.json index 9ae3aa63..78f64e0a 100644 --- a/infra/config/generated/builders/ci/ToTMac/properties.json +++ b/infra/config/generated/builders/ci/ToTMac/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTMac", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_mac", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTMac", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTMacASan/properties.json b/infra/config/generated/builders/ci/ToTMacASan/properties.json index 9ae3aa63..a263965 100644 --- a/infra/config/generated/builders/ci/ToTMacASan/properties.json +++ b/infra/config/generated/builders/ci/ToTMacASan/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTMacASan", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "clang_tot_mac_asan", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTMacASan", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTWin\050dbg\051/properties.json" "b/infra/config/generated/builders/ci/ToTWin\050dbg\051/properties.json" index 3fa5f41e..5c0e21e 100644 --- "a/infra/config/generated/builders/ci/ToTWin\050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTWin\050dbg\051/properties.json"
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWin(dbg)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "chromium_win_clang_tot", + "target_bits": 32 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWin(dbg)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTWin\050dll\051/properties.json" "b/infra/config/generated/builders/ci/ToTWin\050dll\051/properties.json" index 3fa5f41e..56b03d0 100644 --- "a/infra/config/generated/builders/ci/ToTWin\050dll\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTWin\050dll\051/properties.json"
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWin(dll)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_tot", + "target_bits": 32 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWin(dll)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTWin/properties.json b/infra/config/generated/builders/ci/ToTWin/properties.json index 3fa5f41e..d03040dc 100644 --- a/infra/config/generated/builders/ci/ToTWin/properties.json +++ b/infra/config/generated/builders/ci/ToTWin/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWin", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_tot", + "target_bits": 32 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWin", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTWin64\050dbg\051/properties.json" "b/infra/config/generated/builders/ci/ToTWin64\050dbg\051/properties.json" index 3fa5f41e..c9c051c3 100644 --- "a/infra/config/generated/builders/ci/ToTWin64\050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTWin64\050dbg\051/properties.json"
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWin64(dbg)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Debug", + "config": "chromium_win_clang_tot", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWin64(dbg)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git "a/infra/config/generated/builders/ci/ToTWin64\050dll\051/properties.json" "b/infra/config/generated/builders/ci/ToTWin64\050dll\051/properties.json" index 3fa5f41e..866a084 100644 --- "a/infra/config/generated/builders/ci/ToTWin64\050dll\051/properties.json" +++ "b/infra/config/generated/builders/ci/ToTWin64\050dll\051/properties.json"
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWin64(dll)", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_tot", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWin64(dll)", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTWin64/properties.json b/infra/config/generated/builders/ci/ToTWin64/properties.json index 3fa5f41e..4330c548 100644 --- a/infra/config/generated/builders/ci/ToTWin64/properties.json +++ b/infra/config/generated/builders/ci/ToTWin64/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWin64", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_tot", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWin64", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTWin64PGO/properties.json b/infra/config/generated/builders/ci/ToTWin64PGO/properties.json index 3fa5f41e..5dc6c8c 100644 --- a/infra/config/generated/builders/ci/ToTWin64PGO/properties.json +++ b/infra/config/generated/builders/ci/ToTWin64PGO/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWin64PGO", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_tot", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWin64PGO", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTWinASanLibfuzzer/properties.json b/infra/config/generated/builders/ci/ToTWinASanLibfuzzer/properties.json index 3fa5f41e..e93d0f0 100644 --- a/infra/config/generated/builders/ci/ToTWinASanLibfuzzer/properties.json +++ b/infra/config/generated/builders/ci/ToTWinASanLibfuzzer/properties.json
@@ -1,4 +1,45 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTWinASanLibfuzzer", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_asan_tot", + "target_bits": 64 + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTWinASanLibfuzzer", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTiOS/properties.json b/infra/config/generated/builders/ci/ToTiOS/properties.json index 9ae3aa63..634bac38 100644 --- a/infra/config/generated/builders/ci/ToTiOS/properties.json +++ b/infra/config/generated/builders/ci/ToTiOS/properties.json
@@ -1,4 +1,47 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTiOS", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb", + "mac_toolchain" + ], + "build_config": "Release", + "config": "clang_tot_ios", + "target_bits": 64, + "target_platform": "ios" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "ios" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTiOS", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/ToTiOSDevice/properties.json b/infra/config/generated/builders/ci/ToTiOSDevice/properties.json index 9ae3aa63..c862996 100644 --- a/infra/config/generated/builders/ci/ToTiOSDevice/properties.json +++ b/infra/config/generated/builders/ci/ToTiOSDevice/properties.json
@@ -1,4 +1,47 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "ToTiOSDevice", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb", + "mac_toolchain" + ], + "build_config": "Release", + "config": "clang_tot_ios", + "target_bits": 64, + "target_platform": "ios" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot" + ], + "config": "ios" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "ToTiOSDevice", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/builders/ci/linux-win_cross-rel/properties.json b/infra/config/generated/builders/ci/linux-win_cross-rel/properties.json index 3fa5f41e..93aabfcf 100644 --- a/infra/config/generated/builders/ci/linux-win_cross-rel/properties.json +++ b/infra/config/generated/builders/ci/linux-win_cross-rel/properties.json
@@ -1,4 +1,47 @@ { + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "linux-win_cross-rel", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-clang-archive", + "builder_group": "chromium.clang", + "execution_mode": "COMPILE_AND_TEST", + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "chromium_win_clang_tot", + "target_bits": 64, + "target_platform": "win" + }, + "legacy_gclient_config": { + "apply_configs": [ + "clang_tot", + "win" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "linux-win_cross-rel", + "project": "chromium" + } + ] + } + }, "$recipe_engine/resultdb/test_presentation": { "column_keys": [], "grouping_keys": [
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg index cd80a26..ee5d8fb 100644 --- a/infra/config/generated/luci/realms.cfg +++ b/infra/config/generated/luci/realms.cfg
@@ -523,6 +523,7 @@ } bindings { role: "role/buildbucket.triggerer" + principals: "group:mdb/foundry-x-team" principals: "group:project-chromium-ci-schedulers" } }
diff --git a/infra/config/generated/testing/gn_isolate_map.pyl b/infra/config/generated/testing/gn_isolate_map.pyl index 6ef0d30..28aa498 100644 --- a/infra/config/generated/testing/gn_isolate_map.pyl +++ b/infra/config/generated/testing/gn_isolate_map.pyl
@@ -2,7 +2,7 @@ # Instead: # 1. Modify //infra/config/targets/targets.star # 2. Run //infra/config/main.star -# 3. Run //infra/config/scripts/sync-py-files.py +# 3. Run //infra/config/scripts/sync-pyl-files.py { "absl_hardening_tests": {
diff --git a/infra/config/generated/testing/mixins.pyl b/infra/config/generated/testing/mixins.pyl index 236d85e..b8aac13 100644 --- a/infra/config/generated/testing/mixins.pyl +++ b/infra/config/generated/testing/mixins.pyl
@@ -2,7 +2,7 @@ # Instead: # 1. Modify //infra/config/targets/mixins.star # 2. Run //infra/config/main.star -# 3. Run //infra/config/scripts/sync-py-files.py +# 3. Run //infra/config/scripts/sync-pyl-files.py { '10-x86-emulator': {
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index 1d77022..628d07f 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -2,7 +2,7 @@ # Instead: # 1. Modify //infra/config/targets/variants.star # 2. Run //infra/config/main.star -# 3. Run //infra/config/scripts/sync-py-files.py +# 3. Run //infra/config/scripts/sync-pyl-files.py { 'DISABLE_FIELD_TRIAL_CONFIG': { @@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 119.0.6017.0', + 'description': 'Run with ash-chrome version 119.0.6018.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v119.0.6017.0', - 'revision': 'version:119.0.6017.0', + 'location': 'lacros_version_skew_tests_v119.0.6018.0', + 'revision': 'version:119.0.6018.0', }, ], },
diff --git a/infra/config/lib/builder_health_indicators.star b/infra/config/lib/builder_health_indicators.star index 95e1e31..18ce3a4 100644 --- a/infra/config/lib/builder_health_indicators.star +++ b/infra/config/lib/builder_health_indicators.star
@@ -56,7 +56,13 @@ def modified_default(**kwargs): return structs.evolve(_default_thresholds, **kwargs) -def register_health_spec(bucket, name, spec): +def _exempted_from_contact(bucket, builder): + return builder in _exempted_from_contact_builders.get(bucket, []) + +def register_health_spec(bucket, name, spec, contact_team_email): + if not contact_team_email and not _exempted_from_contact(bucket, name): + fail("Builder " + name + " must have a contact_team_email. All new builders must specify a team email for contact in case the builder stops being healthy or providing value.") + if spec: health_spec_key = _HEALTH_SPEC.add( bucket, @@ -82,6 +88,949 @@ ctx.output["health-specs/health-specs.json"] = json.indent(json.encode(result), indent = " ") +# This dict should NOT be added to. It contains a list of builders that are exempted from needing a contact_team_email field. +# It's intended as a stopgap for older builders. All new builders should have a contact_team_email field for the good of our code and CI system. +# Builders should be removed from here once their contact is assigned. +_exempted_from_contact_builders = { + "ci": [ + "3pp-linux-amd64-packager", + "3pp-mac-amd64-packager", + "ASAN Debug", + "ASAN Release Media", + "ASAN Release", + "ASan Debug (32-bit x86 with V8-ARM)", + "ASan Release (32-bit x86 with V8-ARM)", + "ASan Release Media (32-bit x86 with V8-ARM)", + "Blink Unexpected Pass Finder", + "Cast Audio Linux", + "Cast Linux ARM64", + "Cast Linux Debug", + "Cast Linux", + "Centipede Upload Linux ASan", + "ChromiumOS ASAN Release", + "Comparison Android (reclient) (reproxy cache)", + "Comparison Android (reclient)", + "Comparison Android (reclient)(CQ)", + "Comparison Linux (reclient)", + "Comparison Linux (reclient)(CQ)", + "Comparison Mac (reclient)", + "Comparison Mac (reclient)(CQ)", + "Comparison Mac arm64 (reclient)", + "Comparison Mac arm64 on arm64 (reclient)", + "Comparison Simple Chrome (reclient)", + "Comparison Simple Chrome (reclient)(CQ)", + "Comparison Windows (8 cores) (reclient)", + "Comparison Windows (reclient)", + "Comparison Windows (reclient)(CQ)", + "Comparison ios (reclient)", + "Comparison ios (reclient)(CQ)", + "Dawn Linux x64 Builder", + "Dawn Linux x64 DEPS Builder", + "Dawn Linux x64 DEPS Release (Intel UHD 630)", + "Dawn Linux x64 DEPS Release (NVIDIA)", + "Dawn Linux x64 Release (Intel UHD 630)", + "Dawn Linux x64 Release (NVIDIA)", + "Dawn Mac x64 Builder", + "Dawn Mac x64 DEPS Builder", + "Dawn Mac x64 DEPS Release (AMD)", + "Dawn Mac x64 DEPS Release (Intel)", + "Dawn Mac x64 Experimental Release (AMD)", + "Dawn Mac x64 Experimental Release (Intel)", + "Dawn Mac x64 Release (AMD)", + "Dawn Mac x64 Release (Intel)", + "Dawn Win10 x64 Builder", + "Dawn Win10 x64 DEPS Builder", + "Dawn Win10 x64 DEPS Release (Intel)", + "Dawn Win10 x64 DEPS Release (NVIDIA)", + "Dawn Win10 x64 Experimental Release (Intel)", + "Dawn Win10 x64 Release (Intel)", + "Dawn Win10 x64 Release (NVIDIA)", + "Dawn Win10 x86 Builder", + "Dawn Win10 x86 DEPS Builder", + "Dawn Win10 x86 DEPS Release (NVIDIA)", + "Dawn Win10 x86 Experimental Release (Intel)", + "Dawn Win10 x86 Release (Intel)", + "Dawn Win10 x86 Release (NVIDIA)", + "GPU FYI Win Builder", + "GPU FYI Win x64 Builder (dbg)", + "GPU Linux Builder (dbg)", + "GPU Mac Builder (dbg)", + "GPU Win x64 Builder (dbg)", + "Leak Detection Linux", + "Libfuzzer Upload Chrome OS ASan", + "Libfuzzer Upload Linux ASan Debug", + "Libfuzzer Upload Linux ASan", + "Libfuzzer Upload Linux MSan", + "Libfuzzer Upload Linux UBSan", + "Libfuzzer Upload Linux V8-ARM64 ASan Debug", + "Libfuzzer Upload Linux V8-ARM64 ASan", + "Libfuzzer Upload Linux32 ASan", + "Libfuzzer Upload Linux32 V8-ARM ASan Debug", + "Libfuzzer Upload Linux32 V8-ARM ASan", + "Libfuzzer Upload Mac ASan", + "Libfuzzer Upload Windows ASan", + "Libfuzzer Upload iOS Catalyst Debug", + "Linux ASan LSan Builder", + "Linux ASan LSan Tests (1)", + "Linux ASan Tests (sandboxed)", + "Linux Builder (Wayland)", + "Linux Builder (reclient compare)", + "Linux CFI", + "Linux Chromium OS ASan LSan Builder", + "Linux Chromium OS ASan LSan Tests (1)", + "Linux ChromiumOS Full", + "Linux ChromiumOS MSan Builder", + "Linux ChromiumOS MSan Tests", + "Linux Debug (NVIDIA)", + "Linux FYI Experimental Release (NVIDIA)", + "Linux MSan Builder", + "Linux MSan Tests", + "Linux TSan Builder", + "Linux TSan Tests", + "Linux Tests (Wayland)", + "Linux Viz", + "MSAN Release (chained origins)", + "MSAN Release (no origins)", + "Mac ASAN Release Media", + "Mac ASAN Release", + "Mac ASan 64 Builder", + "Mac ASan 64 Tests (1)", + "Mac Builder (reclient compare)", + "Mac Builder Next", + "Mac Debug (Intel)", + "Mac deterministic (dbg)", + "Mac deterministic", + "Mac12 Tests", + "Mac13 Tests (dbg)", + "Mac13 Tests", + "Network Service Linux", + "Oreo Phone Tester", + "Site Isolation Android", + "TSAN Debug", + "TSAN Release", + "UBSan Release", + "UBSan vptr Release", + "WebKit Linux ASAN", + "WebKit Linux Leak", + "WebKit Linux MSAN", + "WebKit Win10", + "Win 10 Fast Ring", + "Win ASan Release Media", + "Win ASan Release", + "Win Builder (dbg)", + "Win Builder", + "Win x64 Builder (dbg)", + "Win x64 Builder (reclient compare)", + "Win x64 Builder (reclient)", + "Win x64 Builder", + "Win10 FYI x64 Exp Release (NVIDIA)", + "Win10 Tests x64 (dbg)", + "Win10 Tests x64", + "Win11 Tests x64", + "Windows deterministic", + "android-11-x86-fyi-rel", + "android-11-x86-rel", + "android-12-x64-dbg-tests", + "android-12-x64-fyi-rel", + "android-12l-x64-fyi-dbg", + "android-13-x64-fyi-rel", + "android-13-x64-rel", + "android-angle-chromium-arm64-builder", + "android-annotator-rel", + "android-archive-dbg", + "android-archive-rel", + "android-arm64-archive-rel", + "android-asan", + "android-avd-packager", + "android-build-perf-developer", + "android-chrome-pie-x86-wpt-android-specific", + "android-chrome-pie-x86-wpt-fyi-rel", + "android-code-coverage", + "android-code-coverage-native", + "android-cronet-arm-dbg", + "android-cronet-arm-rel", + "android-cronet-arm64-dbg", + "android-cronet-arm64-rel", + "android-cronet-asan-arm-rel", + "android-cronet-asan-x86-rel", + "android-cronet-mainline-clang-arm64-dbg", + "android-cronet-mainline-clang-arm64-rel", + "android-cronet-mainline-clang-x86-dbg", + "android-cronet-mainline-clang-x86-rel", + "android-cronet-x64-dbg", + "android-cronet-x64-dbg-12-tests", + "android-cronet-x64-dbg-13-tests", + "android-cronet-x64-rel", + "android-cronet-x86-dbg", + "android-cronet-x86-dbg-10-tests", + "android-cronet-x86-dbg-11-tests", + "android-cronet-x86-dbg-lollipop-tests", + "android-cronet-x86-dbg-marshmallow-tests", + "android-cronet-x86-dbg-nougat-tests", + "android-cronet-x86-dbg-oreo-tests", + "android-cronet-x86-dbg-pie-tests", + "android-cronet-x86-rel", + "android-device-flasher", + "android-fieldtrial-rel", + "android-official", + "android-perfetto-rel", + "android-pie-arm64-rel-dev", + "android-pie-x86-fyi-rel", + "android-rust-arm32-rel", + "android-rust-arm64-dbg", + "android-rust-arm64-rel", + "android-sdk-packager", + "android-webview-12-x64-dbg-tests", + "android-webview-13-x64-dbg-tests", + "android-webview-pie-x86-wpt-fyi-rel", + "android-x86-code-coverage", + "build-perf-android", + "build-perf-android-siso", + "build-perf-linux", + "build-perf-linux-siso", + "build-perf-windows", + "build-perf-windows-siso", + "chromeos-amd64-generic-asan-rel", + "chromeos-amd64-generic-cfi-thin-lto-rel", + "chromeos-amd64-generic-dbg", + "chromeos-amd64-generic-lacros-dbg", + "chromeos-amd64-generic-rel (reclient compare)", + "chromeos-amd64-generic-rel (reclient)", + "chromeos-amd64-generic-rel", + "chromeos-arm-generic-dbg", + "chromeos-arm-generic-rel", + "chromeos-arm64-generic-rel", + "chromeos-jacuzzi-rel", + "chromeos-js-code-coverage", + "chromeos-octopus-rel", + "fuchsia-angle-builder", + "fuchsia-code-coverage", + "fuchsia-official", + "fuchsia-x64-accessibility-rel", + "ios-angle-builder", + "ios-asan", + "ios-blink-dbg-fyi", + "ios-catalyst", + "ios-device", + "ios-fieldtrial-rel", + "ios-m1-simulator", + "ios-m1-simulator-cronet", + "ios-simulator", + "ios-simulator-code-coverage", + "ios-simulator-cronet", + "ios-simulator-full-configs", + "ios-simulator-multi-window", + "ios-simulator-noncq", + "ios-webkit-tot", + "ios-wpt-fyi-rel", + "ios16-beta-simulator", + "ios16-sdk-device", + "ios16-sdk-simulator", + "ios17-beta-simulator", + "ios17-sdk-simulator", + "lacros-amd64-generic-binary-size-rel", + "lacros-amd64-generic-rel (reclient)", + "lacros-amd64-generic-rel", + "lacros-amd64-generic-rel-fyi", + "lacros-amd64-generic-rel-skylab", + "lacros-amd64-generic-rel-skylab-fyi", + "lacros-arm-archive-rel", + "lacros-arm-generic-rel", + "lacros-arm-generic-rel-skylab", + "lacros-arm-generic-rel-skylab-fyi", + "lacros-arm64-archive-rel", + "lacros-arm64-generic-rel", + "lacros-arm64-generic-rel-skylab", + "lacros-arm64-generic-rel-skylab-fyi", + "lacros64-archive-rel", + "linux-angle-chromium-builder", + "linux-annotator-rel", + "linux-ash-chromium-generator-rel", + "linux-bfcache-rel", + "linux-blink-animation-use-time-delta", + "linux-blink-heap-verification", + "linux-blink-web-tests-force-accessibility-rel", + "linux-blink-wpt-reset-rel", + "linux-build-perf-developer", + "linux-chromeos-annotator-rel", + "linux-chromeos-build-perf", + "linux-chromeos-build-perf-siso", + "linux-chromeos-code-coverage", + "linux-chromeos-dbg", + "linux-chromeos-rel", + "linux-code-coverage", + "linux-exp-asan-lsan-fyi-rel", + "linux-exp-msan-fyi-rel", + "linux-exp-tsan-fyi-rel", + "linux-extended-tracing-rel", + "linux-fieldtrial-rel", + "linux-fuzz-coverage", + "linux-gcc-rel", + "linux-headless-shell-rel", + "linux-js-code-coverage", + "linux-lacros-archive-rel", + "linux-lacros-asan-lsan-rel", + "linux-lacros-builder-fyi-rel", + "linux-lacros-builder-rel (reclient)", + "linux-lacros-builder-rel", + "linux-lacros-code-coverage", + "linux-lacros-dbg", + "linux-lacros-dbg-fyi", + "linux-lacros-dbg-tests-fyi", + "linux-lacros-tester-fyi-rel", + "linux-lacros-tester-rel", + "linux-lacros-version-skew-fyi", + "linux-local-ssd-rel-dev", + "linux-network-sandbox-rel", + "linux-official", + "linux-perfetto-rel", + "linux-rel-dev", + "linux-rel-jammy-dev", + "linux-rel-no-external-ip", + "linux-remote-ssd-rel-dev", + "linux-rust-x64-dbg", + "linux-rust-x64-rel", + "linux-ubsan-fyi-rel", + "linux-ubsan-vptr", + "linux-updater-builder-dbg", + "linux-updater-builder-rel", + "linux-updater-tester-dbg", + "linux-updater-tester-rel", + "linux-upload-perfetto", + "linux-v4l2-codec-rel", + "linux-wpt-content-shell-asan-fyi-rel", + "linux-wpt-content-shell-fyi-rel", + "linux-wpt-content-shell-leak-detection", + "linux-wpt-fyi-rel", + "linux-wpt-identity-fyi-rel", + "linux-wpt-input-fyi-rel", + "mac-angle-chromium-builder", + "mac-angle-chromium-intel", + "mac-archive-dbg", + "mac-archive-rel", + "mac-arm-rel-dev", + "mac-arm64-archive-dbg", + "mac-arm64-archive-rel", + "mac-build-perf", + "mac-build-perf-developer", + "mac-build-perf-siso", + "mac-code-coverage", + "mac-fieldtrial-tester", + "mac-intel-on-arm64-rel", + "mac-lsan-fyi-rel", + "mac-osxbeta-rel", + "mac-perfetto-rel", + "mac-rel-dev", + "mac-rust-x64-dbg", + "mac-updater-builder-arm64-dbg", + "mac-updater-builder-arm64-rel", + "mac-updater-builder-asan-dbg", + "mac-updater-builder-dbg", + "mac-updater-builder-rel", + "mac-upload-perfetto", + "mac10.15-updater-tester-dbg", + "mac10.15-updater-tester-rel", + "mac10.15-wpt-content-shell-fyi-rel", + "mac11-arm64-updater-tester-dbg", + "mac11-arm64-updater-tester-rel", + "mac11-arm64-wpt-content-shell-fyi-rel", + "mac11-wpt-content-shell-fyi-rel", + "mac11-x64-updater-tester-dbg", + "mac11-x64-updater-tester-rel", + "mac12-arm64-rel-tests", + "mac12-arm64-updater-tester-rel", + "mac12-arm64-wpt-content-shell-fyi-rel", + "mac12-wpt-content-shell-fyi-rel", + "mac12-x64-updater-tester-asan-dbg", + "mac13-arm64-updater-tester-dbg", + "mac13-arm64-wpt-content-shell-fyi-rel", + "mac13-wpt-content-shell-fyi-rel", + "mac13-x64-updater-tester-rel", + "metadata-exporter", + "rts-model-packager", + "rts-suite-analysis", + "win-angle-chromium-x64-builder", + "win-angle-chromium-x86-builder", + "win-annotator-rel", + "win-archive-dbg", + "win-archive-rel", + "win-asan", + "win-build-perf-developer", + "win-celab-builder-rel", + "win-fieldtrial-rel", + "win-local-ssd-rel-dev", + "win-network-sandbox-tester", + "win-official", + "win-perfetto-rel", + "win-rel-dev", + "win-rust-x64-dbg", + "win-rust-x64-rel", + "win-updater-builder-dbg", + "win-updater-builder-rel", + "win-upload-perfetto", + "win10-32-on-64-updater-tester-dbg", + "win10-32-on-64-updater-tester-rel", + "win10-angle-chromium-x64-intel", + "win10-angle-chromium-x64-nvidia", + "win10-code-coverage", + "win10-rel-no-external-ip", + "win10-updater-tester-dbg", + "win10-updater-tester-dbg-uac", + "win10-updater-tester-rel", + "win10-updater-tester-rel-uac", + "win10-wpt-content-shell-fyi-rel", + "win11-rel-dev", + "win11-updater-tester-dbg-uac", + "win11-updater-tester-rel", + "win11-wpt-content-shell-fyi-rel", + "win32-archive-dbg", + "win32-archive-rel", + "win32-arm64-rel", + "win32-official", + "win32-updater-builder-dbg", + "win32-updater-builder-rel", + ], + "try": [ + "3pp-linux-amd64-packager", + "3pp-mac-amd64-packager", + "Crossbench CBB Mac Try", + "android-10-arm64-rel", + "android-11-x86-rel", + "android-12-x64-dbg", + "android-12-x64-dual-coverage-exp-rel", + "android-12-x64-rel", + "android-12-x64-rel-compilator", + "android-12-x64-siso-rel", + "android-12-x64-siso-rel-compilator", + "android-12l-x64-dbg", + "android-13-x64-rel", + "android-angle-chromium-try", + "android-arm-compile-dbg", + "android-arm64-all-targets-dbg", + "android-arm64-rel", + "android-arm64-rel-compilator", + "android-arm64-siso-rel", + "android-arm64-siso-rel-compilator", + "android-asan-compile-dbg", + "android-bfcache-rel", + "android-binary-size", + "android-chrome-pie-x86-wpt-android-specific", + "android-chrome-pie-x86-wpt-fyi-rel", + "android-clang-tidy-rel", + "android-code-coverage", + "android-code-coverage-native", + "android-cronet-arm-dbg", + "android-cronet-arm64-dbg", + "android-cronet-arm64-rel", + "android-cronet-asan-arm-rel", + "android-cronet-mainline-clang-arm64-dbg", + "android-cronet-mainline-clang-arm64-rel", + "android-cronet-mainline-clang-x86-dbg", + "android-cronet-mainline-clang-x86-rel", + "android-cronet-x64-dbg", + "android-cronet-x64-dbg-12-tests", + "android-cronet-x64-dbg-13-tests", + "android-cronet-x64-rel", + "android-cronet-x86-dbg", + "android-cronet-x86-dbg-10-tests", + "android-cronet-x86-dbg-11-tests", + "android-cronet-x86-dbg-lolipop", + "android-cronet-x86-dbg-marshmallow", + "android-cronet-x86-dbg-nougat-tests", + "android-cronet-x86-dbg-oreo-tests", + "android-cronet-x86-dbg-pie-tests", + "android-cronet-x86-rel", + "android-dawn-arm-rel", + "android-dawn-arm64-rel", + "android-deterministic-dbg", + "android-deterministic-rel", + "android-fieldtrial-rel", + "android-inverse-fieldtrials-pie-x86-fyi-rel", + "android-nougat-x86-dual-coverage-exp-rel", + "android-nougat-x86-rel", + "android-nougat-x86-rel-compilator", + "android-nougat-x86-siso-rel", + "android-nougat-x86-siso-rel-compilator", + "android-official", + "android-oreo-arm64-dbg", + "android-oreo-x86-rel", + "android-perfetto-rel", + "android-pie-arm64-dbg", + "android-pie-x86-rel", + "android-rust-arm32-rel", + "android-rust-arm64-dbg", + "android-rust-arm64-rel", + "android-webview-10-x86-rel-tests", + "android-webview-12-x64-dbg", + "android-webview-13-x64-dbg", + "android-webview-nougat-arm64-dbg", + "android-webview-oreo-arm64-dbg", + "android-webview-pie-arm64-dbg", + "android-webview-pie-x86-wpt-fyi-rel", + "android-x64-cast", + "android_archive_rel_ng", + "android_arm64_dbg_recipe", + "android_blink_rel", + "android_compile_dbg", + "android_compile_x64_dbg", + "android_compile_x86_dbg", + "android_cronet", + "android_optional_gpu_tests_rel", + "android_unswarmed_pixel_aosp", + "branch-config-verifier", + "builder-config-verifier", + "chromeos-amd64-generic-asan-rel", + "chromeos-amd64-generic-cfi-thin-lto-rel", + "chromeos-amd64-generic-dbg", + "chromeos-amd64-generic-lacros-dbg", + "chromeos-amd64-generic-rel", + "chromeos-amd64-generic-rel-compilator", + "chromeos-amd64-generic-siso-rel", + "chromeos-amd64-generic-siso-rel-compilator", + "chromeos-arm-generic-dbg", + "chromeos-arm-generic-rel", + "chromeos-arm64-generic-rel", + "chromeos-jacuzzi-rel", + "chromeos-js-code-coverage", + "chromeos-js-coverage-rel", + "chromeos-octopus-rel", + "chromium_presubmit", + "dawn-android-arm-deps-rel", + "dawn-android-arm64-deps-rel", + "dawn-linux-x64-deps-rel", + "dawn-mac-x64-deps-rel", + "dawn-try-linux-tsan-rel", + "dawn-try-mac-amd-exp", + "dawn-try-mac-arm64-rel", + "dawn-try-mac-intel-exp", + "dawn-try-win-x64-intel-exp", + "dawn-try-win-x86-intel-exp", + "dawn-try-win10-x64-intel-asan", + "dawn-try-win10-x64-nvidia-asan", + "dawn-try-win10-x86-rel", + "dawn-win10-x64-deps-rel", + "dawn-win10-x86-deps-rel", + "fuchsia-angle-try", + "fuchsia-arm64-cast-receiver-rel", + "fuchsia-arm64-rel", + "fuchsia-binary-size", + "fuchsia-clang-tidy-rel", + "fuchsia-code-coverage", + "fuchsia-compile-x64-dbg", + "fuchsia-deterministic-dbg", + "fuchsia-fyi-arm64-dbg", + "fuchsia-fyi-x64-dbg", + "fuchsia-official", + "fuchsia-x64-accessibility-rel", + "fuchsia-x64-cast-receiver-rel", + "fuchsia-x64-cast-receiver-rel-compilator", + "fuchsia-x64-cast-receiver-siso-rel", + "fuchsia-x64-cast-receiver-siso-rel-compilator", + "fuchsia-x64-rel", + "gpu-fyi-cq-android-arm64", + "gpu-fyi-try-android-m-nexus-5x-64", + "gpu-fyi-try-android-nvidia-shield-tv", + "gpu-fyi-try-android-p-pixel-2-32", + "gpu-fyi-try-android-pixel-6-64", + "gpu-fyi-try-android-r-pixel-4-32", + "gpu-fyi-try-chromeos-amd64-generic", + "gpu-fyi-try-chromeos-kevin", + "gpu-fyi-try-chromeos-skylab-kevin", + "gpu-fyi-try-lacros-amd-rel", + "gpu-fyi-try-lacros-intel-rel", + "gpu-fyi-try-linux-amd-rel", + "gpu-fyi-try-linux-intel-exp", + "gpu-fyi-try-linux-intel-rel", + "gpu-fyi-try-linux-nvidia-dbg", + "gpu-fyi-try-linux-nvidia-exp", + "gpu-fyi-try-linux-nvidia-rel", + "gpu-fyi-try-linux-nvidia-tsn", + "gpu-fyi-try-mac-amd-pro-rel", + "gpu-fyi-try-mac-amd-retina-asan", + "gpu-fyi-try-mac-amd-retina-dbg", + "gpu-fyi-try-mac-amd-retina-exp", + "gpu-fyi-try-mac-amd-retina-rel", + "gpu-fyi-try-mac-arm64-apple-m1-exp", + "gpu-fyi-try-mac-arm64-apple-m1-rel", + "gpu-fyi-try-mac-arm64-apple-m2-retina-rel", + "gpu-fyi-try-mac-intel-asan", + "gpu-fyi-try-mac-intel-dbg", + "gpu-fyi-try-mac-intel-exp", + "gpu-fyi-try-mac-intel-rel", + "gpu-fyi-try-mac-nvidia-retina-exp", + "gpu-fyi-try-mac-nvidia-retina-rel", + "gpu-fyi-try-win10-amd-rel-64", + "gpu-fyi-try-win10-intel-exp-64", + "gpu-fyi-try-win10-intel-rel-64", + "gpu-fyi-try-win10-nvidia-dbg-64", + "gpu-fyi-try-win10-nvidia-dx12vk-dbg-64", + "gpu-fyi-try-win10-nvidia-dx12vk-rel-64", + "gpu-fyi-try-win10-nvidia-exp-64", + "gpu-fyi-try-win10-nvidia-rel-32", + "gpu-fyi-try-win10-nvidia-rel-64", + "gpu-try-android-m-nexus-5x-64", + "gpu-try-linux-nvidia-dbg", + "gpu-try-linux-nvidia-rel", + "gpu-try-mac-amd-retina-dbg", + "gpu-try-mac-intel-dbg", + "ios-angle-try-intel", + "ios-asan", + "ios-blink-dbg-fyi", + "ios-catalyst", + "ios-device", + "ios-fieldtrial-rel", + "ios-m1-simulator", + "ios-m1-simulator-cronet", + "ios-simulator", + "ios-simulator-code-coverage", + "ios-simulator-compilator", + "ios-simulator-cronet", + "ios-simulator-full-configs", + "ios-simulator-inverse-fieldtrials-fyi", + "ios-simulator-multi-window", + "ios-simulator-noncq", + "ios-wpt-fyi-rel", + "ios16-beta-simulator", + "ios16-sdk-simulator", + "ios17-beta-simulator", + "ios17-sdk-simulator", + "lacros-amd64-generic-rel", + "lacros-amd64-generic-rel-skylab", + "lacros-amd64-generic-rel-skylab-fyi", + "lacros-arm-generic-rel", + "lacros-arm64-generic-rel", + "layout_test_leak_detection", + "leak_detection_linux", + "linux-afl-asan-rel", + "linux-angle-chromium-try", + "linux-annotator-rel", + "linux-arm64-castos", + "linux-arm64-rel-cft", + "linux-bfcache-rel", + "linux-blink-heap-verification-try", + "linux-blink-rel", + "linux-blink-web-tests-force-accessibility-rel", + "linux-centipede-asan-rel", + "linux-cfm-rel", + "linux-chromeos-annotator-rel", + "linux-chromeos-clang-tidy-rel", + "linux-chromeos-code-coverage", + "linux-chromeos-compile-dbg", + "linux-chromeos-dbg", + "linux-chromeos-inverse-fieldtrials-fyi-rel", + "linux-chromeos-rel", + "linux-chromeos-rel-compilator", + "linux-chromeos-siso-rel", + "linux-chromeos-siso-rel-compilator", + "linux-clang-tidy-rel", + "linux-code-coverage", + "linux-dawn-rel", + "linux-dcheck-off-rel", + "linux-exp-asan-lsan-fyi-rel", + "linux-exp-msan-fyi-rel", + "linux-exp-tsan-fyi-rel", + "linux-extended-tracing-rel", + "linux-fieldtrial-rel", + "linux-gcc-rel", + "linux-headless-shell-rel", + "linux-inverse-fieldtrials-fyi-rel", + "linux-js-code-coverage", + "linux-js-coverage-rel", + "linux-lacros-asan-lsan-rel", + "linux-lacros-clang-tidy-rel", + "linux-lacros-code-coverage", + "linux-lacros-dbg", + "linux-lacros-fyi-rel", + "linux-lacros-rel", + "linux-lacros-rel-compilator", + "linux-lacros-siso-rel", + "linux-lacros-siso-rel-compilator", + "linux-lacros-version-skew-fyi", + "linux-layout-tests-edit-ng", + "linux-libfuzzer-asan-rel", + "linux-mbi-mode-per-render-process-host-rel", + "linux-mbi-mode-per-site-instance-rel", + "linux-official", + "linux-perfetto-rel", + "linux-rel", + "linux-rel-cft", + "linux-rel-compilator", + "linux-rust-x64-dbg", + "linux-rust-x64-rel", + "linux-siso-rel", + "linux-siso-rel-compilator", + "linux-swangle-chromium-try-x64", + "linux-swangle-chromium-try-x64-exp", + "linux-swangle-try-tot-swiftshader-x64", + "linux-swangle-try-x64", + "linux-swangle-try-x64-exp", + "linux-ubsan-fyi-rel", + "linux-ubsan-vptr", + "linux-updater-try-builder-dbg", + "linux-updater-try-builder-rel", + "linux-v4l2-codec-rel", + "linux-viz-rel", + "linux-wayland-rel", + "linux-wayland-rel-compilator", + "linux-wayland-siso-rel", + "linux-wayland-siso-rel-compilator", + "linux-webkit-msan-rel", + "linux-wpt-content-shell-fyi-rel", + "linux-wpt-content-shell-leak-detection", + "linux-wpt-fyi-rel", + "linux-wpt-identity-fyi-rel", + "linux-wpt-input-fyi-rel", + "linux-x64-castos", + "linux-x64-castos-audio", + "linux-x64-castos-dbg", + "linux_chromium_archive_rel_ng", + "linux_chromium_asan_rel_ng", + "linux_chromium_asan_rel_ng-compilator", + "linux_chromium_asan_siso_rel_ng", + "linux_chromium_asan_siso_rel_ng-compilator", + "linux_chromium_cfi_rel_ng", + "linux_chromium_chromeos_asan_rel_ng", + "linux_chromium_chromeos_msan_rel_ng", + "linux_chromium_clobber_deterministic", + "linux_chromium_clobber_rel_ng", + "linux_chromium_compile_dbg_ng", + "linux_chromium_compile_rel_ng", + "linux_chromium_dbg_ng", + "linux_chromium_msan_rel_ng", + "linux_chromium_tsan_rel_ng", + "linux_chromium_tsan_rel_ng-compilator", + "linux_chromium_tsan_siso_rel_ng", + "linux_chromium_tsan_siso_rel_ng-compilator", + "linux_optional_gpu_tests_rel", + "linux_upload_clang", + "linux_upload_rust", + "mac-angle-chromium-try", + "mac-arm64-on-arm64-rel", + "mac-builder-next", + "mac-clang-tidy-rel", + "mac-code-coverage", + "mac-dawn-rel", + "mac-fieldtrial-tester", + "mac-intel-on-arm64-rel", + "mac-inverse-fieldtrials-fyi-rel", + "mac-official", + "mac-osxbeta-rel", + "mac-perfetto-rel", + "mac-rel", + "mac-rel-cft", + "mac-rel-compilator", + "mac-rust-x64-dbg", + "mac-swangle-chromium-try-x64", + "mac-updater-try-builder-dbg", + "mac-updater-try-builder-rel", + "mac10.15-blink-rel", + "mac10.15-wpt-content-shell-fyi-rel", + "mac11-arm64-rel", + "mac11-arm64-wpt-content-shell-fyi-rel", + "mac11-wpt-content-shell-fyi-rel", + "mac11.0-blink-rel", + "mac11.0.arm64-blink-rel", + "mac12-arm64-rel", + "mac12-arm64-wpt-content-shell-fyi-rel", + "mac12-tests", + "mac12-wpt-content-shell-fyi-rel", + "mac12.0-blink-rel", + "mac12.0.arm64-blink-rel", + "mac13-arm64-rel", + "mac13-arm64-rel-compilator", + "mac13-arm64-wpt-content-shell-fyi-rel", + "mac13-blink-rel", + "mac13-tests", + "mac13-wpt-content-shell-fyi-rel", + "mac13.arm64-blink-rel", + "mac_chromium_10.15_rel_ng", + "mac_chromium_11.0_rel_ng", + "mac_chromium_archive_rel_ng", + "mac_chromium_asan_rel_ng", + "mac_chromium_compile_dbg_ng", + "mac_chromium_compile_rel_ng", + "mac_chromium_dbg_ng", + "mac_optional_gpu_tests_rel", + "mac_upload_clang", + "mac_upload_clang_arm", + "mac_upload_rust", + "mac_upload_rust_arm", + "network_service_linux", + "reclient-config-deployment-verifier", + "requires-testing-checker", + "targets-config-verifier", + "tricium-clang-tidy", + "tricium-metrics-analysis", + "tricium-oilpan-analysis", + "tricium-simple", + "try-nougat-phone-tester", + "win-angle-chromium-x64-try", + "win-angle-chromium-x86-try", + "win-annotator-rel", + "win-asan", + "win-celab-try-rel", + "win-dawn-rel", + "win-fieldtrial-rel", + "win-libfuzzer-asan-rel", + "win-official", + "win-perfetto-rel", + "win-presubmit", + "win-rel", + "win-rel-cft", + "win-rel-compilator", + "win-rust-x64-dbg", + "win-rust-x64-rel", + "win-siso-rel", + "win-siso-rel-compilator", + "win-swangle-chromium-try-x86", + "win-swangle-try-tot-swiftshader-x64", + "win-swangle-try-tot-swiftshader-x86", + "win-swangle-try-x64", + "win-swangle-try-x86", + "win-updater-try-builder-dbg", + "win-updater-try-builder-rel", + "win10-clang-tidy-rel", + "win10-code-coverage", + "win10-wpt-content-shell-fyi-rel", + "win10.20h2-blink-rel", + "win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng", + "win10_chromium_x64_dbg_ng", + "win11-arm64-blink-rel", + "win11-blink-rel", + "win11-wpt-content-shell-fyi-rel", + "win11-x64-fyi-rel", + "win32-official", + "win_archive", + "win_chromium_compile_dbg_ng", + "win_chromium_compile_rel_ng", + "win_chromium_x64_rel_ng", + "win_optional_gpu_tests_rel", + "win_upload_clang", + "win_upload_rust", + "win_x64_archive", + ], + "infra": [ + "autosharder", + ], + "codesearch": [ + "gen-android-try", + "gen-chromiumos-try", + "gen-fuchsia-try", + "gen-ios-try", + "gen-lacros-try", + "gen-linux-try", + "gen-mac-try", + "gen-webview-try", + "gen-win-try", + ], + "findit": [ + "gofindit-culprit-verification", + "test-single-revision", + ], + "flaky-reproducer": [ + "runner", + ], + "goma": [ + "Chromium Android ARM 32-bit Goma RBE Staging", + "Chromium Linux Goma RBE Staging (dbg)", + "Chromium Linux Goma RBE Staging", + "Chromium Mac Goma RBE Staging (dbg)", + "Chromium Mac Goma RBE Staging", + "Chromium Win Goma RBE ATS Staging", + "Chromium Win Goma RBE Staging", + "Linux Builder Goma RBE Canary", + "Mac Builder (dbg) Goma RBE Canary (clobber)", + "Mac M1 Builder (dbg) Goma RBE Canary (clobber)", + "Win Builder (dbg) Goma RBE ATS Canary", + "Win Builder (dbg) Goma RBE Canary", + "Win Builder Goma RBE ATS Canary", + "Win Builder Goma RBE Canary", + "android-archive-dbg-goma-rbe-ats-canary", + "android-archive-dbg-goma-rbe-canary", + "chromeos-amd64-generic-rel-goma-rbe-canary", + "chromeos-amd64-generic-rel-goma-rbe-staging", + "ios-device-goma-rbe-canary-clobber", + "linux-archive-rel-goma-rbe-ats-canary", + "linux-archive-rel-goma-rbe-canary", + "mac-archive-rel-goma-rbe-canary", + ], + "reclient": [ + "Comparison Linux (reclient vs reclient remote links)", + "Linux Builder (canonical wd) (reclient compare)", + "Linux Builder reclient staging untrusted", + "Linux Builder reclient staging", + "Linux Builder reclient test (casng) untrusted", + "Linux Builder reclient test (casng)", + "Linux Builder reclient test (unified uploads) untrusted", + "Linux Builder reclient test (unified uploads)", + "Linux Builder reclient test untrusted", + "Linux Builder reclient test", + "Mac Builder reclient staging untrusted", + "Mac Builder reclient staging", + "Mac Builder reclient test untrusted", + "Mac Builder reclient test", + "Simple Chrome Builder reclient staging untrusted", + "Simple Chrome Builder reclient staging", + "Simple Chrome Builder reclient test untrusted", + "Simple Chrome Builder reclient test", + "Win x64 Builder reclient staging untrusted", + "Win x64 Builder reclient staging", + "Win x64 Builder reclient test untrusted", + "Win x64 Builder reclient test", + "Win x64 Cross Builder (reclient compare)", + "Windows Cross deterministic", + "ios-simulator reclient staging untrusted", + "ios-simulator reclient staging", + "ios-simulator reclient test untrusted", + "ios-simulator reclient test", + "mac-arm64-rel reclient staging untrusted", + "mac-arm64-rel reclient staging", + "mac-arm64-rel reclient test untrusted", + "mac-arm64-rel reclient test", + ], + "reviver": [ + "android-coverage-launcher", + "android-device-launcher", + "android-launcher", + "android-x64-launcher", + "coverage-runner", + "fuchsia-coordinator", + "lacros-coordinator", + "linux-launcher", + "mac-launcher", + "runner", + "win-launcher", + ], + "webrtc": [ + "WebRTC Chromium Android Builder", + "WebRTC Chromium Android Tester", + "WebRTC Chromium Linux Builder", + "WebRTC Chromium Linux Tester", + "WebRTC Chromium Mac Builder", + "WebRTC Chromium Mac Tester", + "WebRTC Chromium Win Builder", + "WebRTC Chromium Win10 Tester", + ], + "webrtc.fyi": [ + "WebRTC Chromium FYI Android Builder", + "WebRTC Chromium FYI Android Builder (dbg)", + "WebRTC Chromium FYI Android Builder ARM64 (dbg)", + "WebRTC Chromium FYI Android Tests (dbg)", + "WebRTC Chromium FYI Android Tests ARM64 (dbg)", + "WebRTC Chromium FYI Linux Builder", + "WebRTC Chromium FYI Linux Builder (dbg)", + "WebRTC Chromium FYI Linux Tester", + "WebRTC Chromium FYI Mac Builder", + "WebRTC Chromium FYI Mac Builder (dbg)", + "WebRTC Chromium FYI Mac Tester", + "WebRTC Chromium FYI Win Builder", + "WebRTC Chromium FYI Win Builder (dbg)", + "WebRTC Chromium FYI Win10 Tester", + "WebRTC Chromium FYI ios-device", + "WebRTC Chromium FYI ios-simulator", + ], +} + health_spec = struct( DEFAULT = DEFAULT, spec = spec,
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 0b1daca1..8d0edb2 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -956,7 +956,7 @@ register_bootstrap(bucket, name, bootstrap, executable) health_spec = defaults.get_value("health_spec", health_spec) - register_health_spec(bucket, name, health_spec) + register_health_spec(bucket, name, health_spec, kwargs.get("contact_team_email")) register_gn_args(builder_group, bucket, name, gn_args)
diff --git a/infra/config/lib/targets.star b/infra/config/lib/targets.star index 7d9a5c04..7c7af0e 100644 --- a/infra/config/lib/targets.star +++ b/infra/config/lib/targets.star
@@ -517,7 +517,7 @@ # Instead: # 1. Modify //infra/config/targets/{star_file} # 2. Run //infra/config/main.star -# 3. Run //infra/config/scripts/sync-py-files.py +# 3. Run //infra/config/scripts/sync-pyl-files.py {{ {entries}
diff --git a/infra/config/subprojects/chromium/ci/chromium.clang.star b/infra/config/subprojects/chromium/ci/chromium.clang.star index 690cf1e..aa8bbea 100644 --- a/infra/config/subprojects/chromium/ci/chromium.clang.star +++ b/infra/config/subprojects/chromium/ci/chromium.clang.star
@@ -103,6 +103,21 @@ ci.builder( name = "CFI Linux CF", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config(config = "chromium"), + chromium_config = builder_config.chromium_config( + config = "chromium", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + clusterfuzz_archive = builder_config.clusterfuzz_archive( + archive_name_prefix = "cfi", + gs_acl = "public-read", + gs_bucket = "chromium-browser-cfi", + ), + ), console_view_entry = consoles.console_view_entry( category = "CFI|Linux", short_name = "CF", @@ -115,6 +130,19 @@ ci.builder( name = "CFI Linux ToT", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "CFI|Linux", short_name = "ToT", @@ -125,6 +153,19 @@ ci.builder( name = "CrWinAsan", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_asan_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, console_view_entry = consoles.console_view_entry( category = "ToT Windows|Asan", @@ -135,6 +176,19 @@ ci.builder( name = "CrWinAsan(dll)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_asan_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, console_view_entry = consoles.console_view_entry( category = "ToT Windows|Asan", @@ -145,6 +199,25 @@ ci.builder( name = "ToTAndroid", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.ARM, + target_bits = 32, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "clang_builder_mb_x64"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Android", short_name = "rel", @@ -154,6 +227,25 @@ ci.builder( name = "ToTAndroid (dbg)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android", + apply_configs = ["mb"], + build_config = builder_config.build_config.DEBUG, + target_arch = builder_config.target_arch.ARM, + target_bits = 32, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "clang_builder_mb_x64"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Android", short_name = "dbg", @@ -163,6 +255,25 @@ ci.builder( name = "ToTAndroid x64", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "clang_builder_mb_x64"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Android", short_name = "x64", @@ -172,6 +283,25 @@ ci.builder( name = "ToTAndroid x86", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 32, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "clang_builder_mb_x64"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Android", short_name = "x86", @@ -181,6 +311,25 @@ ci.builder( name = "ToTAndroidCoverage x86", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 32, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "clang_builder_mb_x64"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Code Coverage", short_name = "and", @@ -190,6 +339,25 @@ ci.builder( name = "ToTAndroid64", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.ARM, + target_bits = 64, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "clang_builder_mb_x64"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Android", short_name = "a64", @@ -199,6 +367,25 @@ ci.builder( name = "ToTAndroidASan", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android_asan", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.ARM, + target_bits = 32, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "asan_symbolize"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Android", short_name = "asn", @@ -208,6 +395,25 @@ ci.builder( name = "ToTAndroidOfficial", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "android", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_android", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.ARM, + target_bits = 32, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "clang_builder_mb_x64"), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Android", short_name = "off", @@ -217,6 +423,23 @@ ci.builder( name = "ToTChromeOS", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "chromeos", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_chromeos", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.CHROMEOS, + ), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT ChromeOS", short_name = "rel", @@ -226,6 +449,23 @@ ci.builder( name = "ToTChromeOS (dbg)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "chromeos", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_chromeos", + apply_configs = ["mb"], + build_config = builder_config.build_config.DEBUG, + target_bits = 64, + target_platform = builder_config.target_platform.CHROMEOS, + ), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT ChromeOS", short_name = "dbg", @@ -235,6 +475,25 @@ ci.builder( name = "ToTFuchsia x64", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "fuchsia_x64", + "fuchsia_no_hooks", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_fuchsia", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.FUCHSIA, + ), + build_gs_bucket = "chromium-clang-archive", + run_tests_serially = True, + ), console_view_entry = [ consoles.console_view_entry( category = "ToT Fuchsia", @@ -252,6 +511,27 @@ ci.builder( name = "ToTFuchsiaOfficial arm64", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "checkout_pgo_profiles", + "clang_tot", + "fuchsia_arm64", + "fuchsia_arm64_host", + "fuchsia_no_hooks", + ], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_fuchsia", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.FUCHSIA, + ), + build_gs_bucket = "chromium-clang-archive", + run_tests_serially = True, + ), console_view_entry = [ consoles.console_view_entry( category = "ToT Fuchsia", @@ -269,21 +549,77 @@ clang_tot_linux_builder( name = "ToTLinux", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), short_name = "rel", ) clang_tot_linux_builder( name = "ToTLinux (dbg)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux", + apply_configs = ["mb"], + build_config = builder_config.build_config.DEBUG, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), short_name = "dbg", ) clang_tot_linux_builder( name = "ToTLinuxASan", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux_asan", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), short_name = "asn", ) clang_tot_linux_builder( name = "ToTLinuxASanLibfuzzer", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux_asan", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), # Requires a large disk, so has a machine specifically devoted to it builderless = False, short_name = "fuz", @@ -298,27 +634,96 @@ clang_tot_linux_builder( name = "ToTLinuxMSan", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.LINUX_FOCAL, short_name = "msn", ) clang_tot_linux_builder( name = "ToTLinuxPGO", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), short_name = "pgo", ) clang_tot_linux_builder( name = "ToTLinuxTSan", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), short_name = "tsn", ) clang_tot_linux_builder( name = "ToTLinuxUBSanVptr", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_linux_ubsan_vptr", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_arch = builder_config.target_arch.INTEL, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), short_name = "usn", ) ci.builder( name = "ToTWin", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, free_space = builders.free_space.high, console_view_entry = consoles.console_view_entry( @@ -330,6 +735,19 @@ ci.builder( name = "ToTWin(dbg)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.DEBUG, + target_bits = 32, + ), + build_gs_bucket = "chromium-clang-archive", + ), builderless = False, os = os.WINDOWS_DEFAULT, console_view_entry = consoles.console_view_entry( @@ -341,6 +759,19 @@ ci.builder( name = "ToTWin(dll)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, console_view_entry = consoles.console_view_entry( category = "ToT Windows", @@ -351,6 +782,19 @@ ci.builder( name = "ToTWin64", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, console_view_entry = consoles.console_view_entry( category = "ToT Windows|x64", @@ -361,6 +805,19 @@ ci.builder( name = "ToTWin64(dbg)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.DEBUG, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, free_space = builders.free_space.high, console_view_entry = consoles.console_view_entry( @@ -372,6 +829,19 @@ ci.builder( name = "ToTWin64(dll)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, free_space = builders.free_space.high, console_view_entry = consoles.console_view_entry( @@ -383,6 +853,19 @@ ci.builder( name = "ToTWinASanLibfuzzer", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_asan_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), builderless = False, os = os.WINDOWS_DEFAULT, console_view_entry = consoles.console_view_entry( @@ -435,6 +918,19 @@ ci.builder( name = "ToTWin64PGO", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), os = os.WINDOWS_DEFAULT, console_view_entry = consoles.console_view_entry( category = "ToT Windows|x64", @@ -445,6 +941,23 @@ ci.builder( name = "linux-win_cross-rel", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = [ + "clang_tot", + "win", + ], + ), + chromium_config = builder_config.chromium_config( + config = "chromium_win_clang_tot", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.WIN, + ), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Windows", short_name = "lxw", @@ -454,6 +967,23 @@ ci.builder( name = "ToTiOS", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "ios", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_ios", + apply_configs = [ + "mb", + "mac_toolchain", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.IOS, + ), + build_gs_bucket = "chromium-clang-archive", + ), builderless = False, cores = None, os = os.MAC_DEFAULT, @@ -468,6 +998,23 @@ ci.builder( name = "ToTiOSDevice", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "ios", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_ios", + apply_configs = [ + "mb", + "mac_toolchain", + ], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + target_platform = builder_config.target_platform.IOS, + ), + build_gs_bucket = "chromium-clang-archive", + ), builderless = False, cores = None, os = os.MAC_DEFAULT, @@ -482,6 +1029,19 @@ clang_mac_builder( name = "ToTMac", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_mac", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Mac", short_name = "rel", @@ -491,6 +1051,19 @@ clang_mac_builder( name = "ToTMac (dbg)", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_mac", + apply_configs = ["mb"], + build_config = builder_config.build_config.DEBUG, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Mac", short_name = "dbg", @@ -500,6 +1073,19 @@ clang_mac_builder( name = "ToTMacASan", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["clang_tot"], + ), + chromium_config = builder_config.chromium_config( + config = "clang_tot_mac_asan", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 64, + ), + build_gs_bucket = "chromium-clang-archive", + ), console_view_entry = consoles.console_view_entry( category = "ToT Mac", short_name = "asn",
diff --git a/infra/config/subprojects/reclient/reclient.star b/infra/config/subprojects/reclient/reclient.star index 06c0822e0..f48c390 100644 --- a/infra/config/subprojects/reclient/reclient.star +++ b/infra/config/subprojects/reclient/reclient.star
@@ -18,7 +18,10 @@ ), acl.entry( roles = acl.BUILDBUCKET_TRIGGERER, - groups = "project-chromium-ci-schedulers", + groups = [ + "project-chromium-ci-schedulers", + "mdb/foundry-x-team", + ], ), acl.entry( roles = acl.BUILDBUCKET_OWNER,
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index 358d977..d0ce2cb7 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@ { "LACROS_VERSION_SKEW_CANARY": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "identifier": "Lacros version skew testing ash canary", "swarming": { "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ] }
diff --git a/ios/chrome/browser/credential_provider/credential_provider_service.mm b/ios/chrome/browser/credential_provider/credential_provider_service.mm index 070d404..acc3791 100644 --- a/ios/chrome/browser/credential_provider/credential_provider_service.mm +++ b/ios/chrome/browser/credential_provider/credential_provider_service.mm
@@ -247,12 +247,14 @@ const bool fallback_to_google_server = CanSendHistoryData(sync_service_); for (const auto& form : forms) { - NSString* favicon_key = GetFaviconFileKey(form->url); - // Fetch the favicon and save it to the storage. - FetchFaviconForURLToPath(favicon_loader_, form->url, favicon_key, - should_skip_max_verification, - fallback_to_google_server); - + NSString* favicon_key; + if (form->url.is_valid()) { + favicon_key = GetFaviconFileKey(form->url); + // Fetch the favicon and save it to the storage. + FetchFaviconForURLToPath(favicon_loader_, form->url, favicon_key, + should_skip_max_verification, + fallback_to_google_server); + } ArchivableCredential* credential = [[ArchivableCredential alloc] initWithPasswordForm:*form favicon:favicon_key];
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index f1b94b3c..e709859 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -1719,6 +1719,12 @@ {"top-toolbar-theme-color", flag_descriptions::kThemeColorInTopToolbarName, flag_descriptions::kThemeColorInTopToolbarDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kThemeColorInTopToolbar)}, + {"iph-ios-promo-manager-widget-promo", + flag_descriptions::kIPHiOSPromoPasswordManagerWidgetName, + flag_descriptions::kIPHiOSPromoPasswordManagerWidgetDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + feature_engagement::kIPHiOSPromoPasswordManagerWidgetFeature)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 19fa178..b6486b25 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -680,6 +680,12 @@ const char kIPHForSafariSwitcherDescription[] = "Enables displaying IPH for users who are considered Safari Switcher"; +const char kIPHiOSPromoPasswordManagerWidgetName[] = + "Password Manager widget promo IPH"; +const char kIPHiOSPromoPasswordManagerWidgetDescription[] = + "Enables displaying the Password Manager widget promo IPH when users " + "navigate to the Password Manager"; + const char kLockBottomToolbarName[] = "Lock bottom toolbar"; const char kLockBottomToolbarDescription[] = "When enabled, the bottom toolbar will not get collapsed when scrolling "
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index c0c02a9..168a13b 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -581,6 +581,11 @@ extern const char kIPHForSafariSwitcherName[]; extern const char kIPHForSafariSwitcherDescription[]; +// Title and description for the flag to enable the Password Manager widget +// promo IPH. +extern const char kIPHiOSPromoPasswordManagerWidgetName[]; +extern const char kIPHiOSPromoPasswordManagerWidgetDescription[]; + // Title and description for the flag to lock the bottom toolbar into place. extern const char kLockBottomToolbarName[]; extern const char kLockBottomToolbarDescription[];
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm b/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm index 6d4e9d0..446deea5 100644 --- a/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm +++ b/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm
@@ -118,6 +118,8 @@ referrer:password_manager:: PasswordCheckReferrer:: kSafetyCheckMagicStack]; + + return; } // If there are multiple passwords (with multiple warning types), or no @@ -125,6 +127,7 @@ // overview screen. base::RecordAction( base::UserMetricsAction("MobileMagicStackOpenPasswordCheckup")); + [handler showPasswordCheckupPageForReferrer: password_manager::PasswordCheckReferrer::kSafetyCheckMagicStack]; }
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h index 467c9d7e..c573518 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.h
@@ -20,6 +20,9 @@ // The layout guide center for the current scene. @property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter; +// The lens button, which may be nil. +@property(nonatomic, strong) UIButton* lensButton; + // Notifies the delegate that the Voice Search button was tapped. - (void)keyboardAccessoryVoiceSearchTapped:(id)sender;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm index 3a18ca7..b76794f 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm
@@ -25,6 +25,7 @@ @synthesize browserCoordinatorCommandsHandler = _browserCoordinatorCommandsHandler; @synthesize layoutGuideCenter = _layoutGuideCenter; +@synthesize lensButton = _lensButton; @synthesize qrScannerCommandsHandler = _qrScannerCommandsHandler; @synthesize omniboxTextField = _omniboxTextField;
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.h b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.h index 1d6c04a..b323ccd 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.h +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.h
@@ -14,6 +14,10 @@ @protocol OmniboxAssistiveKeyboardDelegate; +// Updates the appearance of the Lens button after the ui interface environment +// changes. +void UpdateLensButtonAppearance(UIButton* button); + // Returns the leading buttons of the assistive view. NSArray<UIControl*>* OmniboxAssistiveKeyboardLeadingControls( id<OmniboxAssistiveKeyboardDelegate> delegate,
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm index 5456e7f5..ce94c127 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.mm
@@ -41,14 +41,17 @@ button.layer.shadowRadius = kButtonShadowRadius; } -void SetUpButtonWithSymbol(UIButton* button, NSString* symbolName) { +} // namespace + +void UpdateLensButtonAppearance(UIButton* button) { [button setTranslatesAutoresizingMaskIntoConstraints:NO]; UIImageSymbolConfiguration* configuration = [UIImageSymbolConfiguration configurationWithPointSize:kSymbolPointSize weight:UIImageSymbolWeightSemibold scale:UIImageSymbolScaleMedium]; - UIImage* icon = CustomSymbolWithConfiguration(symbolName, configuration); + UIImage* icon = + CustomSymbolWithConfiguration(kCameraLensSymbol, configuration); if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { icon = MakeSymbolMonochrome(icon); @@ -72,8 +75,6 @@ ]]; } -} // namespace - NSArray<UIControl*>* OmniboxAssistiveKeyboardLeadingControls( id<OmniboxAssistiveKeyboardDelegate> delegate, id<UIPasteConfigurationSupporting> pasteTarget, @@ -97,7 +98,8 @@ [ExtendedTouchTargetButton buttonWithType:UIButtonTypeCustom]; if (useLens) { // Set up the camera button for Lens. - SetUpButtonWithSymbol(cameraButton, kCameraLensSymbol); + delegate.lensButton = cameraButton; + UpdateLensButtonAppearance(cameraButton); [cameraButton addTarget:delegate action:@selector(keyboardAccessoryLensTapped) forControlEvents:UIControlEventTouchUpInside];
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm index 16d63926..9da736e 100644 --- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm +++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_keyboard_accessory_view.mm
@@ -70,6 +70,16 @@ return self; } +- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + // The Lens button needs to be updated when the device goes from light to dark + // mode or vice versa. + UIButton* lensButton = _delegate.lensButton; + if (lensButton) { + UpdateLensButtonAppearance(lensButton); + } +} + - (void)addSubviews { if (!self.subviews.count) return;
diff --git a/ios/chrome/browser/ui/safe_mode/BUILD.gn b/ios/chrome/browser/ui/safe_mode/BUILD.gn index 3663a9a..4ce8ed8 100644 --- a/ios/chrome/browser/ui/safe_mode/BUILD.gn +++ b/ios/chrome/browser/ui/safe_mode/BUILD.gn
@@ -66,6 +66,9 @@ "//ios/testing:block_swizzler", "//ios/testing/earl_grey:eg_test_support+eg2", "//ui/base", + + # TODO(crbug.com/1484597): Remove this when the issue is fixed. + "//components/sync/base:features", ] frameworks = [ "UIKit.framework" ] }
diff --git a/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm b/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm index b7ba2b1..ac9e4c7 100644 --- a/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm +++ b/ios/chrome/browser/ui/safe_mode/safe_mode_egtest.mm
@@ -22,6 +22,9 @@ #import "ios/testing/scoped_block_swizzler.h" #import "ui/base/l10n/l10n_util.h" +// TODO(crbug.com/1484597): Remove this when the issue is fixed. +#import "components/sync/base/features.h" + using chrome_test_util::ButtonWithAccessibilityLabel; namespace { @@ -69,6 +72,14 @@ @implementation SafeModeTestCase +// TODO(crbug.com/1484597): Remove this when the issue is fixed. +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config; + config.features_disabled.push_back( + syncer::kReplaceSyncPromosWithSignInPromos); + return config; +} + // Tests that Safe Mode crash upload screen is displayed when there are crash // reports to upload. - (void)testSafeModeSendingCrashReport {
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm index 41fcba6..5d916f7 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm
@@ -32,6 +32,7 @@ #import "ui/base/l10n/l10n_util.h" using password_manager::WarningType; +using password_manager::features::IsAuthOnEntryV2Enabled; namespace { @@ -144,8 +145,10 @@ // Disable animation when content will be blocked for reauth to prevent // flickering in navigation bar. - [self.baseNavigationController pushViewController:self.viewController - animated:_skipAuthenticationOnStart]; + [self.baseNavigationController + pushViewController:self.viewController + animated:_skipAuthenticationOnStart || + !IsAuthOnEntryV2Enabled()]; [self startReauthCoordinatorWithAuthOnStart:!_skipAuthenticationOnStart]; } @@ -294,7 +297,7 @@ // scene is backgrounded and foregrounded until reauthCoordinator is stopped. - (void)startReauthCoordinatorWithAuthOnStart:(BOOL)authOnStart { // No-op if Auth on Entry is not enabled for the password manager. - if (!password_manager::features::IsAuthOnEntryV2Enabled()) { + if (!IsAuthOnEntryV2Enabled()) { return; } @@ -329,7 +332,7 @@ - (void)restartReauthCoordinator { // Restart reauth coordinator so it monitors scene state changes and requests // local authentication after the scene goes to the background. - if (password_manager::features::IsAuthOnEntryV2Enabled()) { + if (IsAuthOnEntryV2Enabled()) { [self startReauthCoordinatorWithAuthOnStart:NO]; } }
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm index 304b68ed..0d4108d0 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -187,19 +187,20 @@ // can leave the new top view controller with a toolbar when it doesn't // require one. Disabling editing mode to avoid this. See crbug.com/1404111 as // an example. - if (parent == nullptr) { - if ([self respondsToSelector:@selector(settingsWillBeDismissed)]) { - [self performSelector:@selector(settingsWillBeDismissed)]; - } - - if (self.isEditing) { - [self setEditing:NO animated:NO]; - } + if (!parent && self.isEditing) { + [self setEditing:NO animated:NO]; } [self.navigationController setToolbarHidden:YES animated:YES]; } +- (void)didMoveToParentViewController:(UIViewController*)parent { + [super didMoveToParentViewController:parent]; + if (!parent && [self respondsToSelector:@selector(settingsWillBeDismissed)]) { + [self performSelector:@selector(settingsWillBeDismissed)]; + } +} + - (void)setEditing:(BOOL)editing animated:(BOOL)animated { [super setEditing:editing animated:animated]; if (!editing)
diff --git a/ios/web/js_messaging/java_script_content_world.mm b/ios/web/js_messaging/java_script_content_world.mm index 5addf9f..eb40125 100644 --- a/ios/web/js_messaging/java_script_content_world.mm +++ b/ios/web/js_messaging/java_script_content_world.mm
@@ -6,6 +6,7 @@ #import "base/check_op.h" #import "base/containers/contains.h" +#import "base/debug/crash_logging.h" #import "base/notreached.h" #import "base/strings/sys_string_conversions.h" #import "ios/web/js_messaging/web_view_js_utils.h" @@ -154,6 +155,9 @@ JavaScriptFeature::ScriptMessageHandler handler, BrowserState* browser_state, WKScriptMessage* script_message) { + SCOPED_CRASH_KEY_STRING32("ScriptMessage", "name", + base::SysNSStringToUTF8(script_message.name)); + web::WebViewWebStateMap* map = web::WebViewWebStateMap::FromBrowserState(browser_state); web::WebState* web_state = map->GetWebStateForWebView(script_message.webView);
diff --git a/ios/web/js_messaging/web_view_js_utils.mm b/ios/web/js_messaging/web_view_js_utils.mm index d833d14..59eb4efa 100644 --- a/ios/web/js_messaging/web_view_js_utils.mm +++ b/ios/web/js_messaging/web_view_js_utils.mm
@@ -8,6 +8,7 @@ #import <WebKit/WebKit.h> #import "base/apple/foundation_util.h" +#import "base/debug/crash_logging.h" #import "base/logging.h" #import "base/notreached.h" #import "base/strings/sys_string_conversions.h" @@ -47,6 +48,7 @@ for (id key in wk_result) { NSString* obj_c_string = base::apple::ObjCCast<NSString>(key); const std::string path = base::SysNSStringToUTF8(obj_c_string); + SCOPED_CRASH_KEY_STRING32("ScriptMessage", "path", path); std::unique_ptr<base::Value> value = ValueResultFromWKResult(wk_result[obj_c_string], max_depth - 1); if (value) {
diff --git a/ios_internal b/ios_internal index 8dee0d1..6e026a7 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 8dee0d1c5ee5e14dde381c8a1ec44b82e9d0eaec +Subproject commit 6e026a76cf60b32d9e8ac71e7aaacca05a6b1c37
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 47ea0039..00d35ea 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -571,7 +571,7 @@ // hardware video decoders. BASE_FEATURE(kUseMultiPlaneFormatForHardwareVideo, "UseMultiPlaneFormatForHardwareVideo", -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) || BUILDFLAG(IS_FUCHSIA) base::FEATURE_ENABLED_BY_DEFAULT #else base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/net/base/features.cc b/net/base/features.cc index 01ed763..24f700b 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -455,8 +455,4 @@ "ThirdPartyPartitionedStorageAllowedByDefault", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kCookieDeprecationFacilitatedTestingLabels, - "CookieDeprecationFacilitatedTestingLabels", - base::FEATURE_DISABLED_BY_DEFAULT); - } // namespace net::features
diff --git a/net/base/features.h b/net/base/features.h index fb3cd1f..2d1797d 100644 --- a/net/base/features.h +++ b/net/base/features.h
@@ -452,13 +452,6 @@ NET_EXPORT BASE_DECLARE_FEATURE(kThirdPartyPartitionedStorageAllowedByDefault); -// Gate access to cookie deprecation API which allows developers to opt in -// server side testing without cookies. This doesn't actually do anything in -// terms of deprecating cookies. -// (See -// https://developer.chrome.com/en/docs/privacy-sandbox/chrome-testing/#mode-a) -NET_EXPORT BASE_DECLARE_FEATURE(kCookieDeprecationFacilitatedTestingLabels); - } // namespace net::features #endif // NET_BASE_FEATURES_H_
diff --git a/net/cookies/cookie_inclusion_status.cc b/net/cookies/cookie_inclusion_status.cc index 117fca1..368a4ef 100644 --- a/net/cookies/cookie_inclusion_status.cc +++ b/net/cookies/cookie_inclusion_status.cc
@@ -338,10 +338,13 @@ } bool CookieInclusionStatus::ExcludedByUserPreferences() const { - if (HasOnlyExclusionReason(ExclusionReason::EXCLUDE_USER_PREFERENCES)) + if (HasOnlyExclusionReason(ExclusionReason::EXCLUDE_USER_PREFERENCES) || + HasOnlyExclusionReason(ExclusionReason::EXCLUDE_THIRD_PARTY_PHASEOUT)) { return true; + } return exclusion_reasons_.count() == 2 && - exclusion_reasons_[ExclusionReason::EXCLUDE_USER_PREFERENCES] && + (exclusion_reasons_[ExclusionReason::EXCLUDE_USER_PREFERENCES] || + exclusion_reasons_[ExclusionReason::EXCLUDE_THIRD_PARTY_PHASEOUT]) && exclusion_reasons_ [ExclusionReason:: EXCLUDE_THIRD_PARTY_BLOCKED_WITHIN_FIRST_PARTY_SET];
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index eac944172..1d7c8723 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -34,7 +34,6 @@ #include "base/types/optional_util.h" #include "base/values.h" #include "build/build_config.h" -#include "net/base/features.h" #include "net/base/host_port_pair.h" #include "net/base/http_user_agent_settings.h" #include "net/base/load_flags.h" @@ -769,8 +768,6 @@ size_t n_partitioned_cookies = 0; bool may_set_sec_cookie_deprecation_header = - base::FeatureList::IsEnabled( - net::features::kCookieDeprecationFacilitatedTestingLabels) && request_->context()->cookie_deprecation_label().has_value(); // TODO(crbug.com/1031664): Reduce the number of times the cookie list
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index f9b7f1a..b6eb95bb1 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -282,12 +282,12 @@ net::CookieInclusionStatus:: WARN_TENTATIVELY_ALLOWING_SECURE_SOURCE_SCHEME); - // TODO(crbug.com/1469135): We may want to notify about cookies blocked due to - // 3PCD enabled via local switch. return status.IsInclude() || status.ShouldWarn() || status.HasExclusionReason( net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES) || status.HasExclusionReason( + net::CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT) || + status.HasExclusionReason( net::CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII); }
diff --git a/testing/buildbot/chromium.cft.json b/testing/buildbot/chromium.cft.json index 0da2152..6ece7dc 100644 --- a/testing/buildbot/chromium.cft.json +++ b/testing/buildbot/chromium.cft.json
@@ -1914,6 +1914,7 @@ "enable": true, "has_native_resultdb_integration": true }, + "results_handler": "layout tests", "swarming": { "dimensions": { "cpu": "arm64",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index cb4d6c1..2d80d028 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -1284,6 +1284,7 @@ "--board=amd64-generic", "--use-vm" ], + "ci_only": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -5075,9 +5076,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5087,8 +5088,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -5223,9 +5224,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5235,8 +5236,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -5355,9 +5356,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5367,8 +5368,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index adbf431..4d417c6 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -24601,6 +24601,7 @@ "enable": true, "has_native_resultdb_integration": true }, + "results_handler": "layout tests", "swarming": { "dimensions": { "os": "Ubuntu-22.04" @@ -25384,9 +25385,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25396,8 +25397,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -25532,9 +25533,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25544,8 +25545,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -25664,9 +25665,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25676,8 +25677,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index d6751841..01e1d10d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -43200,9 +43200,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43211,8 +43211,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -43348,9 +43348,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43359,8 +43359,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -43480,9 +43480,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43491,8 +43491,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -44804,9 +44804,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44815,8 +44815,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -44952,9 +44952,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44963,8 +44963,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -45084,9 +45084,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45095,8 +45095,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -45794,9 +45794,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45805,8 +45805,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -48120,6 +48120,7 @@ "enable": true, "has_native_resultdb_integration": true }, + "results_handler": "layout tests", "swarming": { "dimensions": { "os": "Ubuntu-22.04",
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 0f53c87..84679885 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -6829,6 +6829,7 @@ "enable": true, "has_native_resultdb_integration": true }, + "results_handler": "layout tests", "swarming": { "dimensions": { "os": "Ubuntu-22.04"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 25941de..81e00bda 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -16439,12 +16439,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16454,8 +16454,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -16607,12 +16607,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16622,8 +16622,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": { @@ -16754,12 +16754,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 119.0.6017.0", + "description": "Run with ash-chrome version 119.0.6018.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16769,8 +16769,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v119.0.6017.0", - "revision": "version:119.0.6017.0" + "location": "lacros_version_skew_tests_v119.0.6018.0", + "revision": "version:119.0.6018.0" } ], "dimensions": {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 6ef0d30..28aa498 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -2,7 +2,7 @@ # Instead: # 1. Modify //infra/config/targets/targets.star # 2. Run //infra/config/main.star -# 3. Run //infra/config/scripts/sync-py-files.py +# 3. Run //infra/config/scripts/sync-pyl-files.py { "absl_hardening_tests": {
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 236d85e..b8aac13 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -2,7 +2,7 @@ # Instead: # 1. Modify //infra/config/targets/mixins.star # 2. Run //infra/config/main.star -# 3. Run //infra/config/scripts/sync-py-files.py +# 3. Run //infra/config/scripts/sync-pyl-files.py { '10-x86-emulator': {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 3f8d4bc..a0dbd6a4 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -3379,6 +3379,13 @@ }, }, }, + 'lacros_all_tast_tests amd64-generic': { + 'modifications': { + 'lacros-amd64-generic-rel': { + 'ci_only': True, + } + } + }, 'lacros_chrome_browsertests_run_in_series': { 'modifications': { 'linux-lacros-asan-lsan-rel': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index ad187ff..8e64575 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -4626,6 +4626,7 @@ 'mixins': [ 'has_native_resultdb_integration', ], + 'results_handler': 'layout tests', 'swarming': { 'shards': 2, },
diff --git a/testing/buildbot/tryserver.blink.json b/testing/buildbot/tryserver.blink.json index 283d029..34429a6 100644 --- a/testing/buildbot/tryserver.blink.json +++ b/testing/buildbot/tryserver.blink.json
@@ -215,6 +215,7 @@ "enable": true, "has_native_resultdb_integration": true }, + "results_handler": "layout tests", "swarming": { "dimensions": { "os": "Ubuntu-22.04"
diff --git a/testing/buildbot/tryserver.v8.json b/testing/buildbot/tryserver.v8.json index af9b2c8f..b620fe3 100644 --- a/testing/buildbot/tryserver.v8.json +++ b/testing/buildbot/tryserver.v8.json
@@ -213,6 +213,7 @@ "enable": true, "has_native_resultdb_integration": true }, + "results_handler": "layout tests", "swarming": { "dimensions": { "os": "Ubuntu-22.04"
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 1d77022..628d07f 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -2,7 +2,7 @@ # Instead: # 1. Modify //infra/config/targets/variants.star # 2. Run //infra/config/main.star -# 3. Run //infra/config/scripts/sync-py-files.py +# 3. Run //infra/config/scripts/sync-pyl-files.py { 'DISABLE_FIELD_TRIAL_CONFIG': { @@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 119.0.6017.0', + 'description': 'Run with ash-chrome version 119.0.6018.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6017.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v119.0.6018.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v119.0.6017.0', - 'revision': 'version:119.0.6017.0', + 'location': 'lacros_version_skew_tests_v119.0.6018.0', + 'revision': 'version:119.0.6018.0', }, ], },
diff --git a/testing/iossim/iossim.mm b/testing/iossim/iossim.mm index 41a740e..03814ec3 100644 --- a/testing/iossim/iossim.mm +++ b/testing/iossim/iossim.mm
@@ -303,14 +303,6 @@ XCRunTask* install_task = [[XCRunTask alloc] initWithArguments:@[ @"simctl", @"install", udid, app_path ]]; [install_task run]; - - XCRunTask* launch_task = [[XCRunTask alloc] - initWithArguments:@[ @"simctl", @"launch", udid, bundle_identifier ]]; - [launch_task run]; - - XCRunTask* terminate_task = [[XCRunTask alloc] - initWithArguments:@[ @"simctl", @"terminate", udid, bundle_identifier ]]; - [terminate_task run]; } int RunWebTest(NSString* app_path, NSString* udid, NSMutableArray* cmd_args) {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index b9f89dda..0875c85 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -195,24 +195,6 @@ ] } ], - "AndroidAppIntegration": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "content_ttl_hours": "168" - }, - "enable_features": [ - "AndroidAppIntegration" - ] - } - ] - } - ], "AndroidAutofillFormSubmissionCheckById": [ { "platforms": [ @@ -1822,6 +1804,7 @@ { "platforms": [ "android", + "android_webview", "chromeos", "chromeos_lacros", "linux", @@ -1830,7 +1813,7 @@ ], "experiments": [ { - "name": "Enabled", + "name": "Enabled_20230919", "enable_features": [ "AutofillUseDomNodeIdForRendererId" ] @@ -13617,6 +13600,23 @@ ] } ], + "ReportAllAvailablePointerTypes": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReportAllAvailablePointerTypes" + ] + } + ] + } + ], "ReportCertificateErrors": [ { "platforms": [ @@ -13933,6 +13933,28 @@ ] } ], + "SafeBrowsingFriendlierSettings": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FriendlierSafeBrowsingSettingsEnhancedProtection", + "FriendlierSafeBrowsingSettingsStandardProtection" + ] + } + ] + } + ], "SafeBrowsingHashPrefixRealTimeLookups": [ { "platforms": [
diff --git a/third_party/android_toolchain/3pp/3pp.pb b/third_party/android_toolchain/3pp/3pp.pb index be5602e..1b6da62 100644 --- a/third_party/android_toolchain/3pp/3pp.pb +++ b/third_party/android_toolchain/3pp/3pp.pb
@@ -4,13 +4,8 @@ create { source { - url { - download_url: "https://dl.google.com/android/repository/android-ndk-r25c-linux.zip" - version: "r25c" - extension: ".zip" - } + script { name: "fetch.py" } unpack_archive: true - patch_version: "cr3" } # This will execute the `install.sh` script in 3pp dir after the source CIPD
diff --git a/third_party/android_toolchain/3pp/fetch.py b/third_party/android_toolchain/3pp/fetch.py new file mode 100755 index 0000000..49a2dc8 --- /dev/null +++ b/third_party/android_toolchain/3pp/fetch.py
@@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# Copyright 2023 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import hashlib +import json +import pathlib + + +# Update this when upgrading NDK. +_URL = "https://dl.google.com/android/repository/android-ndk-r25c-linux.zip" + +def do_latest(): + # Change version time this file changes. + md5 = hashlib.md5() + md5.update(pathlib.Path(__file__).read_bytes()) + + this_dir = pathlib.Path(__file__).parent + # Trigger on changes to other files in this directory. + md5.update((this_dir / '3pp.pb').read_bytes()) + md5.update((this_dir / 'install.sh').read_bytes()) + print(md5.hexdigest()) + + +def do_get_url(): + partial_manifest = { + 'url': [_URL], + 'ext': '.zip', + } + print(json.dumps(partial_manifest)) + + +def main(): + ap = argparse.ArgumentParser() + sub = ap.add_subparsers(required=True) + + latest = sub.add_parser("latest") + latest.set_defaults(func=do_latest) + + download = sub.add_parser("get_url") + download.set_defaults(func=lambda: do_get_url()) + + opts = ap.parse_args() + opts.func() + + +if __name__ == '__main__': + main()
diff --git a/third_party/android_toolchain/README.chromium b/third_party/android_toolchain/README.chromium index 4e93117..870d41c 100644 --- a/third_party/android_toolchain/README.chromium +++ b/third_party/android_toolchain/README.chromium
@@ -17,6 +17,20 @@ This allows us to use tracing and gdb support, while limiting our dependencies. +How to upgrade NDK: +1. Assign `_URL` variable in `3pp/fetch.py` to point to the new file. Edit + `README.chromium` and `3pp/install.sh` as needed. Commit. +2. The builder for CIPD packagers +https://ci.chromium.org/ui/p/chromium/builders/ci/3pp-linux-amd64-packager + should run (trigger if needed) with the commit. Wait for it to finish. +3. The `fetch.py` change leads to version code change, which triggers update in + "latest" entry for the page: +https://chrome-infra-packages.appspot.com/p/chromium/third_party/android_toolchain/android_toolchain +4. Copy the full hash from the above. Open `/DEPS`, under the + `src/third_party/android_toolchain/ndk` entry, update `packages` -> + `version` value with the full hash. Commit. +5. `gclient sync` on updated Chromium repo will pull in the updated NDK. + Local Modifications: * Removed files in the sysroot that conflict with other files when unzipped on case-insensitive filesystems (e.g. usr/include/netfilter/xt_CONNMARK.h).
diff --git a/third_party/android_toolchain_canary/3pp/3pp.pb b/third_party/android_toolchain_canary/3pp/3pp.pb index 889702c..b0874d0 100644 --- a/third_party/android_toolchain_canary/3pp/3pp.pb +++ b/third_party/android_toolchain_canary/3pp/3pp.pb
@@ -4,13 +4,8 @@ create { source { - url { - download_url: "https://ci.android.com/builds/submitted/10625055/linux/latest/raw/android-ndk-10625055-linux-x86_64.zip" - version: "10625055" - extension: ".zip" - } + script { name: "fetch.py" } unpack_archive: true - patch_version: "cr1" } # This will execute the `install.sh` script in 3pp dir after the source CIPD
diff --git a/third_party/android_toolchain_canary/3pp/fetch.py b/third_party/android_toolchain_canary/3pp/fetch.py new file mode 100755 index 0000000..9f017fd --- /dev/null +++ b/third_party/android_toolchain_canary/3pp/fetch.py
@@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# Copyright 2023 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import hashlib +import json +import pathlib + + +# Update this when upgrading NDK. +_URL = "https://ci.android.com/builds/submitted/10625055/linux/latest/raw/android-ndk-10625055-linux-x86_64.zip" + +def do_latest(): + # Change version time this file changes. + md5 = hashlib.md5() + md5.update(pathlib.Path(__file__).read_bytes()) + + this_dir = pathlib.Path(__file__).parent + # Trigger on changes to other files in this directory. + md5.update((this_dir / '3pp.pb').read_bytes()) + md5.update((this_dir / 'install.sh').read_bytes()) + print(md5.hexdigest()) + + +def do_get_url(): + partial_manifest = { + 'url': [_URL], + 'ext': '.zip', + } + print(json.dumps(partial_manifest)) + + +def main(): + ap = argparse.ArgumentParser() + sub = ap.add_subparsers(required=True) + + latest = sub.add_parser("latest") + latest.set_defaults(func=do_latest) + + download = sub.add_parser("get_url") + download.set_defaults(func=lambda: do_get_url()) + + opts = ap.parse_args() + opts.func() + + +if __name__ == '__main__': + main()
diff --git a/third_party/android_toolchain_canary/README.chromium b/third_party/android_toolchain_canary/README.chromium index 5be941f..9fc58bd 100644 --- a/third_party/android_toolchain_canary/README.chromium +++ b/third_party/android_toolchain_canary/README.chromium
@@ -17,6 +17,20 @@ This allows us to use tracing and gdb support, while limiting our dependencies. +How to upgrade NDK: +1. Assign `_URL` variable in `3pp/fetch.py` to point to the new file. Edit + `README.chromium` and `3pp/install.sh` as needed. Commit. +2. The builder for CIPD packagers +https://ci.chromium.org/ui/p/chromium/builders/ci/3pp-linux-amd64-packager + should run (trigger if needed) with the commit. Wait for it to finish. +3. The `fetch.py` change leads to version code change, which triggers update in + "latest" entry for the page: +https://chrome-infra-packages.appspot.com/p/chromium/third_party/android_toolchain_canary/android_toolchain_canary +4. Copy the full hash from the above. Open `/DEPS`, under the + `src/third_party/android_toolchain_canary/ndk` entry, update `packages` -> + `version` value with the full hash. Commit. +5. `gclient sync` on updated Chromium repo will pull in the updated NDK. + Local Modifications: * Removed files in the sysroot that conflict with other files when unzipped on case-insensitive filesystems (e.g. usr/include/netfilter/xt_CONNMARK.h).
diff --git a/third_party/angle b/third_party/angle index 91ef1f3..eb0d599 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 91ef1f3cfd307b1b48ef692b5ab44520563a22c4 +Subproject commit eb0d59973d21f845b5785563f5d56b8ebb617478
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 79995c2..cafca57 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -5736,6 +5736,8 @@ SameSiteNoneInsecure # The cookie was not stored due to user preferences. UserPreferences + # The cookie was blocked due to third-party cookie phaseout. + ThirdPartyPhaseout # The cookie was blocked by third-party cookie blocking between sites in # the same First-Party Set. ThirdPartyBlockedInFirstPartySet @@ -5807,6 +5809,8 @@ SameSiteNoneInsecure # The cookie was not sent due to user preferences. UserPreferences + # The cookie was blocked due to third-party cookie phaseout. + ThirdPartyPhaseout # The cookie was blocked by third-party cookie blocking between sites in # the same First-Party Set. ThirdPartyBlockedInFirstPartySet @@ -9331,6 +9335,8 @@ loaded bid win + additionalBid + additionalBidWin # Ad advertising element inside an interest group. type InterestGroupAd extends object
diff --git a/third_party/blink/public/web/web_frame.h b/third_party/blink/public/web/web_frame.h index 4c01b392..f47fa4a 100644 --- a/third_party/blink/public/web/web_frame.h +++ b/third_party/blink/public/web/web_frame.h
@@ -158,7 +158,7 @@ // Returns true if the WebFrame currently executing JavaScript has access // to the given WebFrame, or false otherwise. - static bool ScriptCanAccess(WebFrame*); + static bool ScriptCanAccess(v8::Isolate* isolate, WebFrame*); // Navigation ----------------------------------------------------------
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc index 9f5c538..50306197 100644 --- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc +++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -109,7 +109,8 @@ // willReleaseScriptContext callback, so all disposing should happen after // it returns. GetFrame()->Client()->WillReleaseScriptContext(context, world_->GetWorldId()); - MainThreadDebugger::Instance()->ContextWillBeDestroyed(script_state_); + MainThreadDebugger::Instance(script_state_->GetIsolate()) + ->ContextWillBeDestroyed(script_state_); if (next_status == Lifecycle::kV8MemoryIsForciblyPurged || next_status == Lifecycle::kGlobalObjectIsDetached) { // Clean up state on the global proxy, which will be reused. @@ -195,8 +196,8 @@ TRACE_EVENT2("v8", "ContextCreatedNotification", "IsMainFrame", GetFrame()->IsMainFrame(), "IsOutermostMainFrame", GetFrame()->IsOutermostMainFrame()); - MainThreadDebugger::Instance()->ContextCreated(script_state_, GetFrame(), - origin.get()); + MainThreadDebugger::Instance(script_state_->GetIsolate()) + ->ContextCreated(script_state_, GetFrame(), origin.get()); GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); }
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index 2a3f50e..1b34c80 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -594,6 +594,10 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_timeline_phase.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_timeline_range.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_timeline_range.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underline_style.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underline_style.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underline_thickness.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underline_thickness.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_url_pattern_component.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_url_pattern_component.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visibility_state.cc",
diff --git a/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc index 332ba42b..ddb004cef 100644 --- a/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc
@@ -43,7 +43,7 @@ InterpolationValue CSSFontStretchInterpolationType::MaybeConvertInitial( const StyleResolverState&, ConversionCheckers& conversion_checkers) const { - return CreateFontStretchValue(NormalWidthValue()); + return CreateFontStretchValue(kNormalWidthValue); } InterpolationValue CSSFontStretchInterpolationType::MaybeConvertInherit(
diff --git a/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc index a35137e..ccd6d02 100644 --- a/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc
@@ -43,7 +43,7 @@ InterpolationValue CSSFontStyleInterpolationType::MaybeConvertInitial( const StyleResolverState&, ConversionCheckers& conversion_checkers) const { - return CreateFontStyleValue(NormalSlopeValue()); + return CreateFontStyleValue(kNormalSlopeValue); } InterpolationValue CSSFontStyleInterpolationType::MaybeConvertInherit( @@ -81,7 +81,7 @@ StyleResolverState& state) const { state.GetFontBuilder().SetStyle(FontSelectionValue( ClampTo(To<InterpolableNumber>(interpolable_value).Value(), - MinObliqueValue(), MaxObliqueValue()))); + kMinObliqueValue, kMaxObliqueValue))); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc index 323a9fb4..c900bfa 100644 --- a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
@@ -43,7 +43,7 @@ InterpolationValue CSSFontWeightInterpolationType::MaybeConvertInitial( const StyleResolverState&, ConversionCheckers& conversion_checkers) const { - return CreateFontWeightValue(NormalWeightValue()); + return CreateFontWeightValue(kNormalWeightValue); } InterpolationValue CSSFontWeightInterpolationType::MaybeConvertInherit( @@ -88,7 +88,7 @@ StyleResolverState& state) const { state.GetFontBuilder().SetWeight(FontSelectionValue( ClampTo(To<InterpolableNumber>(interpolable_value).Value(), - MinWeightValue(), MaxWeightValue()))); + kMinWeightValue, kMaxWeightValue))); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_font_face_source_test.cc b/third_party/blink/renderer/core/css/css_font_face_source_test.cc index cfdf099..ba530d8 100644 --- a/third_party/blink/renderer/core/css/css_font_face_source_test.cc +++ b/third_party/blink/renderer/core/css/css_font_face_source_test.cc
@@ -31,9 +31,9 @@ FontDescription font_description; font_description.SetComputedSize(size); FontSelectionCapabilities normal_capabilities( - {NormalWidthValue(), NormalWidthValue()}, - {NormalSlopeValue(), NormalSlopeValue()}, - {NormalWeightValue(), NormalWeightValue()}); + {kNormalWidthValue, kNormalWidthValue}, + {kNormalSlopeValue, kNormalSlopeValue}, + {kNormalWeightValue, kNormalWeightValue}); return GetFontData(font_description, normal_capabilities); } }; @@ -67,9 +67,9 @@ DummyFontFaceSource font_face_source; FontDescription font_description_variable; FontSelectionCapabilities normal_capabilities( - {NormalWidthValue(), NormalWidthValue()}, - {NormalSlopeValue(), NormalSlopeValue()}, - {NormalWeightValue(), NormalWeightValue()}); + {kNormalWidthValue, kNormalWidthValue}, + {kNormalSlopeValue, kNormalSlopeValue}, + {kNormalWeightValue, kNormalWeightValue}); // Roughly 3000 font variants. for (float wght = 700; wght < 705; wght += 1 / 6.f) {
diff --git a/third_party/blink/renderer/core/css/css_segmented_font_face.cc b/third_party/blink/renderer/core/css/css_segmented_font_face.cc index 5e6b3cb..ec0bacaa 100644 --- a/third_party/blink/renderer/core/css/css_segmented_font_face.cc +++ b/third_party/blink/renderer/core/css/css_segmented_font_face.cc
@@ -142,12 +142,12 @@ const FontSelectionRequest& font_selection_request = font_description.GetFontSelectionRequest(); requested_font_description.SetSyntheticBold( - font_selection_capabilities_.weight.maximum < BoldThreshold() && - font_selection_request.weight >= BoldThreshold() && + font_selection_capabilities_.weight.maximum < kBoldThreshold && + font_selection_request.weight >= kBoldThreshold && font_description.SyntheticBoldAllowed()); requested_font_description.SetSyntheticItalic( - font_selection_capabilities_.slope.maximum < ItalicSlopeValue() && - font_selection_request.slope >= ItalicSlopeValue() && + font_selection_capabilities_.slope.maximum < kItalicSlopeValue && + font_selection_request.slope >= kItalicSlopeValue && font_description.SyntheticItalicAllowed()); font_faces_->ForEachReverse(WTF::BindRepeating(
diff --git a/third_party/blink/renderer/core/css/font_face.cc b/third_party/blink/renderer/core/css/font_face.cc index 06a3082..4cfe6cf 100644 --- a/third_party/blink/renderer/core/css/font_face.cc +++ b/third_party/blink/renderer/core/css/font_face.cc
@@ -594,9 +594,9 @@ // weight values. The first value of each pair is the minimum value, the // second is the maximum value. FontSelectionCapabilities normal_capabilities( - {NormalWidthValue(), NormalWidthValue()}, - {NormalSlopeValue(), NormalSlopeValue()}, - {NormalWeightValue(), NormalWeightValue()}); + {kNormalWidthValue, kNormalWidthValue}, + {kNormalSlopeValue, kNormalSlopeValue}, + {kNormalWeightValue, kNormalWeightValue}); FontSelectionCapabilities capabilities(normal_capabilities); if (stretch_) { @@ -604,46 +604,46 @@ DynamicTo<CSSIdentifierValue>(stretch_.Get())) { switch (stretch_identifier_value->GetValueID()) { case CSSValueID::kUltraCondensed: - capabilities.width = {UltraCondensedWidthValue(), - UltraCondensedWidthValue(), + capabilities.width = {kUltraCondensedWidthValue, + kUltraCondensedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kExtraCondensed: - capabilities.width = {ExtraCondensedWidthValue(), - ExtraCondensedWidthValue(), + capabilities.width = {kExtraCondensedWidthValue, + kExtraCondensedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kCondensed: - capabilities.width = {CondensedWidthValue(), CondensedWidthValue(), + capabilities.width = {kCondensedWidthValue, kCondensedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kSemiCondensed: - capabilities.width = {SemiCondensedWidthValue(), - SemiCondensedWidthValue(), + capabilities.width = {kSemiCondensedWidthValue, + kSemiCondensedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kSemiExpanded: - capabilities.width = {SemiExpandedWidthValue(), - SemiExpandedWidthValue(), + capabilities.width = {kSemiExpandedWidthValue, + kSemiExpandedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kExpanded: - capabilities.width = {ExpandedWidthValue(), ExpandedWidthValue(), + capabilities.width = {kExpandedWidthValue, kExpandedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kExtraExpanded: - capabilities.width = {ExtraExpandedWidthValue(), - ExtraExpandedWidthValue(), + capabilities.width = {kExtraExpandedWidthValue, + kExtraExpandedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kUltraExpanded: - capabilities.width = {UltraExpandedWidthValue(), - UltraExpandedWidthValue(), + capabilities.width = {kUltraExpandedWidthValue, + kUltraExpandedWidthValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kAuto: DCHECK(RuntimeEnabledFeatures::CSSFontFaceAutoVariableRangeEnabled()); - capabilities.width = {NormalWidthValue(), NormalWidthValue(), + capabilities.width = {kNormalWidthValue, kNormalWidthValue, FontSelectionRange::RangeType::kSetFromAuto}; break; default: @@ -696,20 +696,20 @@ if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(style_.Get())) { switch (identifier_value->GetValueID()) { case CSSValueID::kNormal: - capabilities.slope = {NormalSlopeValue(), NormalSlopeValue(), + capabilities.slope = {kNormalSlopeValue, kNormalSlopeValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kOblique: - capabilities.slope = {ItalicSlopeValue(), ItalicSlopeValue(), + capabilities.slope = {kItalicSlopeValue, kItalicSlopeValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kItalic: - capabilities.slope = {ItalicSlopeValue(), ItalicSlopeValue(), + capabilities.slope = {kItalicSlopeValue, kItalicSlopeValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kAuto: DCHECK(RuntimeEnabledFeatures::CSSFontFaceAutoVariableRangeEnabled()); - capabilities.slope = {NormalSlopeValue(), NormalSlopeValue(), + capabilities.slope = {kNormalSlopeValue, kNormalSlopeValue, FontSelectionRange::RangeType::kSetFromAuto}; break; default: @@ -723,12 +723,12 @@ if (!range_value->GetObliqueValues()) { if (font_style_id == CSSValueID::kNormal) { capabilities.slope = { - NormalSlopeValue(), NormalSlopeValue(), + kNormalSlopeValue, kNormalSlopeValue, FontSelectionRange::RangeType::kSetExplicitly}; } DCHECK(font_style_id == CSSValueID::kItalic || font_style_id == CSSValueID::kOblique); - capabilities.slope = {ItalicSlopeValue(), ItalicSlopeValue(), + capabilities.slope = {kItalicSlopeValue, kItalicSlopeValue, FontSelectionRange::RangeType::kSetExplicitly}; } else { DCHECK(font_style_id == CSSValueID::kOblique); @@ -774,16 +774,16 @@ if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(weight_.Get())) { switch (identifier_value->GetValueID()) { case CSSValueID::kNormal: - capabilities.weight = {NormalWeightValue(), NormalWeightValue(), + capabilities.weight = {kNormalWeightValue, kNormalWeightValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kBold: - capabilities.weight = {BoldWeightValue(), BoldWeightValue(), + capabilities.weight = {kBoldWeightValue, kBoldWeightValue, FontSelectionRange::RangeType::kSetExplicitly}; break; case CSSValueID::kAuto: DCHECK(RuntimeEnabledFeatures::CSSFontFaceAutoVariableRangeEnabled()); - capabilities.weight = {NormalWeightValue(), NormalWeightValue(), + capabilities.weight = {kNormalWeightValue, kNormalWeightValue, FontSelectionRange::RangeType::kSetFromAuto}; break; default:
diff --git a/third_party/blink/renderer/core/css/font_face_cache_test.cc b/third_party/blink/renderer/core/css/font_face_cache_test.cc index 96cb63c..42c0b91 100644 --- a/third_party/blink/renderer/core/css/font_face_cache_test.cc +++ b/third_party/blink/renderer/core/css/font_face_cache_test.cc
@@ -118,7 +118,7 @@ CSSIdentifierValue* stretch_value_condensed = CSSIdentifierValue::Create(CSSValueID::kCondensed); CSSPrimitiveValue* weight_value = CSSNumericLiteralValue::Create( - BoldWeightValue(), CSSPrimitiveValue::UnitType::kNumber); + kBoldWeightValue, CSSPrimitiveValue::UnitType::kNumber); CSSIdentifierValue* style_value = CSSIdentifierValue::Create(CSSValueID::kItalic); @@ -135,7 +135,7 @@ CSSIdentifierValue* stretch_value_condensed = CSSIdentifierValue::Create(CSSValueID::kCondensed); CSSPrimitiveValue* weight_value = CSSNumericLiteralValue::Create( - NormalWeightValue(), CSSPrimitiveValue::UnitType::kNumber); + kNormalWeightValue, CSSPrimitiveValue::UnitType::kNumber); CSSIdentifierValue* style_value = CSSIdentifierValue::Create(CSSValueID::kNormal); AppendTestFaceForCapabilities(*stretch_value_expanded, *style_value, @@ -145,7 +145,7 @@ ASSERT_EQ(cache_->GetNumSegmentedFacesForTesting(), 2ul); const FontDescription& description_condensed = FontDescriptionForRequest( - CondensedWidthValue(), NormalSlopeValue(), NormalWeightValue()); + kCondensedWidthValue, kNormalSlopeValue, kNormalWeightValue); CSSSegmentedFontFace* result = cache_->Get(description_condensed, kFontNameForTesting); ASSERT_TRUE(result); @@ -153,11 +153,11 @@ FontSelectionCapabilities result_capabilities = result->GetFontSelectionCapabilities(); ASSERT_EQ(result_capabilities.width, - FontSelectionRange({CondensedWidthValue(), CondensedWidthValue()})); + FontSelectionRange({kCondensedWidthValue, kCondensedWidthValue})); ASSERT_EQ(result_capabilities.weight, - FontSelectionRange({NormalWeightValue(), NormalWeightValue()})); + FontSelectionRange({kNormalWeightValue, kNormalWeightValue})); ASSERT_EQ(result_capabilities.slope, - FontSelectionRange({NormalSlopeValue(), NormalSlopeValue()})); + FontSelectionRange({kNormalSlopeValue, kNormalSlopeValue})); } TEST_F(FontFaceCacheTest, SimpleWeightMatch) { @@ -176,19 +176,19 @@ ASSERT_EQ(cache_->GetNumSegmentedFacesForTesting(), 2ul); const FontDescription& description_bold = FontDescriptionForRequest( - NormalWidthValue(), NormalSlopeValue(), BoldWeightValue()); + kNormalWidthValue, kNormalSlopeValue, kBoldWeightValue); CSSSegmentedFontFace* result = cache_->Get(description_bold, kFontNameForTesting); ASSERT_TRUE(result); FontSelectionCapabilities result_capabilities = result->GetFontSelectionCapabilities(); ASSERT_EQ(result_capabilities.width, - FontSelectionRange({NormalWidthValue(), NormalWidthValue()})); + FontSelectionRange({kNormalWidthValue, kNormalWidthValue})); ASSERT_EQ( result_capabilities.weight, FontSelectionRange({FontSelectionValue(900), FontSelectionValue(900)})); ASSERT_EQ(result_capabilities.slope, - FontSelectionRange({NormalSlopeValue(), NormalSlopeValue()})); + FontSelectionRange({kNormalSlopeValue, kNormalSlopeValue})); } // For each capability, we can either not have it at all, have two of them, or @@ -240,10 +240,10 @@ CSSNumericLiteralValue::Create(900, CSSPrimitiveValue::UnitType::kNumber)}; - Vector<FontSelectionValue> width_choices = {CondensedWidthValue(), - ExpandedWidthValue()}; - Vector<FontSelectionValue> slope_choices = {NormalSlopeValue(), - ItalicSlopeValue()}; + Vector<FontSelectionValue> width_choices = {kCondensedWidthValue, + kExpandedWidthValue}; + Vector<FontSelectionValue> slope_choices = {kNormalSlopeValue, + kItalicSlopeValue}; Vector<FontSelectionValue> weight_choices = {FontSelectionValue(100), FontSelectionValue(900)}; @@ -319,19 +319,19 @@ ASSERT_EQ(cache_->GetNumSegmentedFacesForTesting(), 2ul); const FontDescription& description_bold = FontDescriptionForRequest( - NormalWidthValue(), NormalSlopeValue(), BoldWeightValue()); + kNormalWidthValue, kNormalSlopeValue, kBoldWeightValue); CSSSegmentedFontFace* result = cache_->Get(description_bold, kFontNameForTesting); ASSERT_TRUE(result); FontSelectionCapabilities result_capabilities = result->GetFontSelectionCapabilities(); ASSERT_EQ(result_capabilities.width, - FontSelectionRange({NormalWidthValue(), NormalWidthValue()})); + FontSelectionRange({kNormalWidthValue, kNormalWidthValue})); ASSERT_EQ( result_capabilities.weight, FontSelectionRange({FontSelectionValue(700), FontSelectionValue(800)})); ASSERT_EQ(result_capabilities.slope, - FontSelectionRange({NormalSlopeValue(), NormalSlopeValue()})); + FontSelectionRange({kNormalSlopeValue, kNormalSlopeValue})); } TEST_F(FontFaceCacheTest, WidthRangeMatchingBetween400500) { @@ -371,7 +371,7 @@ FontSelectionValue test_weight(450); const FontDescription& description_expanded = FontDescriptionForRequest( - NormalWidthValue(), NormalSlopeValue(), test_weight); + kNormalWidthValue, kNormalSlopeValue, test_weight); CSSSegmentedFontFace* result = cache_->Get(description_expanded, kFontNameForTesting); ASSERT_TRUE(result); @@ -428,7 +428,7 @@ ASSERT_EQ(cache_->GetNumSegmentedFacesForTesting(), 2ul); const FontDescription& description_expanded = FontDescriptionForRequest( - FontSelectionValue(105), NormalSlopeValue(), NormalWeightValue()); + FontSelectionValue(105), kNormalSlopeValue, kNormalWeightValue); CSSSegmentedFontFace* result = cache_->Get(description_expanded, kFontNameForTesting); ASSERT_TRUE(result); @@ -438,9 +438,9 @@ FontSelectionRange({FontSelectionValue(kStretchFrom), FontSelectionValue(kStretchTo)})); ASSERT_EQ(result_capabilities.weight, - FontSelectionRange({NormalWeightValue(), NormalWeightValue()})); + FontSelectionRange({kNormalWeightValue, kNormalWeightValue})); ASSERT_EQ(result_capabilities.slope, - FontSelectionRange({NormalSlopeValue(), NormalSlopeValue()})); + FontSelectionRange({kNormalSlopeValue, kNormalSlopeValue})); } TEST_F(FontFaceCacheTest, ObliqueRangeMatching) { @@ -481,16 +481,16 @@ ASSERT_EQ(cache_->GetNumSegmentedFacesForTesting(), 2ul); const FontDescription& description_italic = FontDescriptionForRequest( - NormalWidthValue(), ItalicSlopeValue(), NormalWeightValue()); + kNormalWidthValue, kItalicSlopeValue, kNormalWeightValue); CSSSegmentedFontFace* result = cache_->Get(description_italic, kFontNameForTesting); ASSERT_TRUE(result); FontSelectionCapabilities result_capabilities = result->GetFontSelectionCapabilities(); ASSERT_EQ(result_capabilities.width, - FontSelectionRange({NormalWidthValue(), NormalWidthValue()})); + FontSelectionRange({kNormalWidthValue, kNormalWidthValue})); ASSERT_EQ(result_capabilities.weight, - FontSelectionRange({NormalWeightValue(), NormalWeightValue()})); + FontSelectionRange({kNormalWeightValue, kNormalWeightValue})); ASSERT_EQ( result_capabilities.slope, FontSelectionRange({FontSelectionValue(30), FontSelectionValue(35)}));
diff --git a/third_party/blink/renderer/core/css/local_font_face_source.cc b/third_party/blink/renderer/core/css/local_font_face_source.cc index 94be7733..ca69a4f 100644 --- a/third_party/blink/renderer/core/css/local_font_face_source.cc +++ b/third_party/blink/renderer/core/css/local_font_face_source.cc
@@ -105,9 +105,9 @@ // pass font_description to avoid breaking Google Fonts. FontDescription unstyled_description(font_description); #if !BUILDFLAG(IS_ANDROID) - unstyled_description.SetStretch(NormalWidthValue()); - unstyled_description.SetStyle(NormalSlopeValue()); - unstyled_description.SetWeight(NormalWeightValue()); + unstyled_description.SetStretch(kNormalWidthValue); + unstyled_description.SetStyle(kNormalSlopeValue); + unstyled_description.SetWeight(kNormalWeightValue); #endif // TODO(https://crbug.com/1302264): Enable passing down of font-palette // information here (font_description.GetFontPalette()).
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc index 7b5d4a3..e625883c 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -1037,11 +1037,11 @@ CSSValue* ComputedStyleUtils::ValueForFontStyle(const ComputedStyle& style) { FontSelectionValue angle = style.GetFontDescription().Style(); - if (angle == NormalSlopeValue()) { + if (angle == kNormalSlopeValue) { return CSSIdentifierValue::Create(CSSValueID::kNormal); } - if (angle == ItalicSlopeValue()) { + if (angle == kItalicSlopeValue) { return CSSIdentifierValue::Create(CSSValueID::kItalic); } @@ -1295,34 +1295,34 @@ CSSIdentifierValue* ValueForFontStretchAsKeyword(const ComputedStyle& style) { FontSelectionValue stretch_value = style.GetFontDescription().Stretch(); CSSValueID value_id = CSSValueID::kInvalid; - if (stretch_value == UltraCondensedWidthValue()) { + if (stretch_value == kUltraCondensedWidthValue) { value_id = CSSValueID::kUltraCondensed; } - if (stretch_value == UltraCondensedWidthValue()) { + if (stretch_value == kUltraCondensedWidthValue) { value_id = CSSValueID::kUltraCondensed; } - if (stretch_value == ExtraCondensedWidthValue()) { + if (stretch_value == kExtraCondensedWidthValue) { value_id = CSSValueID::kExtraCondensed; } - if (stretch_value == CondensedWidthValue()) { + if (stretch_value == kCondensedWidthValue) { value_id = CSSValueID::kCondensed; } - if (stretch_value == SemiCondensedWidthValue()) { + if (stretch_value == kSemiCondensedWidthValue) { value_id = CSSValueID::kSemiCondensed; } - if (stretch_value == NormalWidthValue()) { + if (stretch_value == kNormalWidthValue) { value_id = CSSValueID::kNormal; } - if (stretch_value == SemiExpandedWidthValue()) { + if (stretch_value == kSemiExpandedWidthValue) { value_id = CSSValueID::kSemiExpanded; } - if (stretch_value == ExpandedWidthValue()) { + if (stretch_value == kExpandedWidthValue) { value_id = CSSValueID::kExpanded; } - if (stretch_value == ExtraExpandedWidthValue()) { + if (stretch_value == kExtraExpandedWidthValue) { value_id = CSSValueID::kExtraExpanded; } - if (stretch_value == UltraExpandedWidthValue()) { + if (stretch_value == kUltraExpandedWidthValue) { value_id = CSSValueID::kUltraExpanded; } @@ -1502,7 +1502,7 @@ { CSSNumericLiteralValue* font_weight = ValueForFontWeight(style); - if (font_weight->DoubleValue() != NormalWeightValue()) { + if (font_weight->DoubleValue() != kNormalWeightValue) { list->Append(*font_weight); } }
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc index c7461ab..9ecaaa4 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -5072,7 +5072,7 @@ ConsumeIdent<CSSValueID::kOblique>(range); CSSPrimitiveValue* start_angle = ConsumeAngle( - range, context, absl::nullopt, MinObliqueValue(), MaxObliqueValue()); + range, context, absl::nullopt, kMinObliqueValue, kMaxObliqueValue); if (!start_angle) { return oblique_identifier; } @@ -5088,7 +5088,7 @@ } CSSPrimitiveValue* end_angle = ConsumeAngle( - range, context, absl::nullopt, MinObliqueValue(), MaxObliqueValue()); + range, context, absl::nullopt, kMinObliqueValue, kMaxObliqueValue); if (!end_angle || !IsAngleWithinLimits(end_angle)) { return nullptr; }
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder.h b/third_party/blink/renderer/core/css/resolver/font_builder.h index 8bce0915..e07af0a 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder.h +++ b/third_party/blink/renderer/core/css/resolver/font_builder.h
@@ -134,9 +134,15 @@ static OpticalSizing InitialFontOpticalSizing() { return kAutoOpticalSizing; } static FontSmoothingMode InitialFontSmoothing() { return kAutoSmoothing; } - static FontSelectionValue InitialStretch() { return NormalWidthValue(); } - static FontSelectionValue InitialStyle() { return NormalSlopeValue(); } - static FontSelectionValue InitialWeight() { return NormalWeightValue(); } + static constexpr FontSelectionValue InitialStretch() { + return kNormalWidthValue; + } + static constexpr FontSelectionValue InitialStyle() { + return kNormalSlopeValue; + } + static constexpr FontSelectionValue InitialWeight() { + return kNormalWeightValue; + } static FontDescription::FontSynthesisWeight InitialFontSynthesisWeight() { return FontDescription::kAutoFontSynthesisWeight; }
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder_test.cc b/third_party/blink/renderer/core/css/resolver/font_builder_test.cc index 97df08f9..e002e91 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder_test.cc +++ b/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
@@ -105,14 +105,14 @@ d.SetWeight(FontSelectionValue(900)); } static void FontWeightValue(FontBuilder& b) { - b.SetWeight(NormalWeightValue()); + b.SetWeight(kNormalWeightValue); } static void FontStretchBase(FontDescription& d) { - d.SetStretch(UltraExpandedWidthValue()); + d.SetStretch(kUltraExpandedWidthValue); } static void FontStretchValue(FontBuilder& b) { - b.SetStretch(ExtraCondensedWidthValue()); + b.SetStretch(kExtraCondensedWidthValue); } static void FontFamilyBase(FontDescription& d) { @@ -131,10 +131,10 @@ } static void FontStyleBase(FontDescription& d) { - d.SetStyle(ItalicSlopeValue()); + d.SetStyle(kItalicSlopeValue); } static void FontStyleValue(FontBuilder& b) { - b.SetStyle(NormalSlopeValue()); + b.SetStyle(kNormalSlopeValue); } static void FontVariantCapsBase(FontDescription& d) {
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 966cdaa..1633bf0 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -804,34 +804,34 @@ if (const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { switch (identifier_value->GetValueID()) { case CSSValueID::kUltraCondensed: - return UltraCondensedWidthValue(); + return kUltraCondensedWidthValue; case CSSValueID::kExtraCondensed: - return ExtraCondensedWidthValue(); + return kExtraCondensedWidthValue; case CSSValueID::kCondensed: - return CondensedWidthValue(); + return kCondensedWidthValue; case CSSValueID::kSemiCondensed: - return SemiCondensedWidthValue(); + return kSemiCondensedWidthValue; case CSSValueID::kNormal: - return NormalWidthValue(); + return kNormalWidthValue; case CSSValueID::kSemiExpanded: - return SemiExpandedWidthValue(); + return kSemiExpandedWidthValue; case CSSValueID::kExpanded: - return ExpandedWidthValue(); + return kExpandedWidthValue; case CSSValueID::kExtraExpanded: - return ExtraExpandedWidthValue(); + return kExtraExpandedWidthValue; case CSSValueID::kUltraExpanded: - return UltraExpandedWidthValue(); + return kUltraExpandedWidthValue; default: break; } } if (value.IsPendingSystemFontValue()) { - return NormalWidthValue(); + return kNormalWidthValue; } NOTREACHED(); - return NormalWidthValue(); + return kNormalWidthValue; } FontSelectionValue StyleBuilderConverter::ConvertFontStretch( @@ -848,19 +848,19 @@ switch (identifier_value->GetValueID()) { case CSSValueID::kItalic: case CSSValueID::kOblique: - return ItalicSlopeValue(); + return kItalicSlopeValue; case CSSValueID::kNormal: - return NormalSlopeValue(); + return kNormalSlopeValue; default: NOTREACHED(); - return NormalSlopeValue(); + return kNormalSlopeValue; } } else if (const auto* system_font = DynamicTo<cssvalue::CSSPendingSystemFontValue>(value)) { - if (system_font->ResolveFontStyle() == ItalicSlopeValue()) { - return ItalicSlopeValue(); + if (system_font->ResolveFontStyle() == kItalicSlopeValue) { + return kItalicSlopeValue; } - return NormalSlopeValue(); + return kNormalSlopeValue; } else if (const auto* style_range_value = DynamicTo<cssvalue::CSSFontStyleRangeValue>(value)) { const CSSValueList* values = style_range_value->GetObliqueValues(); @@ -871,17 +871,17 @@ } else { identifier_value = style_range_value->GetFontStyleValue(); if (identifier_value->GetValueID() == CSSValueID::kNormal) { - return NormalSlopeValue(); + return kNormalSlopeValue; } if (identifier_value->GetValueID() == CSSValueID::kItalic || identifier_value->GetValueID() == CSSValueID::kOblique) { - return ItalicSlopeValue(); + return kItalicSlopeValue; } } } NOTREACHED(); - return NormalSlopeValue(); + return kNormalSlopeValue; } FontSelectionValue StyleBuilderConverter::ConvertFontStyle( @@ -907,20 +907,20 @@ if (const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { switch (identifier_value->GetValueID()) { case CSSValueID::kNormal: - return NormalWeightValue(); + return kNormalWeightValue; case CSSValueID::kBold: - return BoldWeightValue(); + return kBoldWeightValue; case CSSValueID::kBolder: return FontDescription::BolderWeight(parent_weight); case CSSValueID::kLighter: return FontDescription::LighterWeight(parent_weight); default: NOTREACHED(); - return NormalWeightValue(); + return kNormalWeightValue; } } NOTREACHED(); - return NormalWeightValue(); + return kNormalWeightValue; } FontSelectionValue StyleBuilderConverter::ConvertFontWeight(
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 54b2814..d1bb8b7b 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -3069,11 +3069,88 @@ return initial_data_; } +void StyleEngine::RecalcHighlightStylesForContainer(Element& container) { + const ComputedStyle& style = container.ComputedStyleRef(); + if (!style.HasAnyHighlightPseudoElementStyles() || + !style.HasNonUaHighlightPseudoStyles() || + !style.HighlightData().DependsOnSizeContainerQueries()) { + return; + } + + // We are recalculating styles for a size container whose highlight pseudo + // styles depend on size container queries. Make sure we update those styles + // based on the changed container size. + StyleRecalcContext recalc_context; + recalc_context.container = &container; + if (const ComputedStyle* new_style = container.RecalcHighlightStyles( + recalc_context, nullptr /* old_style */, style, + container.ParentComputedStyle()); + new_style != &style) { + container.SetComputedStyle(new_style); + container.GetLayoutObject()->SetStyle(new_style, + LayoutObject::ApplyStyleChanges::kNo); + } +} + +#if DCHECK_IS_ON() +namespace { +bool ContainerStyleChangesAllowed(Element& container, + const ComputedStyle* old_element_style, + const ComputedStyle* old_layout_style) { + // Generally, the size container element style is not allowed to change during + // layout, but for highlight pseudo elements depending on queries against + // their originating element, we need to update the style during layout since + // the highlight styles hangs off the originating element's ComputedStyle. + const ComputedStyle* new_element_style = container.GetComputedStyle(); + const ComputedStyle* new_layout_style = + container.GetLayoutObject() ? container.GetLayoutObject()->Style() + : nullptr; + + if (!new_element_style || !old_element_style) { + // The container should always have a ComputedStyle. + return false; + } + if (new_element_style != old_element_style) { + Vector<ComputedStyleBase::DebugDiff> diff = + old_element_style->DebugDiffFields(*new_element_style); + // Allow highlight styles to change, but only highlight styles. + if (diff.size() > 1 || + (diff.size() == 1 && + diff[0].field != ComputedStyleBase::DebugField::highlight_data_)) { + return false; + } + } + if (new_layout_style == old_layout_style) { + return true; + } + if (!new_layout_style || !old_element_style) { + // Container may not have a LayoutObject when called from + // UpdateStyleForNonEligibleContainer(), but then make sure the style is + // null for both cases. + return new_layout_style == old_element_style; + } + Vector<ComputedStyleBase::DebugDiff> diff = + old_layout_style->DebugDiffFields(*new_layout_style); + // Allow highlight styles to change, but only highlight styles. + return diff.size() == 0 || + (diff.size() == 1 && + diff[0].field == ComputedStyleBase::DebugField::highlight_data_); +} +} // namespace +#endif // DCHECK_IS_ON() + void StyleEngine::RecalcStyleForContainer(Element& container, StyleRecalcChange change) { // The container node must not need recalc at this point. DCHECK(!StyleRecalcChange().ShouldRecalcStyleFor(container)); +#if DCHECK_IS_ON() + const ComputedStyle* old_element_style = container.GetComputedStyle(); + const ComputedStyle* old_layout_style = + container.GetLayoutObject() ? container.GetLayoutObject()->Style() + : nullptr; +#endif // DCHECK_IS_ON() + // If the container itself depends on an outer container, then its // DependsOnSizeContainerQueries flag will be set, and we would recalc its // style (due to ForceRecalcContainer/ForceRecalcDescendantSizeContainers). @@ -3084,10 +3161,17 @@ container.SetChildNeedsStyleRecalc(); style_recalc_root_.Update(nullptr, &container); + RecalcHighlightStylesForContainer(container); + // TODO(crbug.com/1145970): Consider use a caching mechanism for FromAncestors // as we typically will call it for all containers on the first style/layout // pass. RecalcStyle(change, StyleRecalcContext::FromAncestors(container)); + +#if DCHECK_IS_ON() + DCHECK(ContainerStyleChangesAllowed(container, old_element_style, + old_layout_style)); +#endif // DCHECK_IS_ON() } void StyleEngine::UpdateStyleForNonEligibleContainer(Element& container) {
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index 98e7b64e3..4caddf6 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -816,6 +816,7 @@ void RecalcStyle(StyleRecalcChange, const StyleRecalcContext&); void RecalcStyleForContainer(Element& container, StyleRecalcChange change); + void RecalcHighlightStylesForContainer(Element& container); void RecalcTransitionPseudoStyle();
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index d548acb1..8ce17714 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -357,9 +357,9 @@ FontSelectionCapabilities capabilities = font_face->GetFontSelectionCapabilities(); ASSERT_EQ(capabilities.weight, - FontSelectionRange({BoldWeightValue(), BoldWeightValue()})); + FontSelectionRange({kBoldWeightValue, kBoldWeightValue})); ASSERT_EQ(capabilities.slope, - FontSelectionRange({NormalSlopeValue(), NormalSlopeValue()})); + FontSelectionRange({kNormalSlopeValue, kNormalSlopeValue})); auto* font_face_parsed_sheet = MakeGarbageCollected<StyleSheetContents>( MakeGarbageCollected<CSSParserContext>(GetDocument())); @@ -386,9 +386,9 @@ EXPECT_TRUE(font_face); capabilities = font_face->GetFontSelectionCapabilities(); ASSERT_EQ(capabilities.weight, - FontSelectionRange({BoldWeightValue(), BoldWeightValue()})); + FontSelectionRange({kBoldWeightValue, kBoldWeightValue})); ASSERT_EQ(capabilities.slope, - FontSelectionRange({ItalicSlopeValue(), ItalicSlopeValue()})); + FontSelectionRange({kItalicSlopeValue, kItalicSlopeValue})); auto* style_element = MakeGarbageCollected<HTMLStyleElement>(GetDocument()); style_element->setInnerHTML( @@ -412,9 +412,9 @@ EXPECT_TRUE(font_face); capabilities = font_face->GetFontSelectionCapabilities(); ASSERT_EQ(capabilities.weight, - FontSelectionRange({BoldWeightValue(), BoldWeightValue()})); + FontSelectionRange({kBoldWeightValue, kBoldWeightValue})); ASSERT_EQ(capabilities.slope, - FontSelectionRange({ItalicSlopeValue(), ItalicSlopeValue()})); + FontSelectionRange({kItalicSlopeValue, kItalicSlopeValue})); GetStyleEngine().RemoveInjectedSheet(font_face_key, WebCssOrigin::kUser); UpdateAllLifecyclePhases(); @@ -431,9 +431,9 @@ EXPECT_TRUE(font_face); capabilities = font_face->GetFontSelectionCapabilities(); ASSERT_EQ(capabilities.weight, - FontSelectionRange({NormalWeightValue(), NormalWeightValue()})); + FontSelectionRange({kNormalWeightValue, kNormalWeightValue})); ASSERT_EQ(capabilities.slope, - FontSelectionRange({ItalicSlopeValue(), ItalicSlopeValue()})); + FontSelectionRange({kItalicSlopeValue, kItalicSlopeValue})); // @keyframes rules
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc index b3f0144f7..b385d13 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.cc +++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -2033,25 +2033,38 @@ const CSSValue* template_area_values = property_set_.GetPropertyCSSValue(*shorthand.properties()[2]); - // 1- 'none' case. - if (IsA<CSSIdentifierValue>(template_row_values) && + const bool has_initial_template_rows = + IsA<CSSIdentifierValue>(template_row_values) && To<CSSIdentifierValue>(template_row_values)->GetValueID() == - CSSValueID::kNone && + CSSValueID::kNone; + const bool has_initial_template_columns = IsA<CSSIdentifierValue>(template_column_values) && To<CSSIdentifierValue>(template_column_values)->GetValueID() == - CSSValueID::kNone) { + CSSValueID::kNone; + const bool has_initial_template_areas = + !template_area_values || + (IsA<CSSIdentifierValue>(template_area_values) && + To<CSSIdentifierValue>(template_area_values)->GetValueID() == + CSSValueID::kNone); + + // 1- 'none' case. + if (has_initial_template_areas && has_initial_template_rows && + has_initial_template_columns) { return "none"; } + // It is invalid to specify `grid-template-areas` without + // `grid-template-rows`. + if (!has_initial_template_areas && has_initial_template_rows) { + return ""; + } + const CSSValueList* template_row_value_list = DynamicTo<CSSValueList>(template_row_values); StringBuilder result; // 2- <grid-template-rows> / <grid-template-columns> - if (!template_row_value_list || - (IsA<CSSIdentifierValue>(template_area_values) && - To<CSSIdentifierValue>(template_area_values)->GetValueID() == - CSSValueID::kNone)) { + if (!template_row_value_list || has_initial_template_areas) { result.Append(template_row_values->CssText()); result.Append(" / "); result.Append(template_column_values->CssText()); @@ -2114,10 +2127,8 @@ } } } - if (const CSSIdentifierValue* column_identifier_value = - DynamicTo<CSSIdentifierValue>(template_column_values); - !column_identifier_value || - (column_identifier_value->GetValueID() != CSSValueID::kNone)) { + + if (!has_initial_template_columns) { result.Append(" / "); result.Append(template_column_values->CssText()); }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 844e967f..99e8c4f 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3586,99 +3586,16 @@ if (!ShouldStoreComputedStyle(*new_style)) { new_style = nullptr; NotifyAXOfAttachedSubtree(); - } else if (!new_style->IsContentVisibilityVisible()) { - NotifyAXOfAttachedSubtree(); - } - } - - if (HighlightRecalc highlight_recalc = - CalculateHighlightRecalc(old_style, new_style); - highlight_recalc != HighlightRecalc::kNone) { - DCHECK(new_style); - - ComputedStyleBuilder builder(*new_style); - - if (highlight_recalc == HighlightRecalc::kReuse) { - DCHECK(old_style); - builder.SetHighlightData(old_style->HighlightData()); } else { - DCHECK_EQ(highlight_recalc, HighlightRecalc::kFull); - - const StyleHighlightData* parent_highlights = - parent_style ? &parent_style->HighlightData() : nullptr; - + if (!new_style->IsContentVisibilityVisible()) { + NotifyAXOfAttachedSubtree(); + } if (new_style->IsContainerForSizeContainerQueries()) { new_style_recalc_context.container = this; } - - if (UsesHighlightPseudoInheritance(kPseudoIdSelection) && - new_style->HasPseudoElementStyle(kPseudoIdSelection)) { - StyleHighlightData& highlights = builder.AccessHighlightData(); - const ComputedStyle* highlight_parent = - parent_highlights ? parent_highlights->Selection() : nullptr; - StyleRequest style_request{kPseudoIdSelection, highlight_parent}; - style_request.originating_element_style = new_style; - highlights.SetSelection( - StyleForPseudoElement(new_style_recalc_context, style_request)); - } - - if (UsesHighlightPseudoInheritance(kPseudoIdTargetText) && - new_style->HasPseudoElementStyle(kPseudoIdTargetText)) { - StyleHighlightData& highlights = builder.AccessHighlightData(); - const ComputedStyle* highlight_parent = - parent_highlights ? parent_highlights->TargetText() : nullptr; - StyleRequest style_request{kPseudoIdTargetText, highlight_parent}; - style_request.originating_element_style = new_style; - highlights.SetTargetText( - StyleForPseudoElement(new_style_recalc_context, style_request)); - } - - if (UsesHighlightPseudoInheritance(kPseudoIdSpellingError) && - new_style->HasPseudoElementStyle(kPseudoIdSpellingError)) { - StyleHighlightData& highlights = builder.AccessHighlightData(); - const ComputedStyle* highlight_parent = - parent_highlights ? parent_highlights->SpellingError() : nullptr; - StyleRequest style_request{kPseudoIdSpellingError, highlight_parent}; - style_request.originating_element_style = new_style; - highlights.SetSpellingError( - StyleForPseudoElement(new_style_recalc_context, style_request)); - } - - if (UsesHighlightPseudoInheritance(kPseudoIdGrammarError) && - new_style->HasPseudoElementStyle(kPseudoIdGrammarError)) { - StyleHighlightData& highlights = builder.AccessHighlightData(); - const ComputedStyle* highlight_parent = - parent_highlights ? parent_highlights->GrammarError() : nullptr; - StyleRequest style_request{kPseudoIdGrammarError, highlight_parent}; - style_request.originating_element_style = new_style; - highlights.SetGrammarError( - StyleForPseudoElement(new_style_recalc_context, style_request)); - } - - if (UsesHighlightPseudoInheritance(kPseudoIdHighlight) && - new_style->HasPseudoElementStyle(kPseudoIdHighlight)) { - const HashSet<AtomicString>* custom_highlight_names = - new_style->CustomHighlightNames(); - if (custom_highlight_names) { - for (const AtomicString& custom_highlight_name : - *custom_highlight_names) { - StyleHighlightData& highlights = builder.AccessHighlightData(); - const ComputedStyle* highlight_parent = - parent_highlights - ? parent_highlights->CustomHighlight(custom_highlight_name) - : nullptr; - StyleRequest style_request{kPseudoIdHighlight, highlight_parent, - custom_highlight_name}; - style_request.originating_element_style = new_style; - highlights.SetCustomHighlight( - custom_highlight_name, - StyleForPseudoElement(new_style_recalc_context, style_request)); - } - } - } + new_style = RecalcHighlightStyles(new_style_recalc_context, old_style, + *new_style, parent_style); } - - new_style = builder.TakeStyle(); } ComputedStyle::Difference diff = @@ -4267,8 +4184,9 @@ Element::HighlightRecalc Element::CalculateHighlightRecalc( const ComputedStyle* old_style, - const ComputedStyle* new_style) { - if (!new_style || !new_style->HasAnyHighlightPseudoElementStyles()) { + const ComputedStyle& new_style, + const ComputedStyle* parent_style) { + if (!new_style.HasAnyHighlightPseudoElementStyles()) { return HighlightRecalc::kNone; } // If we are a root element (our parent is a Document or ShadowRoot), we can @@ -4278,14 +4196,14 @@ // In that case, we only need to calculate highlight styles once, because our // UA styles only use type selectors and we never change them dynamically. if (parentNode() == ContainingTreeScope().RootNode()) { - if (new_style->HasNonUaHighlightPseudoStyles()) { + if (new_style.HasNonUaHighlightPseudoStyles()) { return HighlightRecalc::kFull; } if (old_style) { if (old_style->HasNonUaHighlightPseudoStyles()) { return HighlightRecalc::kFull; } - if (old_style->EffectiveZoom() != new_style->EffectiveZoom()) { + if (old_style->EffectiveZoom() != new_style.EffectiveZoom()) { return HighlightRecalc::kFull; } // Neither the new style nor the old style has any non-UA highlight rules, @@ -4298,17 +4216,109 @@ // If the parent matched any non-universal highlight rules, then we need // to recalc, in case there are universal highlight rules. bool parent_non_universal = - ParentComputedStyle() != nullptr && - ParentComputedStyle()->HasNonUniversalHighlightPseudoStyles(); + parent_style != nullptr && + parent_style->HasNonUniversalHighlightPseudoStyles(); // If we matched any non-universal highlight rules, then we need to recalc // and our children also need to recalc (see above). - bool self_non_universal = new_style->HasNonUniversalHighlightPseudoStyles(); + bool self_non_universal = new_style.HasNonUniversalHighlightPseudoStyles(); return (parent_non_universal || self_non_universal) ? HighlightRecalc::kFull : HighlightRecalc::kNone; } +const ComputedStyle* Element::RecalcHighlightStyles( + const StyleRecalcContext& style_recalc_context, + const ComputedStyle* old_style, + const ComputedStyle& new_style, + const ComputedStyle* parent_style) { + HighlightRecalc highlight_recalc = + CalculateHighlightRecalc(old_style, new_style, parent_style); + if (highlight_recalc == HighlightRecalc::kNone) { + return &new_style; + } + + ComputedStyleBuilder builder(new_style); + + if (highlight_recalc == HighlightRecalc::kReuse) { + DCHECK(old_style); + builder.SetHighlightData(old_style->HighlightData()); + } else { + DCHECK_EQ(highlight_recalc, HighlightRecalc::kFull); + + const StyleHighlightData* parent_highlights = + parent_style ? &parent_style->HighlightData() : nullptr; + + if (UsesHighlightPseudoInheritance(kPseudoIdSelection) && + new_style.HasPseudoElementStyle(kPseudoIdSelection)) { + StyleHighlightData& highlights = builder.AccessHighlightData(); + const ComputedStyle* highlight_parent = + parent_highlights ? parent_highlights->Selection() : nullptr; + StyleRequest style_request{kPseudoIdSelection, highlight_parent}; + style_request.originating_element_style = &new_style; + highlights.SetSelection( + StyleForPseudoElement(style_recalc_context, style_request)); + } + + if (UsesHighlightPseudoInheritance(kPseudoIdTargetText) && + new_style.HasPseudoElementStyle(kPseudoIdTargetText)) { + StyleHighlightData& highlights = builder.AccessHighlightData(); + const ComputedStyle* highlight_parent = + parent_highlights ? parent_highlights->TargetText() : nullptr; + StyleRequest style_request{kPseudoIdTargetText, highlight_parent}; + style_request.originating_element_style = &new_style; + highlights.SetTargetText( + StyleForPseudoElement(style_recalc_context, style_request)); + } + + if (UsesHighlightPseudoInheritance(kPseudoIdSpellingError) && + new_style.HasPseudoElementStyle(kPseudoIdSpellingError)) { + StyleHighlightData& highlights = builder.AccessHighlightData(); + const ComputedStyle* highlight_parent = + parent_highlights ? parent_highlights->SpellingError() : nullptr; + StyleRequest style_request{kPseudoIdSpellingError, highlight_parent}; + style_request.originating_element_style = &new_style; + highlights.SetSpellingError( + StyleForPseudoElement(style_recalc_context, style_request)); + } + + if (UsesHighlightPseudoInheritance(kPseudoIdGrammarError) && + new_style.HasPseudoElementStyle(kPseudoIdGrammarError)) { + StyleHighlightData& highlights = builder.AccessHighlightData(); + const ComputedStyle* highlight_parent = + parent_highlights ? parent_highlights->GrammarError() : nullptr; + StyleRequest style_request{kPseudoIdGrammarError, highlight_parent}; + style_request.originating_element_style = &new_style; + highlights.SetGrammarError( + StyleForPseudoElement(style_recalc_context, style_request)); + } + + if (UsesHighlightPseudoInheritance(kPseudoIdHighlight) && + new_style.HasPseudoElementStyle(kPseudoIdHighlight)) { + const HashSet<AtomicString>* custom_highlight_names = + new_style.CustomHighlightNames(); + if (custom_highlight_names) { + for (const AtomicString& custom_highlight_name : + *custom_highlight_names) { + StyleHighlightData& highlights = builder.AccessHighlightData(); + const ComputedStyle* highlight_parent = + parent_highlights + ? parent_highlights->CustomHighlight(custom_highlight_name) + : nullptr; + StyleRequest style_request{kPseudoIdHighlight, highlight_parent, + custom_highlight_name}; + style_request.originating_element_style = &new_style; + highlights.SetCustomHighlight( + custom_highlight_name, + StyleForPseudoElement(style_recalc_context, style_request)); + } + } + } + } + + return builder.TakeStyle(); +} + void Element::SetAnimationStyleChange(bool animation_style_change) { if (animation_style_change && GetDocument().InStyleRecalc()) { return;
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 90c6a65d..ba1deaf 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -608,6 +608,16 @@ void RecalcStyle(const StyleRecalcChange, const StyleRecalcContext&); void RecalcStyleForTraversalRootAncestor(); + + // RecalcHighlightStyles for the originating element's new_style and return + // a new new_style if highlight styles were added. Otherwise return a pointer + // to the passed in new_style. + const ComputedStyle* RecalcHighlightStyles( + const StyleRecalcContext& style_recalc_context, + const ComputedStyle* old_style, + const ComputedStyle& new_style, + const ComputedStyle* parent_style); + void RebuildLayoutTreeForTraversalRootAncestor() { RebuildFirstLetterLayoutTree(); WhitespaceAttacher whitespace_attacher; @@ -1587,7 +1597,8 @@ // like *::selection. To improve runtime and keep copy-on-write inheritance, // avoid recalc if neither parent nor child matched any non-universal rules. HighlightRecalc CalculateHighlightRecalc(const ComputedStyle* old_style, - const ComputedStyle* new_style); + const ComputedStyle& new_style, + const ComputedStyle* parent_style); Member<ElementData> element_data_; };
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc index 0d81cdc..6f9cf955 100644 --- a/third_party/blink/renderer/core/editing/editing_style.cc +++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -1832,7 +1832,7 @@ GetPrimitiveValueNumber(style, CSSPropertyID::kFontWeight, weight); if (GetIdentifierValue(style, CSSPropertyID::kFontWeight) == CSSValueID::kBold || - (is_number && weight >= BoldThreshold())) { + (is_number && weight >= kBoldThreshold)) { style->RemoveProperty(CSSPropertyID::kFontWeight); apply_bold_ = true; } @@ -1948,7 +1948,7 @@ } CHECK(To<CSSPrimitiveValue>(font_weight)->IsNumber()); - return To<CSSPrimitiveValue>(font_weight)->GetFloatValue() >= BoldThreshold(); + return To<CSSPrimitiveValue>(font_weight)->GetFloatValue() >= kBoldThreshold; } static bool FontWeightNeedsResolving(const CSSValue* font_weight) {
diff --git a/third_party/blink/renderer/core/editing/ime/text_format.idl b/third_party/blink/renderer/core/editing/ime/text_format.idl index 4216aae..17f61a9 100644 --- a/third_party/blink/renderer/core/editing/ime/text_format.idl +++ b/third_party/blink/renderer/core/editing/ime/text_format.idl
@@ -7,6 +7,9 @@ // Spec draft: // https://w3c.github.io/edit-context/#textformatupdateevent +enum UnderlineStyle { "none", "solid", "double", "dotted", "dashed", "wavy" }; +enum UnderlineThickness { "none", "thin", "thick" }; + [ Exposed=Window, RuntimeEnabled=EditContext @@ -15,6 +18,6 @@ readonly attribute unsigned long rangeStart; readonly attribute unsigned long rangeEnd; - readonly attribute DOMString underlineStyle; - readonly attribute DOMString underlineThickness; + readonly attribute UnderlineStyle underlineStyle; + readonly attribute UnderlineThickness underlineThickness; };
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc index bc9117e7..423e530 100644 --- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc +++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
@@ -110,14 +110,15 @@ instance_ = nullptr; } - static void EnsureMainThreadDebuggerCreated() { + static void EnsureMainThreadDebuggerCreated(v8::Isolate* isolate) { if (instance_) return; std::unique_ptr<ClientMessageLoopAdapter> instance( new ClientMessageLoopAdapter( Platform::Current()->CreateNestedMessageLoopRunner())); instance_ = instance.get(); - MainThreadDebugger::Instance()->SetClientMessageLoop(std::move(instance)); + MainThreadDebugger::Instance(isolate)->SetClientMessageLoop( + std::move(instance)); } static void ContinueProgram() { @@ -287,10 +288,12 @@ if (!network_agents_.size()) Thread::Current()->AddTaskObserver(this); - ClientMessageLoopAdapter::EnsureMainThreadDebuggerCreated(); - MainThreadDebugger* main_thread_debugger = MainThreadDebugger::Instance(); - v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate(); InspectedFrames* inspected_frames = inspected_frames_.Get(); + v8::Isolate* isolate = + inspected_frames->Root()->GetPage()->GetAgentGroupScheduler().Isolate(); + ClientMessageLoopAdapter::EnsureMainThreadDebuggerCreated(isolate); + MainThreadDebugger* main_thread_debugger = + MainThreadDebugger::Instance(isolate); int context_group_id = main_thread_debugger->ContextGroupId(inspected_frames->Root()); @@ -589,14 +592,18 @@ bool was_blocked_or_low_priority) { if (network_agents_.empty()) return; - ThreadDebugger::IdleFinished(V8PerIsolateData::MainThreadIsolate()); + v8::Isolate* isolate = + inspected_frames_->Root()->GetPage()->GetAgentGroupScheduler().Isolate(); + ThreadDebugger::IdleFinished(isolate); } void WebDevToolsAgentImpl::DidProcessTask( const base::PendingTask& pending_task) { if (network_agents_.empty()) return; - ThreadDebugger::IdleStarted(V8PerIsolateData::MainThreadIsolate()); + v8::Isolate* isolate = + inspected_frames_->Root()->GetPage()->GetAgentGroupScheduler().Isolate(); + ThreadDebugger::IdleStarted(isolate); FlushProtocolNotifications(); }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 22f92d8..0f97cb0d 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -500,7 +500,7 @@ } void LocalDOMWindow::ExceptionThrown(ErrorEvent* event) { - MainThreadDebugger::Instance()->ExceptionThrown(this, event); + MainThreadDebugger::Instance(GetIsolate())->ExceptionThrown(this, event); } // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer @@ -985,7 +985,8 @@ GetAgent()->DetachContext(this); NotifyContextDestroyed(); RemoveAllEventListeners(); - MainThreadDebugger::Instance()->DidClearContextsForFrame(GetFrame()); + MainThreadDebugger::Instance(GetIsolate()) + ->DidClearContextsForFrame(GetFrame()); DisconnectFromFrame(); }
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index 600ace2a..2a25fa8 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -1289,7 +1289,8 @@ frame_, portal_token, std::move(portal), std::move(portal_client), std::move(data.message), ports, std::move(callback)); - ThreadDebugger* debugger = MainThreadDebugger::Instance(); + v8::Isolate* isolate = dom_window->GetIsolate(); + ThreadDebugger* debugger = MainThreadDebugger::Instance(isolate); if (debugger) debugger->ExternalAsyncTaskStarted(data.sender_stack_trace_id); dom_window->DispatchEvent(*event);
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index ccbf9e3..def81df 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -250,7 +250,6 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" #include "third_party/blink/renderer/platform/bindings/source_location.h" -#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" @@ -1163,10 +1162,9 @@ return MainWorldScriptContext()->Global(); } -bool WebFrame::ScriptCanAccess(WebFrame* target) { +bool WebFrame::ScriptCanAccess(v8::Isolate* isolate, WebFrame* target) { return BindingSecurity::ShouldAllowAccessTo( - CurrentDOMWindow(V8PerIsolateData::MainThreadIsolate()), - ToCoreFrame(*target)->DomWindow()); + CurrentDOMWindow(isolate), ToCoreFrame(*target)->DomWindow()); } void WebLocalFrameImpl::StartReload(WebFrameLoadType frame_load_type) {
diff --git a/third_party/blink/renderer/core/highlight/highlight_style_utils.cc b/third_party/blink/renderer/core/highlight/highlight_style_utils.cc index b1db0c92..7947511 100644 --- a/third_party/blink/renderer/core/highlight/highlight_style_utils.cc +++ b/third_party/blink/renderer/core/highlight/highlight_style_utils.cc
@@ -420,17 +420,20 @@ highlight_style.current_color = ResolveColor(document, style, pseudo_style, pseudo, GetCSSPropertyColor(), previous_layer_current_color); - highlight_style.fill_color = ResolveColor( - document, style, pseudo_style, pseudo, - GetCSSPropertyWebkitTextFillColor(), previous_layer_current_color); + highlight_style.fill_color = + ResolveColor(document, style, pseudo_style, pseudo, + GetCSSPropertyWebkitTextFillColor(), + previous_layer_text_style.fill_color); // TODO(crbug.com/1147859) ignore highlight ‘text-emphasis-color’ // https://github.com/w3c/csswg-drafts/issues/7101 - highlight_style.emphasis_mark_color = ResolveColor( - document, style, pseudo_style, pseudo, - GetCSSPropertyTextEmphasisColor(), previous_layer_current_color); - highlight_style.stroke_color = ResolveColor( - document, style, pseudo_style, pseudo, - GetCSSPropertyWebkitTextStrokeColor(), previous_layer_current_color); + highlight_style.emphasis_mark_color = + ResolveColor(document, style, pseudo_style, pseudo, + GetCSSPropertyTextEmphasisColor(), + previous_layer_text_style.emphasis_mark_color); + highlight_style.stroke_color = + ResolveColor(document, style, pseudo_style, pseudo, + GetCSSPropertyWebkitTextStrokeColor(), + previous_layer_text_style.stroke_color); } if (pseudo_style) {
diff --git a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc index 2bd93d3..b302adde 100644 --- a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc +++ b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
@@ -51,8 +51,9 @@ // TODO crbug.com/516675 Add stretch to serialization const char* FontStyleToString(FontSelectionValue slope) { - if (slope == ItalicSlopeValue()) + if (slope == kItalicSlopeValue) { return "italic"; + } return "normal"; } @@ -444,7 +445,7 @@ AddProperty("fontSize", font_description.ComputedPixelSize(), data); } // Our UA stylesheet has font-weight:normal for OPTION. - if (NormalWeightValue() != font_description.Weight()) { + if (kNormalWeightValue != font_description.Weight()) { AddProperty("fontWeight", font_description.Weight().ToString(), data); } if (base_font.Family() != font_description.Family()) {
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/third_party/blink/renderer/core/html/portal/html_portal_element.cc index acb5a683..3ad6cca 100644 --- a/third_party/blink/renderer/core/html/portal/html_portal_element.cc +++ b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -148,8 +148,7 @@ data.message = SerializedScriptValue::UndefinedValue(); data.message->UnregisterMemoryAllocatedWithCurrentScriptContext(); data.sender_origin = context->GetSecurityOrigin()->IsolatedCopy(); - if (ThreadDebugger* debugger = - ThreadDebugger::From(V8PerIsolateData::MainThreadIsolate())) { + if (ThreadDebugger* debugger = ThreadDebugger::From(context->GetIsolate())) { data.sender_stack_trace_id = debugger->StoreCurrentStackTrace("activate (implicit)"); }
diff --git a/third_party/blink/renderer/core/html/portal/portal_activate_event.cc b/third_party/blink/renderer/core/html/portal/portal_activate_event.cc index 999aaf3..99d74fc3 100644 --- a/third_party/blink/renderer/core/html/portal/portal_activate_event.cc +++ b/third_party/blink/renderer/core/html/portal/portal_activate_event.cc
@@ -15,7 +15,6 @@ #include "third_party/blink/renderer/core/html/portal/html_portal_element.h" #include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" -#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" namespace blink { @@ -37,9 +36,10 @@ } PortalActivateEvent* PortalActivateEvent::Create( + v8::Isolate* isolate, const AtomicString& type, const PortalActivateEventInit* init) { - return MakeGarbageCollected<PortalActivateEvent>(type, init); + return MakeGarbageCollected<PortalActivateEvent>(isolate, type, init); } PortalActivateEvent::PortalActivateEvent( @@ -64,12 +64,12 @@ ports_(ports), on_portal_activated_callback_(std::move(callback)) {} -PortalActivateEvent::PortalActivateEvent(const AtomicString& type, +PortalActivateEvent::PortalActivateEvent(v8::Isolate* isolate, + const AtomicString& type, const PortalActivateEventInit* init) : Event(type, init) { if (init->hasData()) { - data_from_init_.Set(V8PerIsolateData::MainThreadIsolate(), - init->data().V8Value()); + data_from_init_.Set(isolate, init->data().V8Value()); } // Remaining fields, such as |document_|, are left null.
diff --git a/third_party/blink/renderer/core/html/portal/portal_activate_event.h b/third_party/blink/renderer/core/html/portal/portal_activate_event.h index f60974b..1cd03aa 100644 --- a/third_party/blink/renderer/core/html/portal/portal_activate_event.h +++ b/third_party/blink/renderer/core/html/portal/portal_activate_event.h
@@ -49,7 +49,8 @@ OnPortalActivatedCallback callback); // Web-exposed and called directly by authors. - static PortalActivateEvent* Create(const AtomicString& type, + static PortalActivateEvent* Create(v8::Isolate* isolate, + const AtomicString& type, const PortalActivateEventInit*); PortalActivateEvent( @@ -61,7 +62,9 @@ UnpackedSerializedScriptValue* data, MessagePortArray*, OnPortalActivatedCallback callback); - PortalActivateEvent(const AtomicString& type, const PortalActivateEventInit*); + PortalActivateEvent(v8::Isolate* isolate, + const AtomicString& type, + const PortalActivateEventInit*); ~PortalActivateEvent() override;
diff --git a/third_party/blink/renderer/core/html/portal/portal_activate_event.idl b/third_party/blink/renderer/core/html/portal/portal_activate_event.idl index 86d2940..343d119 100644 --- a/third_party/blink/renderer/core/html/portal/portal_activate_event.idl +++ b/third_party/blink/renderer/core/html/portal/portal_activate_event.idl
@@ -7,7 +7,7 @@ [ Exposed=Window, RuntimeEnabled=Portals ] interface PortalActivateEvent : Event { - constructor(DOMString type, optional PortalActivateEventInit eventInitDict = {}); + [CallWith=Isolate] constructor(DOMString type, optional PortalActivateEventInit eventInitDict = {}); [CallWith=ScriptState, Measure] readonly attribute any data; [RaisesException, Measure] HTMLPortalElement adoptPredecessor(); };
diff --git a/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc b/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc index a6c2c62..bffc8326 100644 --- a/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc +++ b/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc
@@ -93,7 +93,8 @@ event = MessageEvent::CreateError(source_origin->ToString(), event_target); } - ThreadDebugger* debugger = MainThreadDebugger::Instance(); + v8::Isolate* isolate = context->GetIsolate(); + ThreadDebugger* debugger = MainThreadDebugger::Instance(isolate); if (debugger) debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id); event_target->DispatchEvent(*event);
diff --git a/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc b/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc index 0e433df3..7cbe0ee 100644 --- a/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc
@@ -77,8 +77,9 @@ local_frame->ForciblyPurgeV8Memory(); } } - V8PerIsolateData::MainThreadIsolate()->MemoryPressureNotification( - v8::MemoryPressureLevel::kCritical); + v8::Isolate* isolate = + frames_->Root()->GetPage()->GetAgentGroupScheduler().Isolate(); + isolate->MemoryPressureNotification(v8::MemoryPressureLevel::kCritical); return protocol::Response::Success(); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc index 852d261..23b222d 100644 --- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -1692,7 +1692,7 @@ LocalWindowProxy* isolated_world_window_proxy = frame.DomWindow()->GetScriptController().WindowProxy(*world); - v8::HandleScope handle_scope(V8PerIsolateData::MainThreadIsolate()); + v8::HandleScope handle_scope(frame.DomWindow()->GetIsolate()); callback->sendSuccess(v8_inspector::V8ContextInfo::executionContextId( isolated_world_window_proxy->ContextIfInitialized()));
diff --git a/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc b/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc index 7b14ee6..8046b9f 100644 --- a/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc
@@ -11,6 +11,7 @@ #include "base/time/time_override.h" #include "build/build_config.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/core/execution_context/agent.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/inspector/inspected_frames.h" #include "third_party/blink/renderer/core/loader/document_loader.h" @@ -242,16 +243,16 @@ base::TimeDelta process_time = GetCurrentProcessTime(); AppendMetric(result.get(), "ProcessTime", process_time.InSecondsF()); - v8::HeapStatistics heap_statistics; - V8PerIsolateData::MainThreadIsolate()->GetHeapStatistics(&heap_statistics); - AppendMetric(result.get(), "JSHeapUsedSize", - heap_statistics.used_heap_size()); - AppendMetric(result.get(), "JSHeapTotalSize", - heap_statistics.total_heap_size()); - // Performance timings. Document* document = inspected_frames_->Root()->GetDocument(); if (document) { + v8::HeapStatistics heap_statistics; + document->GetAgent().isolate()->GetHeapStatistics(&heap_statistics); + AppendMetric(result.get(), "JSHeapUsedSize", + heap_statistics.used_heap_size()); + AppendMetric(result.get(), "JSHeapTotalSize", + heap_statistics.total_heap_size()); + AppendMetric(result.get(), "FirstMeaningfulPaint", PaintTiming::From(*document) .FirstMeaningfulPaint()
diff --git a/third_party/blink/renderer/core/inspector/main_thread_debugger.cc b/third_party/blink/renderer/core/inspector/main_thread_debugger.cc index 0bb33bfa..7e61b9f 100644 --- a/third_party/blink/renderer/core/inspector/main_thread_debugger.cc +++ b/third_party/blink/renderer/core/inspector/main_thread_debugger.cc
@@ -223,10 +223,9 @@ return WeakIdentifierMap<LocalFrame>::Identifier(&local_frame_root); } -MainThreadDebugger* MainThreadDebugger::Instance() { +MainThreadDebugger* MainThreadDebugger::Instance(v8::Isolate* isolate) { DCHECK(IsMainThread()); - ThreadDebugger* debugger = - ThreadDebugger::From(V8PerIsolateData::MainThreadIsolate()); + ThreadDebugger* debugger = ThreadDebugger::From(isolate); DCHECK(debugger && !debugger->IsWorker()); return static_cast<MainThreadDebugger*>(debugger); }
diff --git a/third_party/blink/renderer/core/inspector/main_thread_debugger.h b/third_party/blink/renderer/core/inspector/main_thread_debugger.h index 3cb0566..8d0499ca 100644 --- a/third_party/blink/renderer/core/inspector/main_thread_debugger.h +++ b/third_party/blink/renderer/core/inspector/main_thread_debugger.h
@@ -65,7 +65,7 @@ MainThreadDebugger& operator=(const MainThreadDebugger&) = delete; ~MainThreadDebugger() override; - static MainThreadDebugger* Instance(); + static MainThreadDebugger* Instance(v8::Isolate*); bool IsWorker() override { return false; } bool IsPaused() const { return paused_; }
diff --git a/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc b/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc index ab05c62..ef5afc2 100644 --- a/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc +++ b/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
@@ -10,6 +10,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/execution_context/agent.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" @@ -77,7 +78,8 @@ Page::InsertOrdinaryPageForTesting(&GetPage()); Page::InsertOrdinaryPageForTesting(&GetSecondPage()); GetFrame().GetSettings()->SetScriptEnabled(true); - auto* debugger = MainThreadDebugger::Instance(); + auto* debugger = + MainThreadDebugger::Instance(GetDocument().GetAgent().isolate()); int context_group_id = debugger->ContextGroupId(&GetFrame()); if (IsDebuggerAllowed()) {
diff --git a/third_party/blink/renderer/core/inspector/request_debug_header_scope.cc b/third_party/blink/renderer/core/inspector/request_debug_header_scope.cc index 019beeb4..9f1101fc 100644 --- a/third_party/blink/renderer/core/inspector/request_debug_header_scope.cc +++ b/third_party/blink/renderer/core/inspector/request_debug_header_scope.cc
@@ -4,24 +4,18 @@ #include "third_party/blink/renderer/core/inspector/request_debug_header_scope.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/inspector/v8_inspector_string.h" -#include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h" -#include "third_party/blink/renderer/core/workers/worker_global_scope.h" -#include "third_party/blink/renderer/core/workers/worker_thread.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" +#include "third_party/blink/renderer/platform/bindings/thread_debugger.h" namespace blink { // static String RequestDebugHeaderScope::CaptureStackIdForCurrentLocation( ExecutionContext* context) { - ThreadDebugger* debugger = nullptr; - if (auto* scope = DynamicTo<WorkerGlobalScope>(context)) - debugger = WorkerThreadDebugger::From(scope->GetThread()->GetIsolate()); - else if (IsA<LocalDOMWindow>(context)) - debugger = MainThreadDebugger::Instance(); + if (!context) { + return String(); + } + ThreadDebugger* debugger = ThreadDebugger::From(context->GetIsolate()); if (!debugger) return String(); auto stack = debugger->StoreCurrentStackTrace("network request").ToString(); @@ -30,16 +24,14 @@ RequestDebugHeaderScope::RequestDebugHeaderScope(ExecutionContext* context, const String& header) { - if (header.empty()) + if (header.empty() || !context) { return; + } stack_trace_id_ = v8_inspector::V8StackTraceId(ToV8InspectorStringView(header)); if (stack_trace_id_.IsInvalid()) return; - if (auto* scope = DynamicTo<WorkerGlobalScope>(context)) - debugger_ = WorkerThreadDebugger::From(scope->GetThread()->GetIsolate()); - else if (IsA<LocalDOMWindow>(context)) - debugger_ = MainThreadDebugger::Instance(); + debugger_ = ThreadDebugger::From(context->GetIsolate()); if (debugger_) debugger_->ExternalAsyncTaskStarted(stack_trace_id_); }
diff --git a/third_party/blink/renderer/core/inspector/resolve_node.cc b/third_party/blink/renderer/core/inspector/resolve_node.cc index 467947e..a116387 100644 --- a/third_party/blink/renderer/core/inspector/resolve_node.cc +++ b/third_party/blink/renderer/core/inspector/resolve_node.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/node.h" +#include "third_party/blink/renderer/core/execution_context/agent.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/inspector/main_thread_debugger.h" #include "third_party/blink/renderer/core/inspector/v8_inspector_string.h" @@ -37,11 +38,11 @@ if (!frame) return nullptr; - v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate(); + v8::Isolate* isolate = document->GetAgent().isolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context; if (v8_execution_context_id.has_value()) { - if (!MainThreadDebugger::Instance() + if (!MainThreadDebugger::Instance(isolate) ->GetV8Inspector() ->contextById(v8_execution_context_id.value()) .ToLocal(&context)) {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_font_provider_default.cc b/third_party/blink/renderer/core/layout/layout_theme_font_provider_default.cc index 0119c5d5..ca3ebc797 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_font_provider_default.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_font_provider_default.cc
@@ -36,13 +36,13 @@ // static const FontSelectionValue& LayoutThemeFontProvider::SystemFontStyle( CSSValueID system_font_id) { - return NormalSlopeValue(); + return kNormalSlopeValue; } // static const FontSelectionValue& LayoutThemeFontProvider::SystemFontWeight( CSSValueID system_font_id) { - return NormalWeightValue(); + return kNormalWeightValue; } // static
diff --git a/third_party/blink/renderer/core/layout/layout_theme_font_provider_win.cc b/third_party/blink/renderer/core/layout/layout_theme_font_provider_win.cc index b806f1a..c8c887ff 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_font_provider_win.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_font_provider_win.cc
@@ -42,13 +42,13 @@ // static const FontSelectionValue& LayoutThemeFontProvider::SystemFontStyle( CSSValueID system_font_id) { - return NormalSlopeValue(); + return kNormalSlopeValue; } // static const FontSelectionValue& LayoutThemeFontProvider::SystemFontWeight( CSSValueID system_font_id) { - return NormalWeightValue(); + return kNormalWeightValue; } // static
diff --git a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc index cd4bcb5d..64d881d0 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc
@@ -34,9 +34,10 @@ frame, std::move(creation_params), reporting_proxy, pending_layout_registry); global_scope->ScriptController()->Initialize(NullURL()); - MainThreadDebugger::Instance()->ContextCreated( - global_scope->ScriptController()->GetScriptState(), - global_scope->GetFrame(), global_scope->DocumentSecurityOrigin()); + MainThreadDebugger::Instance(global_scope->GetIsolate()) + ->ContextCreated(global_scope->ScriptController()->GetScriptState(), + global_scope->GetFrame(), + global_scope->DocumentSecurityOrigin()); return global_scope; } @@ -51,8 +52,8 @@ LayoutWorkletGlobalScope::~LayoutWorkletGlobalScope() = default; void LayoutWorkletGlobalScope::Dispose() { - MainThreadDebugger::Instance()->ContextWillBeDestroyed( - ScriptController()->GetScriptState()); + MainThreadDebugger::Instance(GetIsolate()) + ->ContextWillBeDestroyed(ScriptController()->GetScriptState()); WorkletGlobalScope::Dispose();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc index b281107..d418128b 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
@@ -108,8 +108,8 @@ String NGInlineBreakToken::ToString() const { StringBuilder string_builder; - string_builder.Append(String::Format(" index:%u offset:%u", StartItemIndex(), - StartTextOffset())); + string_builder.Append(String::Format("NGInlineBreakToken index:%u offset:%u", + StartItemIndex(), StartTextOffset())); if (IsForcedBreak()) string_builder.Append(" forced"); return string_builder.ToString();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc index c128213..6a04c7608 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
@@ -107,10 +107,11 @@ String NGBlockBreakToken::ToString() const { StringBuilder string_builder; - string_builder.Append("("); string_builder.Append(InputNode().ToString()); - string_builder.Append(")"); if (is_break_before_) { + if (is_forced_break_) { + string_builder.Append(" forced"); + } string_builder.Append(" break-before"); } else { string_builder.Append(" sequence:"); @@ -118,6 +119,15 @@ } if (is_repeated_) string_builder.Append(" (repeated)"); + if (is_caused_by_column_spanner_) { + string_builder.Append(" (caused by spanner)"); + } + if (has_seen_all_children_) { + string_builder.Append(" (seen all children)"); + } + if (is_at_block_end_) { + string_builder.Append(" (at block-end)"); + } string_builder.Append(" consumed:"); string_builder.Append(ConsumedBlockSize().ToString()); string_builder.Append("px");
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 1dbd64b..c87f132 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1209,7 +1209,8 @@ DCHECK(commit_reason_ == CommitReason::kInitialization || !frame_->GetPage()->Paused() || - MainThreadDebugger::Instance()->IsPaused()); + MainThreadDebugger::Instance(frame_->DomWindow()->GetIsolate()) + ->IsPaused()); if (loading_main_document_from_mhtml_archive_ && state_ < kCommitted) { // The browser process should block any navigation to an MHTML archive
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 53c8abfc..1eb674b 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -286,15 +286,6 @@ return GetFrame()->Client(); } -void FrameFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request) { - // The remaining modifications are only necessary for HTTP and HTTPS. - if (!request.Url().IsEmpty() && !request.Url().ProtocolIsInHTTPFamily()) - return; - - if (GetResourceFetcherProperties().IsDetached()) - return; -} - // TODO(toyoshim, arthursonzogni): PlzNavigate doesn't use this function to set // the ResourceRequest's cache policy. The cache policy determination needs to // be factored out from FrameFetchContext and moved to the FrameLoader for
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.h b/third_party/blink/renderer/core/loader/frame_fetch_context.h index 8b3954b..d5fc13f 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.h +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.h
@@ -85,7 +85,6 @@ const DetachableResourceFetcherProperties&); ~FrameFetchContext() override = default; - void AddAdditionalRequestHeaders(ResourceRequest&) override; absl::optional<ResourceRequestBlockedReason> CanRequest( ResourceType type, const ResourceRequest& resource_request,
diff --git a/third_party/blink/renderer/core/page/drag_image.cc b/third_party/blink/renderer/core/page/drag_image.cc index 953db68..aa36c4f 100644 --- a/third_party/blink/renderer/core/page/drag_image.cc +++ b/third_party/blink/renderer/core/page/drag_image.cc
@@ -138,11 +138,11 @@ const FontDescription& system_font, float device_scale_factor) { const Font label_font = DeriveDragLabelFont(kDragLinkLabelFontSize, - BoldWeightValue(), system_font); + kBoldWeightValue, system_font); const SimpleFontData* label_font_data = label_font.PrimaryFont(); DCHECK(label_font_data); const Font url_font = DeriveDragLabelFont(kDragLinkUrlFontSize, - NormalWeightValue(), system_font); + kNormalWeightValue, system_font); const SimpleFontData* url_font_data = url_font.PrimaryFont(); DCHECK(url_font_data);
diff --git a/third_party/blink/renderer/core/page/drag_image_test.cc b/third_party/blink/renderer/core/page/drag_image_test.cc index 5641d59..9fd30e30 100644 --- a/third_party/blink/renderer/core/page/drag_image_test.cc +++ b/third_party/blink/renderer/core/page/drag_image_test.cc
@@ -140,8 +140,8 @@ font_description.SetSpecifiedSize(16); font_description.SetIsAbsoluteSize(true); font_description.SetGenericFamily(FontDescription::kNoFamily); - font_description.SetWeight(NormalWeightValue()); - font_description.SetStyle(NormalSlopeValue()); + font_description.SetWeight(kNormalWeightValue); + font_description.SetStyle(kNormalSlopeValue); std::unique_ptr<DragImage> test_image = DragImage::Create(url, test_label, font_description, device_scale_factor);
diff --git a/third_party/blink/renderer/core/paint/embedded_object_painter.cc b/third_party/blink/renderer/core/paint/embedded_object_painter.cc index 423159d..7109403 100644 --- a/third_party/blink/renderer/core/paint/embedded_object_painter.cc +++ b/third_party/blink/renderer/core/paint/embedded_object_painter.cc
@@ -30,7 +30,7 @@ FontDescription font_description; LayoutTheme::GetTheme().SystemFont(CSSValueID::kWebkitSmallControl, font_description, document); - font_description.SetWeight(BoldWeightValue()); + font_description.SetWeight(kBoldWeightValue); font_description.SetComputedSize(font_description.SpecifiedSize()); Font font(font_description); return font;
diff --git a/third_party/blink/renderer/core/style/style_highlight_data.cc b/third_party/blink/renderer/core/style/style_highlight_data.cc index 3c7ff0a..f226174 100644 --- a/third_party/blink/renderer/core/style/style_highlight_data.cc +++ b/third_party/blink/renderer/core/style/style_highlight_data.cc
@@ -108,6 +108,21 @@ custom_highlights_.Set(highlight_name, style); } +bool StyleHighlightData::DependsOnSizeContainerQueries() const { + if ((selection_ && selection_->DependsOnSizeContainerQueries()) || + (target_text_ && target_text_->DependsOnSizeContainerQueries()) || + (spelling_error_ && spelling_error_->DependsOnSizeContainerQueries()) || + (grammar_error_ && grammar_error_->DependsOnSizeContainerQueries())) { + return true; + } + for (auto style : custom_highlights_) { + if (style.value->DependsOnSizeContainerQueries()) { + return true; + } + } + return false; +} + void StyleHighlightData::Trace(Visitor* visitor) const { visitor->Trace(selection_); visitor->Trace(target_text_);
diff --git a/third_party/blink/renderer/core/style/style_highlight_data.h b/third_party/blink/renderer/core/style/style_highlight_data.h index b6a80cf..0862f25 100644 --- a/third_party/blink/renderer/core/style/style_highlight_data.h +++ b/third_party/blink/renderer/core/style/style_highlight_data.h
@@ -45,6 +45,8 @@ void SetGrammarError(const ComputedStyle*); void SetCustomHighlight(const AtomicString&, const ComputedStyle*); + bool DependsOnSizeContainerQueries() const; + void Trace(Visitor*) const; private:
diff --git a/third_party/blink/renderer/core/timing/profiler_group.cc b/third_party/blink/renderer/core/timing/profiler_group.cc index 7012a62c..7dfb6df4 100644 --- a/third_party/blink/renderer/core/timing/profiler_group.cc +++ b/third_party/blink/renderer/core/timing/profiler_group.cc
@@ -87,8 +87,7 @@ void ProfilerGroup::InitializeIfEnabled(LocalDOMWindow* local_window) { if (ProfilerGroup::CanProfile(local_window)) { - auto* profiler_group = - ProfilerGroup::From(V8PerIsolateData::MainThreadIsolate()); + auto* profiler_group = ProfilerGroup::From(local_window->GetIsolate()); profiler_group->OnProfilingContextAdded(local_window); } }
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc index cfb50b5..2196e16 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -203,7 +203,8 @@ void WorkletGlobalScope::ExceptionThrown(ErrorEvent* error_event) { if (IsMainThreadWorkletGlobalScope()) { - MainThreadDebugger::Instance()->ExceptionThrown(this, error_event); + MainThreadDebugger::Instance(GetIsolate()) + ->ExceptionThrown(this, error_event); return; } if (WorkerThreadDebugger* debugger =
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index e7ae1f4..c3e29b3 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -2777,10 +2777,12 @@ *text_strikethrough_style = ax::mojom::blink::TextDecorationStyle::kNone; *text_underline_style = ax::mojom::blink::TextDecorationStyle::kNone; - if (style->GetFontWeight() == BoldWeightValue()) + if (style->GetFontWeight() == kBoldWeightValue) { *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kBold); - if (style->GetFontDescription().Style() == ItalicSlopeValue()) + } + if (style->GetFontDescription().Style() == kItalicSlopeValue) { *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kItalic); + } for (const auto& decoration : style->AppliedTextDecorations()) { if (EnumHasFlags(decoration.Lines(), TextDecorationLine::kOverline)) {
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 c6fb527..0c1d0ff 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
@@ -2399,6 +2399,7 @@ node_object_mapping_.Contains(node)) { RemoveSubtreeWithFlatTraversal(node, /* remove_root */ false, /* notify_parent */ false); + ChildrenChanged(node); } DeferTreeUpdate(TreeUpdateReason::kNodeIsAttached, node); @@ -2757,6 +2758,14 @@ << "No cached values should require an update at this point: " << "\n* Object: " << object->ToString(true) << "\n* Included parent: " << (included_parent ? included_parent->ToString(true) : ""); + if (object->AccessibilityIsIncludedInTree()) { + for (const auto& child : object->CachedChildrenIncludingIgnored()) { + CHECK(child->AccessibilityIsIncludedInTree()) + << "Included parent cannot have unlincluded child:" + << "\n* Parent: " << object->ToString(true, true) + << "\n* Child: " << child->ToString(true, true); + } + } } #else // TODO(crbug.com/1480627) Temporary: do not ship in stable builds.
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index fa1b53e..7143b2fc 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -2520,12 +2520,12 @@ StringBuilder serialized_font; const FontDescription& font_description = GetState().GetFontDescription(); - if (font_description.Style() == ItalicSlopeValue()) { + if (font_description.Style() == kItalicSlopeValue) { serialized_font.Append("italic "); } - if (font_description.Weight() == BoldWeightValue()) { + if (font_description.Weight() == kBoldWeightValue) { serialized_font.Append("bold "); - } else if (font_description.Weight() != NormalWeightValue()) { + } else if (font_description.Weight() != kNormalWeightValue) { int weight_as_int = static_cast<int>((float)font_description.Weight()); serialized_font.AppendNumber(weight_as_int); serialized_font.Append(" ");
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc index 9eff14a..40bf44c 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -327,31 +327,31 @@ FontSelectionValue stretch_value; switch (font_stretch.AsEnum()) { case (V8CanvasFontStretch::Enum::kUltraCondensed): - stretch_value = UltraCondensedWidthValue(); + stretch_value = kUltraCondensedWidthValue; break; case (V8CanvasFontStretch::Enum::kExtraCondensed): - stretch_value = ExtraCondensedWidthValue(); + stretch_value = kExtraCondensedWidthValue; break; case (V8CanvasFontStretch::Enum::kCondensed): - stretch_value = CondensedWidthValue(); + stretch_value = kCondensedWidthValue; break; case (V8CanvasFontStretch::Enum::kSemiCondensed): - stretch_value = SemiCondensedWidthValue(); + stretch_value = kSemiCondensedWidthValue; break; case (V8CanvasFontStretch::Enum::kNormal): - stretch_value = NormalWidthValue(); + stretch_value = kNormalWidthValue; break; case (V8CanvasFontStretch::Enum::kUltraExpanded): - stretch_value = UltraExpandedWidthValue(); + stretch_value = kUltraExpandedWidthValue; break; case (V8CanvasFontStretch::Enum::kExtraExpanded): - stretch_value = ExtraExpandedWidthValue(); + stretch_value = kExtraExpandedWidthValue; break; case (V8CanvasFontStretch::Enum::kExpanded): - stretch_value = ExpandedWidthValue(); + stretch_value = kExpandedWidthValue; break; case (V8CanvasFontStretch::Enum::kSemiExpanded): - stretch_value = SemiExpandedWidthValue(); + stretch_value = kSemiExpandedWidthValue; break; default: NOTREACHED();
diff --git a/third_party/blink/renderer/modules/cookie_deprecation_label/cookie_deprecation_label.idl b/third_party/blink/renderer/modules/cookie_deprecation_label/cookie_deprecation_label.idl index 8e8f2f1c..5601f10 100644 --- a/third_party/blink/renderer/modules/cookie_deprecation_label/cookie_deprecation_label.idl +++ b/third_party/blink/renderer/modules/cookie_deprecation_label/cookie_deprecation_label.idl
@@ -5,7 +5,7 @@ [ Exposed=Window, SecureContext, - RuntimeEnabled=CookieDeprecationFacilitatedTestingLabels + RuntimeEnabled=CookieDeprecationFacilitatedTesting ] interface CookieDeprecationLabel { [CallWith=ScriptState] Promise<DOMString> getValue(); };
diff --git a/third_party/blink/renderer/modules/cookie_deprecation_label/navigator_cookie_deprecation_label.idl b/third_party/blink/renderer/modules/cookie_deprecation_label/navigator_cookie_deprecation_label.idl index bb41eb5..175e7ec 100644 --- a/third_party/blink/renderer/modules/cookie_deprecation_label/navigator_cookie_deprecation_label.idl +++ b/third_party/blink/renderer/modules/cookie_deprecation_label/navigator_cookie_deprecation_label.idl
@@ -6,5 +6,5 @@ Exposed=Window, ImplementedAs=CookieDeprecationLabel ] partial interface Navigator { - [SecureContext, SameObject, RuntimeEnabled=CookieDeprecationFacilitatedTestingLabels] readonly attribute CookieDeprecationLabel cookieDeprecationLabel; + [SecureContext, SameObject, RuntimeEnabled=CookieDeprecationFacilitatedTesting] readonly attribute CookieDeprecationLabel cookieDeprecationLabel; };
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 6ebf711..620836b 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
@@ -103,9 +103,10 @@ auto* global_scope = MakeGarbageCollected<PaintWorkletGlobalScope>( frame, std::move(creation_params), reporting_proxy); global_scope->ScriptController()->Initialize(NullURL()); - MainThreadDebugger::Instance()->ContextCreated( - global_scope->ScriptController()->GetScriptState(), - global_scope->GetFrame(), global_scope->DocumentSecurityOrigin()); + MainThreadDebugger::Instance(global_scope->GetIsolate()) + ->ContextCreated(global_scope->ScriptController()->GetScriptState(), + global_scope->GetFrame(), + global_scope->DocumentSecurityOrigin()); return global_scope; } @@ -140,8 +141,8 @@ PaintWorkletProxyClient::From(Clients())) proxy_client->Dispose(); } else { - MainThreadDebugger::Instance()->ContextWillBeDestroyed( - ScriptController()->GetScriptState()); + MainThreadDebugger::Instance(GetIsolate()) + ->ContextWillBeDestroyed(ScriptController()->GetScriptState()); } WorkletGlobalScope::Dispose();
diff --git a/third_party/blink/renderer/platform/exported/web_font_description.cc b/third_party/blink/renderer/platform/exported/web_font_description.cc index e2aa8d1..4103264 100644 --- a/third_party/blink/renderer/platform/exported/web_font_description.cc +++ b/third_party/blink/renderer/platform/exported/web_font_description.cc
@@ -39,7 +39,7 @@ family_is_generic = desc.Family().FamilyIsGeneric(); generic_family = static_cast<GenericFamily>(desc.GenericFamily()); size = desc.SpecifiedSize(); - italic = desc.Style() == ItalicSlopeValue(); + italic = desc.Style() == kItalicSlopeValue; small_caps = desc.VariantCaps() == FontDescription::kSmallCaps; DCHECK(desc.Weight() >= 100 && desc.Weight() <= 900 && static_cast<int>(desc.Weight()) % 100 == 0); @@ -60,7 +60,7 @@ static_cast<FontDescription::GenericFamilyType>(generic_family)); desc.SetSpecifiedSize(size); desc.SetComputedSize(size); - desc.SetStyle(italic ? ItalicSlopeValue() : NormalSlopeValue()); + desc.SetStyle(italic ? kItalicSlopeValue : kNormalSlopeValue); desc.SetVariantCaps(small_caps ? FontDescription::kSmallCaps : FontDescription::kCapsNormal); static_assert(static_cast<int>(WebFontDescription::kWeight100) == 0,
diff --git a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc index da25d2d..2a1f235 100644 --- a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc +++ b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
@@ -150,8 +150,8 @@ weight_coordinate = { kWghtTag, SkFloatToScalar(wght_range.clampToRange(selection_request.weight))}; - synthetic_bold = bold && wght_range.maximum < BoldThreshold() && - selection_request.weight >= BoldThreshold(); + synthetic_bold = bold && wght_range.maximum < kBoldThreshold && + selection_request.weight >= kBoldThreshold; } SkFontArguments::VariationPosition::Coordinate width_coordinate = { @@ -186,8 +186,8 @@ slant_coordinate = { kSlntTag, SkFloatToScalar(slnt_range.clampToRange(-selection_request.slope))}; - synthetic_italic = italic && slnt_range.maximum < ItalicSlopeValue() && - selection_request.slope >= ItalicSlopeValue(); + synthetic_italic = italic && slnt_range.maximum < kItalicSlopeValue && + selection_request.slope >= kItalicSlopeValue; } variation.push_back(weight_coordinate);
diff --git a/third_party/blink/renderer/platform/fonts/font_description.cc b/third_party/blink/renderer/platform/fonts/font_description.cc index 3eb52ea..35232d5b 100644 --- a/third_party/blink/renderer/platform/fonts/font_description.cc +++ b/third_party/blink/renderer/platform/fonts/font_description.cc
@@ -84,9 +84,9 @@ adjusted_size_(0), letter_spacing_(0), word_spacing_(0), - font_selection_request_(NormalWeightValue(), - NormalWidthValue(), - NormalSlopeValue()) { + font_selection_request_(kNormalWeightValue, + kNormalWidthValue, + kNormalSlopeValue) { fields_as_unsigned_.parts[0] = 0; fields_as_unsigned_.parts[1] = 0; fields_.orientation_ = static_cast<unsigned>(FontOrientation::kHorizontal); @@ -442,41 +442,51 @@ fields_.synthetic_oblique_ = IsVerticalAnyUpright() && original_slope < FontSelectionValue(0); font_selection_request_.slope = - fields_.synthetic_oblique_ ? NormalSlopeValue() : original_slope; + fields_.synthetic_oblique_ ? kNormalSlopeValue : original_slope; } SkFontStyle FontDescription::SkiaFontStyle() const { // FIXME(drott): This is a lossy conversion, compare // https://bugs.chromium.org/p/skia/issues/detail?id=6844 int skia_width = SkFontStyle::kNormal_Width; - if (Stretch() <= UltraCondensedWidthValue()) + if (Stretch() <= kUltraCondensedWidthValue) { skia_width = SkFontStyle::kUltraCondensed_Width; - if (Stretch() <= ExtraCondensedWidthValue()) + } + if (Stretch() <= kExtraCondensedWidthValue) { skia_width = SkFontStyle::kExtraCondensed_Width; - if (Stretch() <= CondensedWidthValue()) + } + if (Stretch() <= kCondensedWidthValue) { skia_width = SkFontStyle::kCondensed_Width; - if (Stretch() <= SemiCondensedWidthValue()) + } + if (Stretch() <= kSemiCondensedWidthValue) { skia_width = SkFontStyle::kSemiCondensed_Width; - if (Stretch() >= SemiExpandedWidthValue()) + } + if (Stretch() >= kSemiExpandedWidthValue) { skia_width = SkFontStyle::kSemiExpanded_Width; - if (Stretch() >= ExpandedWidthValue()) + } + if (Stretch() >= kExpandedWidthValue) { skia_width = SkFontStyle::kExpanded_Width; - if (Stretch() >= ExtraExpandedWidthValue()) + } + if (Stretch() >= kExtraExpandedWidthValue) { skia_width = SkFontStyle::kExtraExpanded_Width; - if (Stretch() >= UltraExpandedWidthValue()) + } + if (Stretch() >= kUltraExpandedWidthValue) { skia_width = SkFontStyle::kUltraExpanded_Width; + } SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant; FontSelectionValue style = Style(); - if (style > NormalSlopeValue() && style <= ItalicThreshold()) + if (style > kNormalSlopeValue && style <= kItalicThreshold) { slant = SkFontStyle::kItalic_Slant; - if (style > ItalicThreshold()) { + } + if (style > kItalicThreshold) { slant = SkFontStyle::kOblique_Slant; } int skia_weight = SkFontStyle::kNormal_Weight; - if (Weight() >= MinWeightValue() && Weight() <= MaxWeightValue()) + if (Weight() >= kMinWeightValue && Weight() <= kMaxWeightValue) { skia_weight = static_cast<int>(Weight()); + } return SkFontStyle(skia_weight, skia_width, slant); } @@ -486,35 +496,35 @@ switch (font_style.width()) { case (SkFontStyle::kUltraCondensed_Width): - SetStretch(UltraCondensedWidthValue()); + SetStretch(kUltraCondensedWidthValue); break; case (SkFontStyle::kExtraCondensed_Width): - SetStretch(ExtraCondensedWidthValue()); + SetStretch(kExtraCondensedWidthValue); break; case (SkFontStyle::kCondensed_Width): - SetStretch(CondensedWidthValue()); + SetStretch(kCondensedWidthValue); break; case (SkFontStyle::kSemiCondensed_Width): - SetStretch(SemiCondensedWidthValue()); + SetStretch(kSemiCondensedWidthValue); break; case (SkFontStyle::kSemiExpanded_Width): - SetStretch(SemiExpandedWidthValue()); + SetStretch(kSemiExpandedWidthValue); break; case (SkFontStyle::kExpanded_Width): - SetStretch(ExpandedWidthValue()); + SetStretch(kExpandedWidthValue); break; case (SkFontStyle::kExtraExpanded_Width): - SetStretch(ExtraExpandedWidthValue()); + SetStretch(kExtraExpandedWidthValue); break; case (SkFontStyle::kUltraExpanded_Width): - SetStretch(UltraExpandedWidthValue()); + SetStretch(kUltraExpandedWidthValue); break; } if (font_style.slant() == SkFontStyle::kOblique_Slant) - SetStyle(ItalicSlopeValue()); + SetStyle(kItalicSlopeValue); else - SetStyle(NormalSlopeValue()); + SetStyle(kNormalSlopeValue); } int FontDescription::MinimumPrefixWidthToHyphenate() const { @@ -575,24 +585,25 @@ } String FontDescription::ToString(FontSelectionValue selection_value) { - if (selection_value == UltraCondensedWidthValue()) + if (selection_value == kUltraCondensedWidthValue) { return "Ultra-Condensed"; - else if (selection_value == ExtraCondensedWidthValue()) + } else if (selection_value == kExtraCondensedWidthValue) { return "Extra-Condensed"; - else if (selection_value == CondensedWidthValue()) + } else if (selection_value == kCondensedWidthValue) { return "Condensed"; - else if (selection_value == SemiCondensedWidthValue()) + } else if (selection_value == kSemiCondensedWidthValue) { return "Semi-Condensed"; - else if (selection_value == NormalWidthValue()) + } else if (selection_value == kNormalWidthValue) { return "Normal"; - else if (selection_value == SemiExpandedWidthValue()) + } else if (selection_value == kSemiExpandedWidthValue) { return "Semi-Expanded"; - else if (selection_value == ExpandedWidthValue()) + } else if (selection_value == kExpandedWidthValue) { return "Expanded"; - else if (selection_value == ExtraExpandedWidthValue()) + } else if (selection_value == kExtraExpandedWidthValue) { return "Extra-Expanded"; - else if (selection_value == UltraExpandedWidthValue()) + } else if (selection_value == kUltraExpandedWidthValue) { return "Ultra-Expanded"; + } return "Unknown"; }
diff --git a/third_party/blink/renderer/platform/fonts/font_description_test.cc b/third_party/blink/renderer/platform/fonts/font_description_test.cc index 3a29e88..955c886 100644 --- a/third_party/blink/renderer/platform/fonts/font_description_test.cc +++ b/third_party/blink/renderer/platform/fonts/font_description_test.cc
@@ -41,13 +41,13 @@ FontSelectionValue(700), FontSelectionValue(800), FontSelectionValue(900)}; FontSelectionValue stretches[]{ - UltraCondensedWidthValue(), ExtraCondensedWidthValue(), - CondensedWidthValue(), SemiCondensedWidthValue(), - NormalWidthValue(), SemiExpandedWidthValue(), - ExpandedWidthValue(), ExtraExpandedWidthValue(), - UltraExpandedWidthValue()}; + kUltraCondensedWidthValue, kExtraCondensedWidthValue, + kCondensedWidthValue, kSemiCondensedWidthValue, + kNormalWidthValue, kSemiExpandedWidthValue, + kExpandedWidthValue, kExtraExpandedWidthValue, + kUltraExpandedWidthValue}; - FontSelectionValue slopes[] = {NormalSlopeValue(), ItalicSlopeValue()}; + FontSelectionValue slopes[] = {kNormalSlopeValue, kItalicSlopeValue}; FontDescription source; WTF::Vector<unsigned> hashes;
diff --git a/third_party/blink/renderer/platform/fonts/font_selection_algorithm.cc b/third_party/blink/renderer/platform/fonts/font_selection_algorithm.cc index 0ac9d52..606d95e 100644 --- a/third_party/blink/renderer/platform/fonts/font_selection_algorithm.cc +++ b/third_party/blink/renderer/platform/fonts/font_selection_algorithm.cc
@@ -34,7 +34,7 @@ if (width.Includes(request_.width)) return {FontSelectionValue(), request_.width}; - if (request_.width > NormalWidthValue()) { + if (request_.width > kNormalWidthValue) { if (width.minimum > request_.width) return {width.minimum - request_.width, width.minimum}; DCHECK(width.maximum < request_.width); @@ -57,7 +57,7 @@ if (slope.Includes(request_.slope)) return {FontSelectionValue(), request_.slope}; - if (request_.slope >= ItalicThreshold()) { + if (request_.slope >= kItalicThreshold) { if (slope.minimum > request_.slope) return {slope.minimum - request_.slope, slope.minimum}; DCHECK(request_.slope > slope.maximum); @@ -77,7 +77,7 @@ return {threshold - slope.maximum, slope.maximum}; } - if (request_.slope > -ItalicThreshold()) { + if (request_.slope > -kItalicThreshold) { if (slope.minimum > request_.slope && slope.minimum <= FontSelectionValue()) return {slope.minimum - request_.slope, slope.minimum}; if (slope.maximum < request_.slope) @@ -102,20 +102,21 @@ if (weight.Includes(request_.weight)) return {FontSelectionValue(), request_.weight}; - if (request_.weight >= LowerWeightSearchThreshold() && - request_.weight <= UpperWeightSearchThreshold()) { + if (request_.weight >= kLowerWeightSearchThreshold && + request_.weight <= kUpperWeightSearchThreshold) { if (weight.minimum > request_.weight && - weight.minimum <= UpperWeightSearchThreshold()) + weight.minimum <= kUpperWeightSearchThreshold) { return {weight.minimum - request_.weight, weight.minimum}; + } if (weight.maximum < request_.weight) - return {UpperWeightSearchThreshold() - weight.maximum, weight.maximum}; - DCHECK(weight.minimum > UpperWeightSearchThreshold()); + return {kUpperWeightSearchThreshold - weight.maximum, weight.maximum}; + DCHECK(weight.minimum > kUpperWeightSearchThreshold); auto threshold = std::min(request_.weight, capabilities_bounds_.weight.minimum); return {weight.minimum - threshold, weight.minimum}; } - if (request_.weight < LowerWeightSearchThreshold()) { + if (request_.weight < kLowerWeightSearchThreshold) { if (weight.maximum < request_.weight) return {request_.weight - weight.maximum, weight.maximum}; DCHECK(weight.minimum > request_.weight); @@ -124,7 +125,7 @@ return {weight.minimum - threshold, weight.minimum}; } - DCHECK(request_.weight >= UpperWeightSearchThreshold()); + DCHECK(request_.weight >= kUpperWeightSearchThreshold); if (weight.minimum > request_.weight) return {weight.minimum - request_.weight, weight.minimum}; DCHECK(weight.maximum < request_.weight);
diff --git a/third_party/blink/renderer/platform/fonts/font_selection_types.h b/third_party/blink/renderer/platform/fonts/font_selection_types.h index cccdd8d..3e7c5d7 100644 --- a/third_party/blink/renderer/platform/fonts/font_selection_types.h +++ b/third_party/blink/renderer/platform/fonts/font_selection_types.h
@@ -50,57 +50,53 @@ FontSelectionValue() = default; // Explicit because it is lossy. - explicit FontSelectionValue(int x) + explicit constexpr FontSelectionValue(int x) : backing_(ClampTo<int16_t>(x * fractionalEntropy)) {} // Explicit because it is lossy. - explicit FontSelectionValue(float x) + explicit constexpr FontSelectionValue(float x) : backing_(ClampTo<int16_t>(x * fractionalEntropy)) {} // Explicit because it is lossy. - explicit FontSelectionValue(double x) + explicit constexpr FontSelectionValue(double x) : backing_(ClampTo<int16_t>(x * fractionalEntropy)) {} - operator float() const { + constexpr operator float() const { // floats have 23 fractional bits, but only 14 fractional bits are // necessary, so every value can be represented losslessly. return backing_ / static_cast<float>(fractionalEntropy); } - FontSelectionValue operator+(const FontSelectionValue other) const; - FontSelectionValue operator-(const FontSelectionValue other) const; - FontSelectionValue operator*(const FontSelectionValue other) const; - FontSelectionValue operator/(const FontSelectionValue other) const; - FontSelectionValue operator-() const; - bool operator==(const FontSelectionValue other) const; - bool operator!=(const FontSelectionValue other) const; - bool operator<(const FontSelectionValue other) const; - bool operator<=(const FontSelectionValue other) const; - bool operator>(const FontSelectionValue other) const; - bool operator>=(const FontSelectionValue other) const; + constexpr FontSelectionValue operator+(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator-(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator*(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator/(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator-() const; + constexpr bool operator==(const FontSelectionValue& other) const; + constexpr bool operator!=(const FontSelectionValue& other) const; + constexpr bool operator<(const FontSelectionValue& other) const; + constexpr bool operator<=(const FontSelectionValue& other) const; + constexpr bool operator>(const FontSelectionValue& other) const; + constexpr bool operator>=(const FontSelectionValue& other) const; int16_t RawValue() const { return backing_; } String ToString() const; - static const FontSelectionValue& MaximumValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - const FontSelectionValue, maximumValue, - (std::numeric_limits<int16_t>::max(), RawTag::RawTag)); - return maximumValue; + static constexpr FontSelectionValue MaximumValue() { + return FontSelectionValue(std::numeric_limits<int16_t>::max(), + RawTag::RawTag); } - static const FontSelectionValue& MinimumValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - const FontSelectionValue, minimumValue, - (std::numeric_limits<int16_t>::min(), RawTag::RawTag)); - return minimumValue; + static constexpr FontSelectionValue MinimumValue() { + return FontSelectionValue(std::numeric_limits<int16_t>::min(), + RawTag::RawTag); } protected: enum class RawTag { RawTag }; - FontSelectionValue(int16_t rawValue, RawTag) : backing_(rawValue) {} + constexpr FontSelectionValue(int16_t rawValue, RawTag) : backing_(rawValue) {} private: static constexpr int fractionalEntropy = 4; @@ -109,208 +105,129 @@ int16_t backing_{0}; }; -inline FontSelectionValue FontSelectionValue::operator+( - const FontSelectionValue other) const { +inline constexpr FontSelectionValue FontSelectionValue::operator+( + const FontSelectionValue& other) const { return FontSelectionValue(backing_ + other.backing_, RawTag::RawTag); } -inline FontSelectionValue FontSelectionValue::operator-( - const FontSelectionValue other) const { +inline constexpr FontSelectionValue FontSelectionValue::operator-( + const FontSelectionValue& other) const { return FontSelectionValue(backing_ - other.backing_, RawTag::RawTag); } -inline FontSelectionValue FontSelectionValue::operator*( - const FontSelectionValue other) const { +inline constexpr FontSelectionValue FontSelectionValue::operator*( + const FontSelectionValue& other) const { return FontSelectionValue( static_cast<int32_t>(backing_) * other.backing_ / fractionalEntropy, RawTag::RawTag); } -inline FontSelectionValue FontSelectionValue::operator/( - const FontSelectionValue other) const { +inline constexpr FontSelectionValue FontSelectionValue::operator/( + const FontSelectionValue& other) const { return FontSelectionValue( static_cast<int32_t>(backing_) / other.backing_ * fractionalEntropy, RawTag::RawTag); } -inline FontSelectionValue FontSelectionValue::operator-() const { +inline constexpr FontSelectionValue FontSelectionValue::operator-() const { return FontSelectionValue(-backing_, RawTag::RawTag); } -inline bool FontSelectionValue::operator==( - const FontSelectionValue other) const { +inline constexpr bool FontSelectionValue::operator==( + const FontSelectionValue& other) const { return backing_ == other.backing_; } -inline bool FontSelectionValue::operator!=( - const FontSelectionValue other) const { +inline constexpr bool FontSelectionValue::operator!=( + const FontSelectionValue& other) const { return !operator==(other); } -inline bool FontSelectionValue::operator<( - const FontSelectionValue other) const { +inline constexpr bool FontSelectionValue::operator<( + const FontSelectionValue& other) const { return backing_ < other.backing_; } -inline bool FontSelectionValue::operator<=( - const FontSelectionValue other) const { +inline constexpr bool FontSelectionValue::operator<=( + const FontSelectionValue& other) const { return backing_ <= other.backing_; } -inline bool FontSelectionValue::operator>( - const FontSelectionValue other) const { +inline constexpr bool FontSelectionValue::operator>( + const FontSelectionValue& other) const { return backing_ > other.backing_; } -inline bool FontSelectionValue::operator>=( - const FontSelectionValue other) const { +inline constexpr bool FontSelectionValue::operator>=( + const FontSelectionValue& other) const { return backing_ >= other.backing_; } -static inline const FontSelectionValue& ItalicThreshold() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, italicThreshold, - (14)); - return italicThreshold; +inline constexpr FontSelectionValue kItalicThreshold = FontSelectionValue(14); + +static constexpr inline bool isItalic(FontSelectionValue fontStyle) { + return fontStyle >= kItalicThreshold; } -static inline bool isItalic(FontSelectionValue fontStyle) { - return fontStyle >= ItalicThreshold(); +inline constexpr FontSelectionValue kFontSelectionZeroValue = + FontSelectionValue(0); + +inline constexpr FontSelectionValue kNormalSlopeValue = FontSelectionValue(); + +inline constexpr FontSelectionValue kItalicSlopeValue = FontSelectionValue(14); + +inline constexpr FontSelectionValue kMaxObliqueValue = FontSelectionValue(90); + +inline constexpr FontSelectionValue kMinObliqueValue = FontSelectionValue(-90); + +inline constexpr FontSelectionValue kBoldThreshold = FontSelectionValue(600); + +inline constexpr FontSelectionValue kMinWeightValue = FontSelectionValue(1); + +inline constexpr FontSelectionValue kMaxWeightValue = FontSelectionValue(1000); + +inline constexpr FontSelectionValue kBoldWeightValue = FontSelectionValue(700); + +inline constexpr FontSelectionValue kNormalWeightValue = + FontSelectionValue(400); + +inline constexpr FontSelectionValue kLightWeightValue = FontSelectionValue(200); + +static constexpr inline bool isFontWeightBold(FontSelectionValue fontWeight) { + return fontWeight >= kBoldThreshold; } -static inline const FontSelectionValue& FontSelectionZeroValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - fontSelectionZeroValue, (0)); - return fontSelectionZeroValue; -} +inline constexpr FontSelectionValue kUpperWeightSearchThreshold = + FontSelectionValue(500); -static inline const FontSelectionValue& NormalSlopeValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, normalSlopeValue, - ()); - return normalSlopeValue; -} +inline constexpr FontSelectionValue kLowerWeightSearchThreshold = + FontSelectionValue(400); -static inline const FontSelectionValue& ItalicSlopeValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, italicValue, (14)); - return italicValue; -} +inline constexpr FontSelectionValue kUltraCondensedWidthValue = + FontSelectionValue(50); -static inline const FontSelectionValue& MaxObliqueValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, maxObliqueValue, - (90)); - return maxObliqueValue; -} +inline constexpr FontSelectionValue kExtraCondensedWidthValue = + FontSelectionValue(62.5f); -static inline const FontSelectionValue& MinObliqueValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, minObliqueValue, - (-90)); - return minObliqueValue; -} +inline constexpr FontSelectionValue kCondensedWidthValue = + FontSelectionValue(75); -static inline const FontSelectionValue& BoldThreshold() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, boldThreshold, - (600)); - return boldThreshold; -} +inline constexpr FontSelectionValue kSemiCondensedWidthValue = + FontSelectionValue(87.5f); -static inline const FontSelectionValue& MinWeightValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, minWeightValue, - (1)); - return minWeightValue; -} +inline constexpr FontSelectionValue kNormalWidthValue = FontSelectionValue(100); -static inline const FontSelectionValue& MaxWeightValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, maxWeightValue, - (1000)); - return maxWeightValue; -} +inline constexpr FontSelectionValue kSemiExpandedWidthValue = + FontSelectionValue(112.5f); -static inline const FontSelectionValue& BoldWeightValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, boldWeightValue, - (700)); - return boldWeightValue; -} +inline constexpr FontSelectionValue kExpandedWidthValue = + FontSelectionValue(125); -static inline const FontSelectionValue& NormalWeightValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, normalWeightValue, - (400)); - return normalWeightValue; -} +inline constexpr FontSelectionValue kExtraExpandedWidthValue = + FontSelectionValue(150); -static inline const FontSelectionValue& LightWeightValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, lightWeightValue, - (200)); - return lightWeightValue; -} - -static inline bool isFontWeightBold(FontSelectionValue fontWeight) { - return fontWeight >= BoldThreshold(); -} - -static inline const FontSelectionValue& UpperWeightSearchThreshold() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - upperWeightSearchThreshold, (500)); - return upperWeightSearchThreshold; -} - -static inline const FontSelectionValue& LowerWeightSearchThreshold() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - lowerWeightSearchThreshold, (400)); - return lowerWeightSearchThreshold; -} - -static inline const FontSelectionValue& UltraCondensedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - ultraCondensedWidthValue, (50)); - return ultraCondensedWidthValue; -} - -static inline const FontSelectionValue& ExtraCondensedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - extraCondensedWidthValue, (62.5f)); - return extraCondensedWidthValue; -} - -static inline const FontSelectionValue& CondensedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, condensedWidthValue, - (75)); - return condensedWidthValue; -} - -static inline const FontSelectionValue& SemiCondensedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - semiCondensedWidthValue, (87.5f)); - return semiCondensedWidthValue; -} - -static inline const FontSelectionValue& NormalWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, normalWidthValue, - (100.0f)); - return normalWidthValue; -} - -static inline const FontSelectionValue& SemiExpandedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - semiExpandedWidthValue, (112.5f)); - return semiExpandedWidthValue; -} - -static inline const FontSelectionValue& ExpandedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, expandedWidthValue, - (125)); - return expandedWidthValue; -} - -static inline const FontSelectionValue& ExtraExpandedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - extraExpandedWidthValue, (150)); - return extraExpandedWidthValue; -} - -static inline const FontSelectionValue& UltraExpandedWidthValue() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(const FontSelectionValue, - ultraExpandedWidthValue, (200)); - return ultraExpandedWidthValue; -} +inline constexpr FontSelectionValue kUltraExpandedWidthValue = + FontSelectionValue(200); struct FontSelectionRange { enum RangeType { kSetFromAuto, kSetExplicitly }; @@ -318,11 +235,12 @@ explicit FontSelectionRange(FontSelectionValue single_value) : minimum(single_value), maximum(single_value) {} - FontSelectionRange(FontSelectionValue minimum, FontSelectionValue maximum) + FontSelectionRange(const FontSelectionValue& minimum, + const FontSelectionValue maximum) : minimum(minimum), maximum(maximum) {} - FontSelectionRange(FontSelectionValue minimum, - FontSelectionValue maximum, + FontSelectionRange(const FontSelectionValue& minimum, + const FontSelectionValue& maximum, RangeType type) : minimum(minimum), maximum(maximum), type(type) {} @@ -457,9 +375,9 @@ return !(*this == other); } - FontSelectionRange width{FontSelectionZeroValue(), FontSelectionZeroValue()}; - FontSelectionRange slope{FontSelectionZeroValue(), FontSelectionZeroValue()}; - FontSelectionRange weight{FontSelectionZeroValue(), FontSelectionZeroValue()}; + FontSelectionRange width{kFontSelectionZeroValue, kFontSelectionZeroValue}; + FontSelectionRange slope{kFontSelectionZeroValue, kFontSelectionZeroValue}; + FontSelectionRange weight{kFontSelectionZeroValue, kFontSelectionZeroValue}; bool is_deleted_value_{false}; };
diff --git a/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc b/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc index 220525c..cdc9c185 100644 --- a/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc +++ b/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
@@ -94,8 +94,8 @@ // First try the specified font with standard style & weight. if (fallback_priority != FontFallbackPriority::kEmojiEmoji && - (font_description.Style() == ItalicSlopeValue() || - font_description.Weight() >= BoldThreshold())) { + (font_description.Style() == kItalicSlopeValue || + font_description.Weight() >= kBoldThreshold)) { scoped_refptr<SimpleFontData> font_data = FallbackOnStandardFontStyle(font_description, c); if (font_data) @@ -122,19 +122,21 @@ bool should_set_synthetic_bold = false; bool should_set_synthetic_italic = false; FontDescription description(font_description); - if (fallback_font.is_bold && description.Weight() < BoldThreshold()) - description.SetWeight(BoldWeightValue()); - if (!fallback_font.is_bold && description.Weight() >= BoldThreshold() && + if (fallback_font.is_bold && description.Weight() < kBoldThreshold) { + description.SetWeight(kBoldWeightValue); + } + if (!fallback_font.is_bold && description.Weight() >= kBoldThreshold && font_description.SyntheticBoldAllowed()) { should_set_synthetic_bold = true; - description.SetWeight(NormalWeightValue()); + description.SetWeight(kNormalWeightValue); } - if (fallback_font.is_italic && description.Style() == NormalSlopeValue()) - description.SetStyle(ItalicSlopeValue()); - if (!fallback_font.is_italic && (description.Style() == ItalicSlopeValue()) && + if (fallback_font.is_italic && description.Style() == kNormalSlopeValue) { + description.SetStyle(kItalicSlopeValue); + } + if (!fallback_font.is_italic && (description.Style() == kItalicSlopeValue) && font_description.SyntheticItalicAllowed()) { should_set_synthetic_italic = true; - description.SetStyle(NormalSlopeValue()); + description.SetStyle(kNormalSlopeValue); } FontPlatformData* substitute_platform_data =
diff --git a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc index ae4a61f..29d1d817 100644 --- a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc +++ b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
@@ -97,8 +97,8 @@ const FontDescription& font_description, UChar32 character) { FontDescription substitute_description(font_description); - substitute_description.SetStyle(NormalSlopeValue()); - substitute_description.SetWeight(NormalWeightValue()); + substitute_description.SetStyle(kNormalSlopeValue); + substitute_description.SetWeight(kNormalWeightValue); FontFaceCreationParams creation_params( substitute_description.Family().FamilyName()); @@ -109,10 +109,10 @@ FontPlatformData platform_data = FontPlatformData(*substitute_platform_data); platform_data.SetSyntheticBold(font_description.Weight() >= - BoldThreshold() && + kBoldThreshold && font_description.SyntheticBoldAllowed()); platform_data.SetSyntheticItalic(font_description.Style() == - ItalicSlopeValue() && + kItalicSlopeValue && font_description.SyntheticItalicAllowed()); return FontDataFromFontPlatformData(&platform_data, kDoNotRetain); } @@ -281,7 +281,7 @@ font_description.GetFontSynthesisWeight() == FontDescription::kAutoFontSynthesisWeight; - bool synthetic_italic = (((font_description.Style() == ItalicSlopeValue()) && + bool synthetic_italic = (((font_description.Style() == kItalicSlopeValue) && !typeface->isItalic()) || font_description.IsSyntheticItalic()) && font_description.GetFontSynthesisStyle() ==
diff --git a/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc b/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc index 83efc5c..01e6acd3 100644 --- a/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc +++ b/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
@@ -284,8 +284,8 @@ // First try the specified font with standard style & weight. if (fallback_priority != FontFallbackPriority::kEmojiEmoji && - (font_description.Style() == ItalicSlopeValue() || - font_description.Weight() >= BoldWeightValue())) { + (font_description.Style() == kItalicSlopeValue || + font_description.Weight() >= kBoldWeightValue)) { scoped_refptr<SimpleFontData> font_data = FallbackOnStandardFontStyle(font_description, character); if (font_data) @@ -392,15 +392,15 @@ // Also includes Narrow as a synonym for Condensed to to support Arial // Narrow and other fonts following the same naming scheme. const static FamilyStretchSuffix kVariantForSuffix[] = { - {u" ultracondensed", 15, UltraCondensedWidthValue()}, - {u" extracondensed", 15, ExtraCondensedWidthValue()}, - {u" condensed", 10, CondensedWidthValue()}, - {u" narrow", 7, CondensedWidthValue()}, - {u" semicondensed", 14, SemiCondensedWidthValue()}, - {u" semiexpanded", 13, SemiExpandedWidthValue()}, - {u" expanded", 9, ExpandedWidthValue()}, - {u" extraexpanded", 14, ExtraExpandedWidthValue()}, - {u" ultraexpanded", 14, UltraExpandedWidthValue()}}; + {u" ultracondensed", 15, kUltraCondensedWidthValue}, + {u" extracondensed", 15, kExtraCondensedWidthValue}, + {u" condensed", 10, kCondensedWidthValue}, + {u" narrow", 7, kCondensedWidthValue}, + {u" semicondensed", 14, kSemiCondensedWidthValue}, + {u" semiexpanded", 13, kSemiExpandedWidthValue}, + {u" expanded", 9, kExpandedWidthValue}, + {u" extraexpanded", 14, kExtraExpandedWidthValue}, + {u" ultraexpanded", 14, kUltraExpandedWidthValue}}; size_t num_variants = std::size(kVariantForSuffix); for (size_t i = 0; i < num_variants; i++) { const FamilyStretchSuffix& entry = kVariantForSuffix[i]; @@ -496,11 +496,11 @@ } bool synthetic_bold_requested = - (font_description.Weight() >= BoldThreshold() && !typeface->isBold()) || + (font_description.Weight() >= kBoldThreshold && !typeface->isBold()) || font_description.IsSyntheticBold(); bool synthetic_italic_requested = - ((font_description.Style() == ItalicSlopeValue()) && + ((font_description.Style() == kItalicSlopeValue) && !typeface->isItalic()) || font_description.IsSyntheticItalic();
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc index 37896cf..ce6358c 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc
@@ -10,51 +10,6 @@ ResourceLoadTiming::ResourceLoadTiming() = default; -ResourceLoadTiming::ResourceLoadTiming( - base::TimeTicks request_time, - base::TimeTicks proxy_start, - base::TimeTicks proxy_end, - base::TimeTicks domain_lookup_start, - base::TimeTicks domain_lookup_end, - base::TimeTicks connect_start, - base::TimeTicks connect_end, - base::TimeTicks worker_start, - base::TimeTicks worker_ready, - base::TimeTicks worker_fetch_start, - base::TimeTicks worker_respond_with_settled, - base::TimeTicks send_start, - base::TimeTicks send_end, - base::TimeTicks receive_headers_start, - base::TimeTicks receive_headers_end, - base::TimeTicks receive_non_informational_headers_start, - base::TimeTicks receive_early_hints_start, - base::TimeTicks ssl_start, - base::TimeTicks ssl_end, - base::TimeTicks push_start, - base::TimeTicks push_end) - : request_time_(request_time), - proxy_start_(proxy_start), - proxy_end_(proxy_end), - domain_lookup_start_(domain_lookup_start), - domain_lookup_end_(domain_lookup_end), - connect_start_(connect_start), - connect_end_(connect_end), - worker_start_(worker_start), - worker_ready_(worker_ready), - worker_fetch_start_(worker_fetch_start), - worker_respond_with_settled_(worker_respond_with_settled), - send_start_(send_start), - send_end_(send_end), - receive_headers_start_(receive_headers_start), - receive_headers_end_(receive_headers_end), - receive_non_informational_headers_start_( - receive_non_informational_headers_start), - receive_early_hints_start_(receive_early_hints_start), - ssl_start_(ssl_start), - ssl_end_(ssl_end), - push_start_(push_start), - push_end_(push_end) {} - scoped_refptr<ResourceLoadTiming> ResourceLoadTiming::Create() { return base::AdoptRef(new ResourceLoadTiming); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h index 6b2490f..6bc9377 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h
@@ -95,27 +95,6 @@ private: ResourceLoadTiming(); - ResourceLoadTiming(base::TimeTicks request_time, - base::TimeTicks proxy_start, - base::TimeTicks proxy_end, - base::TimeTicks domain_lookup_start, - base::TimeTicks domain_lookup_end, - base::TimeTicks connect_start, - base::TimeTicks connect_end, - base::TimeTicks worker_start, - base::TimeTicks worker_ready, - base::TimeTicks worker_fetch_start, - base::TimeTicks worker_respond_with_settled, - base::TimeTicks send_start, - base::TimeTicks send_end, - base::TimeTicks receive_headers_start, - base::TimeTicks receive_headers_end, - base::TimeTicks receive_non_informational_headers_start, - base::TimeTicks receive_early_hints_starts, - base::TimeTicks ssl_start, - base::TimeTicks ssl_end, - base::TimeTicks push_start, - base::TimeTicks push_end); // We want to present a unified timeline to Javascript. Using walltime is // problematic, because the clock may skew while resources load. To prevent
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_client.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_client.h index dd052968..fb65850 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_client.h +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_client.h
@@ -37,15 +37,16 @@ // note: only for requests with upload progress enabled. virtual void OnUploadProgress(uint64_t position, uint64_t size) = 0; - // Called when a redirect occurs. The implementation may return false to - // suppress the redirect. The URLResponseHead provides information about - // the redirect response and the RedirectInfo includes information about the - // request to be made if the method returns true. |removed_headers| outputs - // header field names that need to be removed. - virtual bool OnReceivedRedirect( + // Called when a redirect occurs. The URLResponseHead provides information + // about the redirect response and the RedirectInfo includes information about + // the request to be made if the `follow_redirect_callback` is called. + // `removed_headers` contains header field names that need to be removed. + using FollowRedirectCallback = + base::OnceCallback<void(std::vector<std::string> removed_headers)>; + virtual void OnReceivedRedirect( const net::RedirectInfo& redirect_info, network::mojom::URLResponseHeadPtr head, - std::vector<std::string>* removed_headers) = 0; + FollowRedirectCallback follow_redirect_callback) = 0; // Called when response headers are available (after all redirects have // been followed). `response_arrival` represents the timing at which the
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.cc index 3a82b4bf..501a89d 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.cc
@@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/functional/bind.h" #include "base/logging.h" +#include "base/memory/ref_counted.h" #include "base/metrics/histogram_macros.h" #include "base/ranges/algorithm.h" #include "base/strings/string_util.h" @@ -185,20 +186,38 @@ std::move(download_to_blob_registry), cors_exempt_header_list, std::move(resource_load_info_notifier_wrapper))); - // redirect_or_response_event will signal when each redirect completes, and + // `redirect_or_response_event` will signal when each redirect completes, and // when the final response is complete. redirect_or_response_event.Wait(); while (context_for_redirect) { DCHECK(response->redirect_info); - bool follow_redirect = client->OnReceivedRedirect( + + using RefCountedOptionalStringVector = + base::RefCountedData<absl::optional<std::vector<std::string>>>; + const scoped_refptr<RefCountedOptionalStringVector> removed_headers = + base::MakeRefCounted<RefCountedOptionalStringVector>(); + client->OnReceivedRedirect( *response->redirect_info, response->head.Clone(), - nullptr /* removed_headers */); + /*follow_redirect_callback=*/ + WTF::BindOnce( + [](scoped_refptr<RefCountedOptionalStringVector> + removed_headers_out, + std::vector<std::string> removed_headers) { + removed_headers_out->data = std::move(removed_headers); + }, + removed_headers)); + // `follow_redirect_callback` can't be asynchronously called for synchronous + // requests because the current thread will be blocked by + // `redirect_or_response_event.Wait()` call. So we check `HasOneRef()` here + // to ensure that `follow_redirect_callback` is not kept alive. + CHECK(removed_headers->HasOneRef()); redirect_or_response_event.Reset(); - if (follow_redirect) { + if (removed_headers->data.has_value()) { task_runner->PostTask( FROM_HERE, base::BindOnce(&SyncLoadContext::FollowRedirect, - base::Unretained(context_for_redirect))); + base::Unretained(context_for_redirect), + std::move(*removed_headers->data))); } else { task_runner->PostTask( FROM_HERE, base::BindOnce(&SyncLoadContext::CancelRedirect, @@ -463,31 +482,38 @@ "Blink.ResourceRequest.RedirectDelay", request_info_->local_response_start - remote_response_start); } - std::vector<std::string> removed_headers; - if (request_info_->client->OnReceivedRedirect( - redirect_info, response_head.Clone(), &removed_headers)) { - // Double-check if the request is still around. The call above could - // potentially remove it. - if (!request_info_) { - return; - } - // TODO(yoav): If request_info doesn't change above, we could avoid this - // copy. - WebVector<WebString> vector(removed_headers.size()); - base::ranges::transform(removed_headers, vector.begin(), - &WebString::FromASCII); - request_info_->removed_headers = vector; - request_info_->response_url = KURL(redirect_info.new_url); - request_info_->has_pending_redirect = true; - request_info_->resource_load_info_notifier_wrapper - ->NotifyResourceRedirectReceived(redirect_info, - std::move(response_head)); - if (request_info_->freeze_mode == LoaderFreezeMode::kNone) { - FollowPendingRedirect(request_info_.get()); - } - } else { - Cancel(std::move(task_runner)); + auto callback = + WTF::BindOnce(&ResourceRequestSender::OnFollowRedirectCallback, + weak_factory_.GetWeakPtr(), redirect_info, + response_head.Clone(), std::move(task_runner)); + request_info_->client->OnReceivedRedirect( + redirect_info, std::move(response_head), std::move(callback)); +} + +void ResourceRequestSender::OnFollowRedirectCallback( + const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr response_head, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + std::vector<std::string> removed_headers) { + // DeletePendingRequest() may have cleared request_info_. + if (!request_info_) { + return; + } + + // TODO(yoav): If request_info doesn't change above, we could avoid this + // copy. + WebVector<WebString> vector(removed_headers.size()); + base::ranges::transform(removed_headers, vector.begin(), + &WebString::FromASCII); + request_info_->removed_headers = vector; + request_info_->response_url = KURL(redirect_info.new_url); + request_info_->has_pending_redirect = true; + request_info_->resource_load_info_notifier_wrapper + ->NotifyResourceRedirectReceived(redirect_info, std::move(response_head)); + + if (request_info_->freeze_mode == LoaderFreezeMode::kNone) { + FollowPendingRedirect(request_info_.get()); } }
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.h index dacd41dd..e39419af 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.h +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender.h
@@ -198,6 +198,13 @@ resource_load_info_notifier_wrapper; }; + // Called as a callback for ResourceRequestClient::OnReceivedRedirect(). + void OnFollowRedirectCallback( + const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr response_head, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + std::vector<std::string> removed_headers); + // Follows redirect, if any, for the given request. void FollowPendingRedirect(PendingRequestInfo* request_info);
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender_unittest.cc index 3a29e75..f9514bf 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender_unittest.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_sender_unittest.cc
@@ -15,10 +15,18 @@ #include "base/feature_list.h" #include "base/run_loop.h" +#include "base/synchronization/waitable_event.h" +#include "base/task/thread_pool.h" +#include "base/test/bind.h" #include "base/test/task_environment.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "mojo/public/cpp/system/data_pipe_utils.h" +#include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/base/request_priority.h" #include "net/http/http_response_headers.h" @@ -28,6 +36,7 @@ #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/loader/referrer_utils.h" @@ -36,14 +45,21 @@ #include "third_party/blink/public/platform/web_url_request_extra_data.h" #include "third_party/blink/public/platform/web_url_request_util.h" #include "third_party/blink/renderer/platform/loader/fetch/url_loader/resource_request_client.h" +#include "third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_response.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" +#include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "url/gurl.h" namespace blink { namespace { +using RefCountedURLLoaderClientRemote = + base::RefCountedData<mojo::Remote<network::mojom::URLLoaderClient>>; + static constexpr char kTestPageUrl[] = "http://www.google.com/"; +static constexpr char kRedirectedUrl[] = "http://redirected.example.com/"; +static constexpr char kTestData[] = "Hello world"; constexpr size_t kDataPipeCapacity = 4096; @@ -63,7 +79,46 @@ return base::TimeTicks() + base::Microseconds(micros); } -} // namespace +std::unique_ptr<network::ResourceRequest> CreateResourceRequest() { + std::unique_ptr<network::ResourceRequest> request( + new network::ResourceRequest()); + + request->method = "GET"; + request->url = GURL(kTestPageUrl); + request->site_for_cookies = net::SiteForCookies::FromUrl(GURL(kTestPageUrl)); + request->referrer_policy = ReferrerUtils::GetDefaultNetReferrerPolicy(); + request->resource_type = static_cast<int>(mojom::ResourceType::kSubResource); + request->priority = net::LOW; + request->mode = network::mojom::RequestMode::kNoCors; + + auto url_request_extra_data = base::MakeRefCounted<WebURLRequestExtraData>(); + url_request_extra_data->CopyToResourceRequest(request.get()); + + return request; +} + +std::unique_ptr<network::ResourceRequest> CreateSyncResourceRequest() { + auto request = CreateResourceRequest(); + request->load_flags = net::LOAD_IGNORE_LIMITS; + return request; +} + +mojo::ScopedDataPipeConsumerHandle CreateDataPipeConsumerHandleFilledWithString( + const std::string& string) { + mojo::ScopedDataPipeProducerHandle producer_handle; + mojo::ScopedDataPipeConsumerHandle consumer_handle; + CHECK_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle), + MOJO_RESULT_OK); + CHECK(mojo::BlockingCopyFromString(string, producer_handle)); + return consumer_handle; +} + +class TestPlatformForRedirects final : public TestingPlatformSupport { + public: + bool IsRedirectSafe(const GURL& from_url, const GURL& to_url) override { + return true; + } +}; // A mock ResourceRequestClient to receive messages from the // ResourceRequestSender. @@ -73,11 +128,15 @@ // ResourceRequestClient overrides: void OnUploadProgress(uint64_t position, uint64_t size) override {} - bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, - network::mojom::URLResponseHeadPtr head, - std::vector<std::string>* removed_headers) override { + void OnReceivedRedirect( + const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + FollowRedirectCallback follow_redirect_callback) override { last_load_timing_ = head->load_timing; - return true; + CHECK(on_received_redirect_callback_); + std::move(on_received_redirect_callback_) + .Run(redirect_info, std::move(head), + std::move(follow_redirect_callback)); } void OnReceivedResponse(network::mojom::URLResponseHeadPtr head, base::TimeTicks response_arrival) override { @@ -108,6 +167,13 @@ return completion_status_; } + void SetOnReceivedRedirectCallback( + base::OnceCallback<void(const net::RedirectInfo&, + network::mojom::URLResponseHeadPtr, + FollowRedirectCallback)> callback) { + on_received_redirect_callback_ = std::move(callback); + } + private: // Data received. If downloading to file, remains empty. std::string data_; @@ -116,7 +182,43 @@ bool complete_ = false; net::LoadTimingInfo last_load_timing_; network::URLLoaderCompletionStatus completion_status_; -}; // namespace blink + base::OnceCallback<void(const net::RedirectInfo&, + network::mojom::URLResponseHeadPtr, + FollowRedirectCallback)> + on_received_redirect_callback_; +}; + +class MockLoader : public network::mojom::URLLoader { + public: + using RepeatingFollowRedirectCallback = base::RepeatingCallback<void( + const std::vector<std::string>& removed_headers)>; + MockLoader() = default; + MockLoader(const MockLoader&) = delete; + MockLoader& operator=(const MockLoader&) = delete; + ~MockLoader() override = default; + + // network::mojom::URLLoader implementation: + void FollowRedirect( + const std::vector<std::string>& removed_headers, + const net::HttpRequestHeaders& modified_headers, + const net::HttpRequestHeaders& modified_cors_exempt_headers, + const absl::optional<GURL>& new_url) override { + if (follow_redirect_callback_) { + follow_redirect_callback_.Run(removed_headers); + } + } + void SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) override {} + void PauseReadingBodyFromNet() override {} + void ResumeReadingBodyFromNet() override {} + + void SetFollowRedirectCallback(RepeatingFollowRedirectCallback callback) { + follow_redirect_callback_ = std::move(callback); + } + + private: + RepeatingFollowRedirectCallback follow_redirect_callback_; +}; // Sets up the message sender override for the unit test. class ResourceRequestSenderTest : public testing::Test, @@ -145,27 +247,6 @@ NOTREACHED(); } - std::unique_ptr<network::ResourceRequest> CreateResourceRequest() { - std::unique_ptr<network::ResourceRequest> request( - new network::ResourceRequest()); - - request->method = "GET"; - request->url = GURL(kTestPageUrl); - request->site_for_cookies = - net::SiteForCookies::FromUrl(GURL(kTestPageUrl)); - request->referrer_policy = ReferrerUtils::GetDefaultNetReferrerPolicy(); - request->resource_type = - static_cast<int>(mojom::ResourceType::kSubResource); - request->priority = net::LOW; - request->mode = network::mojom::RequestMode::kNoCors; - - auto url_request_extra_data = - base::MakeRefCounted<WebURLRequestExtraData>(); - url_request_extra_data->CopyToResourceRequest(request.get()); - - return request; - } - ResourceRequestSender* sender() { return resource_request_sender_.get(); } void StartAsync(std::unique_ptr<network::ResourceRequest> request, @@ -186,10 +267,12 @@ mojo::PendingRemote<network::mojom::URLLoaderClient>>> loader_and_clients_; base::test::SingleThreadTaskEnvironment task_environment_; - ScopedTestingPlatformSupport<TestingPlatformSupport> platform_; std::unique_ptr<ResourceRequestSender> resource_request_sender_; scoped_refptr<MockRequestClient> mock_client_; + + private: + ScopedTestingPlatformSupport<TestPlatformForRedirects> platform_; }; // Tests the generation of unique request ids. @@ -202,6 +285,560 @@ EXPECT_GE(first_id, 0); } +TEST_F(ResourceRequestSenderTest, RedirectSyncFollow) { + mock_client_ = base::MakeRefCounted<MockRequestClient>(); + StartAsync(CreateResourceRequest(), mock_client_); + ASSERT_EQ(1u, loader_and_clients_.size()); + mojo::Remote<network::mojom::URLLoaderClient> client( + std::move(loader_and_clients_[0].second)); + std::unique_ptr<MockLoader> mock_loader = std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), + std::move(loader_and_clients_[0].first)); + + base::RunLoop run_loop_for_redirect; + mock_loader_prt->SetFollowRedirectCallback(base::BindLambdaForTesting( + [&](const std::vector<std::string>& removed_headers) { + // network::mojom::URLLoader::FollowRedirect() must be called with an + // empty `removed_headers`. + EXPECT_TRUE(removed_headers.empty()); + run_loop_for_redirect.Quit(); + })); + + mock_client_->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + EXPECT_EQ(GURL(kRedirectedUrl), redirect_info.new_url); + // Synchronously call `callback` with an empty `removed_headers`. + std::move(callback).Run({}); + })); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + client->OnReceiveRedirect(redirect_info, + network::mojom::URLResponseHead::New()); + run_loop_for_redirect.Run(); + client->OnReceiveResponse(network::mojom::URLResponseHead::New(), + mojo::ScopedDataPipeConsumerHandle(), + absl::nullopt); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(mock_client_->received_response()); +} + +TEST_F(ResourceRequestSenderTest, RedirectSyncFollowWithRemovedHeaders) { + mock_client_ = base::MakeRefCounted<MockRequestClient>(); + StartAsync(CreateResourceRequest(), mock_client_); + ASSERT_EQ(1u, loader_and_clients_.size()); + mojo::Remote<network::mojom::URLLoaderClient> client( + std::move(loader_and_clients_[0].second)); + + std::unique_ptr<MockLoader> mock_loader = std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), + std::move(loader_and_clients_[0].first)); + + base::RunLoop run_loop_for_redirect; + mock_loader_prt->SetFollowRedirectCallback(base::BindLambdaForTesting( + [&](const std::vector<std::string>& removed_headers) { + // network::mojom::URLLoader::FollowRedirect() must be called with a + // non-empty `removed_headers`. + EXPECT_THAT(removed_headers, + ::testing::ElementsAreArray({"Foo-Bar", "Hoge-Piyo"})); + run_loop_for_redirect.Quit(); + })); + + mock_client_->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + EXPECT_EQ(GURL(kRedirectedUrl), redirect_info.new_url); + // Synchronously call `callback` with a non-empty `removed_headers`. + std::move(callback).Run({"Foo-Bar", "Hoge-Piyo"}); + })); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + client->OnReceiveRedirect(redirect_info, + network::mojom::URLResponseHead::New()); + run_loop_for_redirect.Run(); + client->OnReceiveResponse(network::mojom::URLResponseHead::New(), + mojo::ScopedDataPipeConsumerHandle(), + absl::nullopt); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(mock_client_->received_response()); +} + +TEST_F(ResourceRequestSenderTest, RedirectSyncCancel) { + mock_client_ = base::MakeRefCounted<MockRequestClient>(); + StartAsync(CreateResourceRequest(), mock_client_); + ASSERT_EQ(1u, loader_and_clients_.size()); + mojo::Remote<network::mojom::URLLoaderClient> client( + std::move(loader_and_clients_[0].second)); + std::unique_ptr<MockLoader> mock_loader = std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), + std::move(loader_and_clients_[0].first)); + + mock_loader_prt->SetFollowRedirectCallback( + base::BindRepeating([](const std::vector<std::string>& removed_headers) { + // FollowRedirect() must not be called. + CHECK(false); + })); + + mock_client_->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + EXPECT_EQ(GURL(kRedirectedUrl), redirect_info.new_url); + // Synchronously cancels the request in the `OnReceivedRedirect()`. + sender()->Cancel(scheduler::GetSingleThreadTaskRunnerForTesting()); + })); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + client->OnReceiveRedirect(redirect_info, + network::mojom::URLResponseHead::New()); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(ResourceRequestSenderTest, RedirectAsyncFollow) { + mock_client_ = base::MakeRefCounted<MockRequestClient>(); + StartAsync(CreateResourceRequest(), mock_client_); + ASSERT_EQ(1u, loader_and_clients_.size()); + mojo::Remote<network::mojom::URLLoaderClient> client( + std::move(loader_and_clients_[0].second)); + std::unique_ptr<MockLoader> mock_loader = std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), + std::move(loader_and_clients_[0].first)); + + base::RunLoop run_loop_for_redirect; + mock_loader_prt->SetFollowRedirectCallback(base::BindLambdaForTesting( + [&](const std::vector<std::string>& removed_headers) { + // network::mojom::URLLoader::FollowRedirect() must be called with an + // empty `removed_headers`. + EXPECT_TRUE(removed_headers.empty()); + run_loop_for_redirect.Quit(); + })); + + absl::optional<net::RedirectInfo> received_redirect_info; + ResourceRequestClient::FollowRedirectCallback follow_redirect_callback; + mock_client_->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + received_redirect_info = redirect_info; + follow_redirect_callback = std::move(callback); + })); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + client->OnReceiveRedirect(redirect_info, + network::mojom::URLResponseHead::New()); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(received_redirect_info); + EXPECT_EQ(GURL(kRedirectedUrl), received_redirect_info->new_url); + // Asynchronously call `callback` with an empty `removed_headers`. + std::move(follow_redirect_callback).Run({}); + run_loop_for_redirect.Run(); + client->OnReceiveResponse(network::mojom::URLResponseHead::New(), + mojo::ScopedDataPipeConsumerHandle(), + absl::nullopt); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(mock_client_->received_response()); +} + +TEST_F(ResourceRequestSenderTest, RedirectAsyncFollowWithRemovedHeaders) { + mock_client_ = base::MakeRefCounted<MockRequestClient>(); + StartAsync(CreateResourceRequest(), mock_client_); + ASSERT_EQ(1u, loader_and_clients_.size()); + mojo::Remote<network::mojom::URLLoaderClient> client( + std::move(loader_and_clients_[0].second)); + std::unique_ptr<MockLoader> mock_loader = std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), + std::move(loader_and_clients_[0].first)); + + base::RunLoop run_loop_for_redirect; + mock_loader_prt->SetFollowRedirectCallback(base::BindLambdaForTesting( + [&](const std::vector<std::string>& removed_headers) { + // network::mojom::URLLoader::FollowRedirect() must be called with a + // non-empty `removed_headers`. + EXPECT_THAT(removed_headers, + ::testing::ElementsAreArray({"Foo-Bar", "Hoge-Piyo"})); + run_loop_for_redirect.Quit(); + })); + + absl::optional<net::RedirectInfo> received_redirect_info; + ResourceRequestClient::FollowRedirectCallback follow_redirect_callback; + mock_client_->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + received_redirect_info = redirect_info; + follow_redirect_callback = std::move(callback); + })); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + client->OnReceiveRedirect(redirect_info, + network::mojom::URLResponseHead::New()); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(received_redirect_info); + EXPECT_EQ(GURL(kRedirectedUrl), received_redirect_info->new_url); + + // Asynchronously call `callback` with a non-empty `removed_headers`. + std::move(follow_redirect_callback).Run({"Foo-Bar", "Hoge-Piyo"}); + run_loop_for_redirect.Run(); + client->OnReceiveResponse(network::mojom::URLResponseHead::New(), + mojo::ScopedDataPipeConsumerHandle(), + absl::nullopt); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(mock_client_->received_response()); +} + +TEST_F(ResourceRequestSenderTest, RedirectAsyncFollowAfterCancel) { + mock_client_ = base::MakeRefCounted<MockRequestClient>(); + StartAsync(CreateResourceRequest(), mock_client_); + ASSERT_EQ(1u, loader_and_clients_.size()); + mojo::Remote<network::mojom::URLLoaderClient> client( + std::move(loader_and_clients_[0].second)); + std::unique_ptr<MockLoader> mock_loader = std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), + std::move(loader_and_clients_[0].first)); + + mock_loader_prt->SetFollowRedirectCallback( + base::BindRepeating([](const std::vector<std::string>& removed_headers) { + // FollowRedirect() must not be called. + CHECK(false); + })); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + + absl::optional<net::RedirectInfo> received_redirect_info; + ResourceRequestClient::FollowRedirectCallback follow_redirect_callback; + mock_client_->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + received_redirect_info = redirect_info; + follow_redirect_callback = std::move(callback); + })); + client->OnReceiveRedirect(redirect_info, + network::mojom::URLResponseHead::New()); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(received_redirect_info); + EXPECT_EQ(redirect_info.new_url, received_redirect_info->new_url); + + // Aynchronously cancels the request. + sender()->Cancel(scheduler::GetSingleThreadTaskRunnerForTesting()); + std::move(follow_redirect_callback).Run({}); + base::RunLoop().RunUntilIdle(); +} + +class BackgroundThreadURLLoaderFactory + : public network::SharedURLLoaderFactory { + public: + using LoadStartCallback = base::OnceCallback<void( + mojo::PendingReceiver<network::mojom::URLLoader>, + mojo::PendingRemote<network::mojom::URLLoaderClient>)>; + + // This SharedURLLoaderFactory is cloned and passed to the background thread + // via PendingFactory. `load_start_callback` will be called in the background + // thread. + explicit BackgroundThreadURLLoaderFactory( + LoadStartCallback load_start_callback) + : load_start_callback_(std::move(load_start_callback)) {} + BackgroundThreadURLLoaderFactory(const BackgroundThreadURLLoaderFactory&) = + delete; + BackgroundThreadURLLoaderFactory& operator=( + const BackgroundThreadURLLoaderFactory&) = delete; + ~BackgroundThreadURLLoaderFactory() override = default; + + // network::SharedURLLoaderFactory: + void CreateLoaderAndStart( + mojo::PendingReceiver<network::mojom::URLLoader> loader, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& request, + mojo::PendingRemote<network::mojom::URLLoaderClient> client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) + override { + CHECK(load_start_callback_); + std::move(load_start_callback_).Run(std::move(loader), std::move(client)); + } + void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) + override { + // Pass |this| as the receiver context to make sure this object stays alive + // while it still has receivers. + receivers_.Add(this, std::move(receiver), this); + } + std::unique_ptr<network::PendingSharedURLLoaderFactory> Clone() override { + CHECK(load_start_callback_); + return std::make_unique<PendingFactory>(std::move(load_start_callback_)); + } + + private: + class PendingFactory : public network::PendingSharedURLLoaderFactory { + public: + explicit PendingFactory(LoadStartCallback load_start_callback) + : load_start_callback_(std::move(load_start_callback)) {} + PendingFactory(const PendingFactory&) = delete; + PendingFactory& operator=(const PendingFactory&) = delete; + ~PendingFactory() override = default; + + protected: + scoped_refptr<network::SharedURLLoaderFactory> CreateFactory() override { + CHECK(load_start_callback_); + return base::MakeRefCounted<BackgroundThreadURLLoaderFactory>( + std::move(load_start_callback_)); + } + + private: + LoadStartCallback load_start_callback_; + }; + + mojo::ReceiverSet<network::mojom::URLLoaderFactory, + scoped_refptr<BackgroundThreadURLLoaderFactory>> + receivers_; + LoadStartCallback load_start_callback_; +}; + +class ResourceRequestSenderSyncTest : public testing::Test { + public: + explicit ResourceRequestSenderSyncTest() = default; + ResourceRequestSenderSyncTest(const ResourceRequestSenderSyncTest&) = delete; + ResourceRequestSenderSyncTest& operator=( + const ResourceRequestSenderSyncTest&) = delete; + ~ResourceRequestSenderSyncTest() override = default; + + protected: + SyncLoadResponse SendSync( + scoped_refptr<ResourceRequestClient> client, + scoped_refptr<network::SharedURLLoaderFactory> loader_factory) { + base::WaitableEvent terminate_sync_load_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + SyncLoadResponse response; + auto sender = std::make_unique<ResourceRequestSender>(); + sender->SendSync(CreateSyncResourceRequest(), TRAFFIC_ANNOTATION_FOR_TESTS, + network::mojom::kURLLoadOptionSynchronous, &response, + std::move(loader_factory), + /*throttles=*/{}, + /*timeout=*/base::Seconds(100), + /*cors_exempt_header_list*/ {}, &terminate_sync_load_event, + /*download_to_blob_registry=*/ + mojo::PendingRemote<mojom::blink::BlobRegistry>(), client, + std::make_unique<ResourceLoadInfoNotifierWrapper>( + /*resource_load_info_notifier=*/nullptr)); + return response; + } + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + private: + ScopedTestingPlatformSupport<TestPlatformForRedirects> platform_; +}; + +TEST_F(ResourceRequestSenderSyncTest, SendSyncRequest) { + scoped_refptr<MockRequestClient> mock_client = + base::MakeRefCounted<MockRequestClient>(); + auto loader_factory = + base::MakeRefCounted<BackgroundThreadURLLoaderFactory>(base::BindOnce( + [](mojo::PendingReceiver<network::mojom::URLLoader> loader, + mojo::PendingRemote<network::mojom::URLLoaderClient> client) { + mojo::MakeSelfOwnedReceiver(std::make_unique<MockLoader>(), + std::move(loader)); + mojo::Remote<network::mojom::URLLoaderClient> loader_client( + std::move(client)); + loader_client->OnReceiveResponse( + network::mojom::URLResponseHead::New(), + CreateDataPipeConsumerHandleFilledWithString(kTestData), + absl::nullopt); + loader_client->OnComplete( + network::URLLoaderCompletionStatus(net::Error::OK)); + })); + SyncLoadResponse response = SendSync(mock_client, std::move(loader_factory)); + EXPECT_EQ(net::OK, response.error_code); + ASSERT_TRUE(response.data); + EXPECT_EQ(kTestData, + std::string(response.data->begin()->data(), response.data->size())); +} + +TEST_F(ResourceRequestSenderSyncTest, SendSyncRedirect) { + scoped_refptr<MockRequestClient> mock_client = + base::MakeRefCounted<MockRequestClient>(); + mock_client->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + EXPECT_EQ(GURL(kRedirectedUrl), redirect_info.new_url); + // Synchronously call `callback` with an empty `removed_headers`. + std::move(callback).Run({}); + })); + + auto loader_factory = base::MakeRefCounted<BackgroundThreadURLLoaderFactory>( + base::BindOnce([](mojo::PendingReceiver<network::mojom::URLLoader> loader, + mojo::PendingRemote<network::mojom::URLLoaderClient> + client) { + std::unique_ptr<MockLoader> mock_loader = + std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), std::move(loader)); + + mojo::Remote<network::mojom::URLLoaderClient> loader_client( + std::move(client)); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + loader_client->OnReceiveRedirect( + redirect_info, network::mojom::URLResponseHead::New()); + + scoped_refptr<RefCountedURLLoaderClientRemote> refcounted_client = + base::MakeRefCounted<RefCountedURLLoaderClientRemote>( + std::move(loader_client)); + + mock_loader_prt->SetFollowRedirectCallback(base::BindRepeating( + [](scoped_refptr<RefCountedURLLoaderClientRemote> refcounted_client, + const std::vector<std::string>& removed_headers) { + // network::mojom::URLLoader::FollowRedirect() must be called with + // an empty `removed_headers`. + EXPECT_TRUE(removed_headers.empty()); + + // After FollowRedirect() is called, calls + // URLLoaderClient::OnReceiveResponse() and + // URLLoaderClient::OnComplete() + refcounted_client->data->OnReceiveResponse( + network::mojom::URLResponseHead::New(), + CreateDataPipeConsumerHandleFilledWithString(kTestData), + absl::nullopt); + + refcounted_client->data->OnComplete( + network::URLLoaderCompletionStatus(net::Error::OK)); + }, + std::move(refcounted_client))); + })); + + SyncLoadResponse response = SendSync(mock_client, std::move(loader_factory)); + EXPECT_EQ(net::OK, response.error_code); + ASSERT_TRUE(response.data); + EXPECT_EQ(kTestData, + std::string(response.data->begin()->data(), response.data->size())); +} + +TEST_F(ResourceRequestSenderSyncTest, SendSyncRedirectWithRemovedHeaders) { + scoped_refptr<MockRequestClient> mock_client = + base::MakeRefCounted<MockRequestClient>(); + mock_client->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + EXPECT_EQ(GURL(kRedirectedUrl), redirect_info.new_url); + // network::mojom::URLLoader::FollowRedirect() must be called with a + // non-empty `removed_headers`. + std::move(callback).Run({"Foo-Bar", "Hoge-Piyo"}); + })); + + auto loader_factory = base::MakeRefCounted<BackgroundThreadURLLoaderFactory>( + base::BindOnce([](mojo::PendingReceiver<network::mojom::URLLoader> loader, + mojo::PendingRemote<network::mojom::URLLoaderClient> + client) { + std::unique_ptr<MockLoader> mock_loader = + std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), std::move(loader)); + + mojo::Remote<network::mojom::URLLoaderClient> loader_client( + std::move(client)); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + loader_client->OnReceiveRedirect( + redirect_info, network::mojom::URLResponseHead::New()); + + scoped_refptr<RefCountedURLLoaderClientRemote> refcounted_client = + base::MakeRefCounted<RefCountedURLLoaderClientRemote>( + std::move(loader_client)); + + mock_loader_prt->SetFollowRedirectCallback(base::BindRepeating( + [](scoped_refptr<RefCountedURLLoaderClientRemote> refcounted_client, + const std::vector<std::string>& removed_headers) { + // Synchronously call `callback` with a non-empty + // `removed_headers`. + EXPECT_THAT(removed_headers, ::testing::ElementsAreArray( + {"Foo-Bar", "Hoge-Piyo"})); + + // After FollowRedirect() is called, calls + // URLLoaderClient::OnReceiveResponse() and + // URLLoaderClient::OnComplete() + refcounted_client->data->OnReceiveResponse( + network::mojom::URLResponseHead::New(), + CreateDataPipeConsumerHandleFilledWithString(kTestData), + absl::nullopt); + refcounted_client->data->OnComplete( + network::URLLoaderCompletionStatus(net::Error::OK)); + }, + std::move(refcounted_client))); + })); + + SyncLoadResponse response = SendSync(mock_client, std::move(loader_factory)); + EXPECT_EQ(net::OK, response.error_code); + ASSERT_TRUE(response.data); + EXPECT_EQ(kTestData, + std::string(response.data->begin()->data(), response.data->size())); +} + +TEST_F(ResourceRequestSenderSyncTest, SendSyncRedirectCancel) { + scoped_refptr<MockRequestClient> mock_client = + base::MakeRefCounted<MockRequestClient>(); + mock_client->SetOnReceivedRedirectCallback(base::BindLambdaForTesting( + [&](const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + ResourceRequestClient::FollowRedirectCallback callback) { + EXPECT_EQ(GURL(kRedirectedUrl), redirect_info.new_url); + // Don't call callback to cancel the request. + })); + + auto loader_factory = + base::MakeRefCounted<BackgroundThreadURLLoaderFactory>(base::BindOnce( + [](mojo::PendingReceiver<network::mojom::URLLoader> loader, + mojo::PendingRemote<network::mojom::URLLoaderClient> client) { + std::unique_ptr<MockLoader> mock_loader = + std::make_unique<MockLoader>(); + MockLoader* mock_loader_prt = mock_loader.get(); + mojo::MakeSelfOwnedReceiver(std::move(mock_loader), + std::move(loader)); + + mojo::Remote<network::mojom::URLLoaderClient> loader_client( + std::move(client)); + + net::RedirectInfo redirect_info; + redirect_info.new_url = GURL(kRedirectedUrl); + loader_client->OnReceiveRedirect( + redirect_info, network::mojom::URLResponseHead::New()); + + scoped_refptr<RefCountedURLLoaderClientRemote> refcounted_client = + base::MakeRefCounted<RefCountedURLLoaderClientRemote>( + std::move(loader_client)); + + mock_loader_prt->SetFollowRedirectCallback(base::BindRepeating( + [](scoped_refptr<base::RefCountedData<mojo::Remote< + network::mojom::URLLoaderClient>>> refcounted_client, + const std::vector<std::string>& removed_headers) { + // FollowRedirect() must not be called. + CHECK(false); + }, + std::move(refcounted_client))); + })); + + SyncLoadResponse response = SendSync(mock_client, std::move(loader_factory)); + EXPECT_EQ(net::ERR_ABORTED, response.error_code); + EXPECT_FALSE(response.data); +} + class TimeConversionTest : public ResourceRequestSenderTest { public: void PerformTest(network::mojom::URLResponseHeadPtr response_head) { @@ -349,4 +986,5 @@ EXPECT_EQ(completion_time(), request_start() + base::Milliseconds(3)); } +} // namespace } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc index c4f3adb..e38edc3 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.cc
@@ -165,10 +165,10 @@ void SyncLoadContext::OnUploadProgress(uint64_t position, uint64_t size) {} -bool SyncLoadContext::OnReceivedRedirect( +void SyncLoadContext::OnReceivedRedirect( const net::RedirectInfo& redirect_info, network::mojom::URLResponseHeadPtr head, - std::vector<std::string>* removed_headers) { + FollowRedirectCallback follow_redirect_callback) { DCHECK(!Completed()); if (has_authorization_header_ && @@ -176,32 +176,17 @@ response_->has_authorization_header_between_cross_origin_redirect_ = true; } - // TODO(https://crbug.com/471397, https://crbug.com/1406737): Reconsider - // the placement of this code, together with the //net counterpart. - if (removed_headers) { - // Step 13 of https://fetch.spec.whatwg.org/#http-redirect-fetch - if (base::FeatureList::IsEnabled( - features::kRemoveAuthroizationOnCrossOriginRedirect) && - !url::Origin::Create(response_->url) - .IsSameOriginWith(redirect_info.new_url)) { - removed_headers->push_back(net::HttpRequestHeaders::kAuthorization); - } - // TODO(yoav): Get the actual PermissionsPolicy here to support selective - // removal for sync XHR. - FindClientHintsToRemove(nullptr /* permissions_policy */, - redirect_info.new_url, removed_headers); - } - response_->url = redirect_info.new_url; response_->head = std::move(head); response_->redirect_info = redirect_info; *context_for_redirect_ = this; - resource_request_sender_->Freeze(LoaderFreezeMode::kStrict); + + follow_redirect_callback_ = std::move(follow_redirect_callback); signals_->SignalRedirectOrResponseComplete(); - return true; } -void SyncLoadContext::FollowRedirect() { +void SyncLoadContext::FollowRedirect(std::vector<std::string> removed_headers) { + CHECK(follow_redirect_callback_); if (!signals_->RestartAfterRedirect()) { CancelRedirect(); return; @@ -209,8 +194,7 @@ response_->redirect_info = net::RedirectInfo(); *context_for_redirect_ = nullptr; - - resource_request_sender_->Freeze(LoaderFreezeMode::kNone); + std::move(follow_redirect_callback_).Run(std::move(removed_headers)); } void SyncLoadContext::CancelRedirect() {
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.h index 91a6d40..101bcc8 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.h +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/sync_load_context.h
@@ -77,7 +77,7 @@ SyncLoadContext& operator=(const SyncLoadContext&) = delete; ~SyncLoadContext() override; - void FollowRedirect(); + void FollowRedirect(std::vector<std::string> removed_headers); void CancelRedirect(); private: @@ -96,9 +96,10 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner); // ResourceRequestClient implementation: void OnUploadProgress(uint64_t position, uint64_t size) override; - bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, - network::mojom::URLResponseHeadPtr head, - std::vector<std::string>*) override; + void OnReceivedRedirect( + const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + FollowRedirectCallback follow_redirect_callback) override; void OnReceivedResponse( network::mojom::URLResponseHeadPtr head, base::TimeTicks response_arrival_at_renderer) override; @@ -122,6 +123,10 @@ // Set to null after CompleteRequest() is called. SyncLoadResponse* response_; + // Used when handling a redirect. It is set in OnReceivedRedirect(), and + // called when FollowRedirect() is called from the original thread. + FollowRedirectCallback follow_redirect_callback_; + // This raw pointer will be set to `this` when receiving redirects on // independent thread and set to nullptr in `FollowRedirect()` or // `CancelRedirect()` on the same thread after `redirect_or_response_event_`
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader.cc index d3ff2ec..63a7a6e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader.cc
@@ -134,9 +134,10 @@ // ResourceRequestClient overrides: void OnUploadProgress(uint64_t position, uint64_t size) override; - bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, - network::mojom::URLResponseHeadPtr head, - std::vector<std::string>* removed_headers) override; + void OnReceivedRedirect( + const net::RedirectInfo& redirect_info, + network::mojom::URLResponseHeadPtr head, + FollowRedirectCallback follow_redirect_callback) override; void OnReceivedResponse( network::mojom::URLResponseHeadPtr head, base::TimeTicks response_arrival_at_renderer) override; @@ -346,12 +347,12 @@ } } -bool URLLoader::Context::OnReceivedRedirect( +void URLLoader::Context::OnReceivedRedirect( const net::RedirectInfo& redirect_info, network::mojom::URLResponseHeadPtr head, - std::vector<std::string>* removed_headers) { + FollowRedirectCallback follow_redirect_callback) { if (!client_) { - return false; + return; } TRACE_EVENT_WITH_FLOW0("loading", "URLLoader::Context::OnReceivedRedirect", @@ -362,13 +363,17 @@ url_, *head, has_devtools_request_id_, request_id_); url_ = KURL(redirect_info.new_url); - return client_->WillFollowRedirect( - url_, redirect_info.new_site_for_cookies, - WebString::FromUTF8(redirect_info.new_referrer), - ReferrerUtils::NetToMojoReferrerPolicy(redirect_info.new_referrer_policy), - WebString::FromUTF8(redirect_info.new_method), response, - has_devtools_request_id_, removed_headers, - redirect_info.insecure_scheme_was_upgraded); + std::vector<std::string> removed_headers; + if (client_->WillFollowRedirect( + url_, redirect_info.new_site_for_cookies, + WebString::FromUTF8(redirect_info.new_referrer), + ReferrerUtils::NetToMojoReferrerPolicy( + redirect_info.new_referrer_policy), + WebString::FromUTF8(redirect_info.new_method), response, + has_devtools_request_id_, &removed_headers, + redirect_info.insecure_scheme_was_upgraded)) { + std::move(follow_redirect_callback).Run(std::move(removed_headers)); + } } void URLLoader::Context::OnReceivedResponse(
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_unittest.cc index 3f206406..067563d8 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_unittest.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_unittest.cc
@@ -54,6 +54,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader.h" #include "third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_client.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "url/gurl.h" #include "url/origin.h" @@ -62,7 +63,6 @@ namespace { const char kTestURL[] = "http://foo"; -const char kTestHTTPSURL[] = "https://foo"; const char kTestData[] = "blah!"; class MockResourceRequestSender : public ResourceRequestSender { @@ -345,22 +345,17 @@ redirect_info.new_site_for_cookies = net::SiteForCookies::FromUrl(GURL(kTestURL)); std::vector<std::string> removed_headers; + bool callback_called = false; resource_request_client()->OnReceivedRedirect( redirect_info, network::mojom::URLResponseHead::New(), - &removed_headers); - EXPECT_TRUE(client()->did_receive_redirect()); - } - - void DoReceiveHTTPSRedirect() { - EXPECT_FALSE(client()->did_receive_redirect()); - net::RedirectInfo redirect_info; - redirect_info.status_code = 302; - redirect_info.new_method = "GET"; - redirect_info.new_url = GURL(kTestHTTPSURL); - redirect_info.new_site_for_cookies = - net::SiteForCookies::FromUrl(GURL(kTestHTTPSURL)); - resource_request_client()->OnReceivedRedirect( - redirect_info, network::mojom::URLResponseHead::New(), nullptr); + /*follow_redirect_callback=*/ + WTF::BindOnce( + [](bool* callback_called, + std::vector<std::string> removed_headers) { + *callback_called = true; + }, + WTF::Unretained(&callback_called))); + DCHECK(callback_called); EXPECT_TRUE(client()->did_receive_redirect()); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index ddf4d65..54bdd442 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -752,7 +752,7 @@ base_feature: "none", }, { - name: "CookieDeprecationFacilitatedTestingLabels", + name: "CookieDeprecationFacilitatedTesting", base_feature: "none", }, {
diff --git a/third_party/blink/renderer/platform/testing/font_test_helpers.cc b/third_party/blink/renderer/platform/testing/font_test_helpers.cc index 4e0d48b8..1b86fef 100644 --- a/third_party/blink/renderer/platform/testing/font_test_helpers.cc +++ b/third_party/blink/renderer/platform/testing/font_test_helpers.cc
@@ -46,9 +46,9 @@ scoped_refptr<FontData> GetFontData(const FontDescription& font_description, const FontFamily&) override { FontSelectionCapabilities normal_capabilities( - {NormalWidthValue(), NormalWidthValue()}, - {NormalSlopeValue(), NormalSlopeValue()}, - {NormalWeightValue(), NormalWeightValue()}); + {kNormalWidthValue, kNormalWidthValue}, + {kNormalSlopeValue, kNormalSlopeValue}, + {kNormalWeightValue, kNormalWeightValue}); FontPlatformData platform_data = custom_platform_data_->GetFontPlatformData( font_description.EffectiveFontSize(), font_description.AdjustedSpecifiedSize(),
diff --git a/third_party/blink/renderer/platform/wtf/math_extras.h b/third_party/blink/renderer/platform/wtf/math_extras.h index 4a10c97..8aec51dc 100644 --- a/third_party/blink/renderer/platform/wtf/math_extras.h +++ b/third_party/blink/renderer/platform/wtf/math_extras.h
@@ -145,9 +145,9 @@ // (2) The default type promotions/conversions are sufficient to handle things // correctly template <typename LimitType, typename ValueType> -inline LimitType ClampToDirectComparison(ValueType value, - LimitType min, - LimitType max) { +inline constexpr LimitType ClampToDirectComparison(ValueType value, + LimitType min, + LimitType max) { if (value >= max) return max; return (value <= min) ? min : static_cast<LimitType>(value); @@ -175,9 +175,9 @@ STATIC_ONLY(ClampToNonLongLongHelper); public: - static inline LimitType ClampTo(ValueType value, - LimitType min, - LimitType max) { + static inline constexpr LimitType ClampTo(ValueType value, + LimitType min, + LimitType max) { return ClampToDirectComparison(value, min, max); } }; @@ -187,9 +187,9 @@ STATIC_ONLY(ClampToNonLongLongHelper); public: - static inline LimitType ClampTo(ValueType value, - LimitType min, - LimitType max) { + static inline constexpr LimitType ClampTo(ValueType value, + LimitType min, + LimitType max) { const double double_value = static_cast<double>(value); if (double_value >= static_cast<double>(max)) return max; @@ -209,9 +209,9 @@ template <typename LimitType, typename ValueType> class ClampToHelper { public: - static inline LimitType ClampTo(ValueType value, - LimitType min, - LimitType max) { + static inline constexpr LimitType ClampTo(ValueType value, + LimitType min, + LimitType max) { // We only use ClampToDirectComparison() when the integerness and // signedness of the two types matches. // @@ -313,7 +313,9 @@ ValueType value, LimitType min = DefaultMinimumForClamp<LimitType>(), LimitType max = DefaultMaximumForClamp<LimitType>()) { - DCHECK(!std::isnan(static_cast<double>(value))); + // We use __builtin_isnan instead of std::isnan here because std::isnan + // is not constexpr prior to C++23. + DCHECK(!__builtin_isnan(static_cast<double>(value))); DCHECK_LE(min, max); // This also ensures |min| and |max| aren't NaN. return ClampToHelper<LimitType, ValueType>::ClampTo(value, min, max); }
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py index f204943d..f03c926 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
@@ -190,7 +190,14 @@ @memoized def all_urls(self): """Returns a set of the URLs for all items in the manifest.""" - return frozenset(self.all_url_items().keys()) + urls_with_nonempty_paths = [] + for url in self.all_url_items().keys(): + assert not url.startswith('/') + assert not url.endswith('/') + # Drop empty path components. + url = url.replace('//', '/') + urls_with_nonempty_paths.append(url) + return frozenset(urls_with_nonempty_paths) def is_test_file(self, path_in_wpt): """Checks if path_in_wpt is a test file according to the manifest."""
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink.py b/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink.py index fcaf6d08..470dc93d 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink.py
@@ -121,6 +121,13 @@ # https://chromium.googlesource.com/infra/luci/luci-go/+/master/resultdb/proto/type/common.proto#56 pair = lambda k, v: {'key': k, 'value': v} + # According to //third_party/blink/web_tests/SlowTests, a test is + # considered slow if it is slower than ~30% of its timeout since test + # times can vary by up to 3x. + portion_of_timeout = result.total_run_time / (self._port.timeout_ms() / + 1000) + test_was_slow = portion_of_timeout > 0.3 + tags = [ pair('test_name', result.test_name), pair('web_tests_device_failed', str(result.device_failed)), @@ -129,6 +136,7 @@ self._port.flag_specific_config_name() or ''), pair('web_tests_base_timeout', str(int(self._port.timeout_ms() / 1000))), + pair('web_tests_test_was_slow', json.dumps(test_was_slow)), ] # The hash allows `rebaseline-cl` to determine whether baselines are
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink_unittest.py b/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink_unittest.py index a6c5604..68d68993 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/test_result_sink_unittest.py
@@ -133,7 +133,11 @@ }, { 'key': 'web_tests_base_timeout', - 'value': '6' + 'value': '6', + }, + { + 'key': 'web_tests_test_was_slow', + 'value': 'false', }, { 'key': 'web_tests_used_expectations_file', @@ -189,7 +193,60 @@ }, { 'key': 'web_tests_base_timeout', - 'value': '6' + 'value': '6', + }, + { + 'key': 'web_tests_test_was_slow', + 'value': 'false', + }, + { + 'key': 'web_tests_used_expectations_file', + 'value': 'TestExpectations', + }, + { + 'key': 'web_tests_used_expectations_file', + 'value': 'NeverFixTests', + }, + { + 'key': 'web_tests_used_expectations_file', + 'value': 'StaleTestExpectations', + }, + { + 'key': 'web_tests_used_expectations_file', + 'value': 'SlowTests', + }, + ] + sent_data = self.sink(True, tr) + self.assertEqual(sent_data['tags'], expected_tags) + + def test_sink_with_long_duration(self): + tr = test_results.TestResult(test_name='test-name') + tr.total_run_time = 2 + tr.type = ResultType.Crash + expected_tags = [ + { + 'key': 'test_name', + 'value': 'test-name' + }, + { + 'key': 'web_tests_device_failed', + 'value': 'False' + }, + { + 'key': 'web_tests_result_type', + 'value': 'CRASH' + }, + { + 'key': 'web_tests_flag_specific_config_name', + 'value': '', + }, + { + 'key': 'web_tests_base_timeout', + 'value': '6', + }, + { + 'key': 'web_tests_test_was_slow', + 'value': 'true', }, { 'key': 'web_tests_used_expectations_file', @@ -239,7 +296,11 @@ }, { 'key': 'web_tests_base_timeout', - 'value': '6' + 'value': '6', + }, + { + 'key': 'web_tests_test_was_slow', + 'value': 'false', }, { 'key': 'web_tests_actual_image_hash', @@ -297,7 +358,11 @@ }, { 'key': 'web_tests_base_timeout', - 'value': '6' + 'value': '6', + }, + { + 'key': 'web_tests_test_was_slow', + 'value': 'false', }, { 'key': 'web_tests_test_type',
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py index 1445447..ff6817a 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
@@ -408,10 +408,12 @@ base_test, test)) return exp + @memoized def get_expectations(self, test): return self._get_expectations_with_fallback(self._flag_expectations, self._expectations, test) + @memoized def get_flag_expectations(self, test): exp = self._get_expectations_with_fallback(self._flag_expectations, [], test) @@ -419,6 +421,7 @@ return None return exp + @memoized def get_base_expectations(self, test): return self._get_expectations_with_fallback(self._base_expectations, [], test)
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py index bca41fc69..7ce9106b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -1372,6 +1372,7 @@ return ('', test_name) return (test_name[0:index], test_name[index:]) + @memoized def normalize_test_name(self, test_name): """Returns a normalized version of the test name or test directory.""" if test_name.endswith('/'): @@ -1525,11 +1526,11 @@ # For a virtual test, if the base test is in exclusive_tests of the # test's own virtual suite, then we should not skip the test. virtual_suite = self._lookup_virtual_suite(test) - for entry in virtual_suite.exclusive_tests: - normalized_entry = self.normalize_test_name(entry) - if base_test.startswith(normalized_entry): + for exclusive_test in self._normalized_exclusive_tests( + virtual_suite): + if base_test.startswith(exclusive_test): return False - if normalized_entry.startswith(base_test): + if exclusive_test.startswith(base_test): # This means base_test is a directory containing exclusive # tests, so should not skip the directory. return False @@ -1539,13 +1540,26 @@ # For a non-virtual test or a virtual test not listed in exclusive_tests # of the test's own virtual suite, we should skip the test if the base # test is in exclusive_tests of any virtual suite. - for suite in self.virtual_test_suites(): - for entry in suite.exclusive_tests: - if base_test.startswith(self.normalize_test_name(entry)): - return True + for exclusive_test in self._all_normalized_exclusive_tests(): + if base_test.startswith(exclusive_test): + return True return False @memoized + def _all_normalized_exclusive_tests(self): + tests = set() + for suite in self.virtual_test_suites(): + tests.update(self._normalized_exclusive_tests(suite)) + return tests + + @memoized + def _normalized_exclusive_tests(self, virtual_suite): + tests = set() + for exclusive_test in virtual_suite.exclusive_tests: + tests.add(self.normalize_test_name(exclusive_test)) + return tests + + @memoized def skipped_due_to_skip_base_tests(self, test): """Checks if the test should be skipped due to the skip_base_test rule of any virtual suite. @@ -2573,12 +2587,6 @@ # Look for all tests in the manifest that are under the relative # |filter_path_from_wpt|. for test_path_from_wpt in wpt_manifest.all_urls(): - assert not test_path_from_wpt.startswith('/') - assert not test_path_from_wpt.endswith('/') - - # Drop empty path components. - test_path_from_wpt = test_path_from_wpt.replace('//', '/') - if test_path_from_wpt.startswith(filter_path_from_wpt): # The result is a test path from the root web test # directory. If a |virtual_prefix| was given, we prepend @@ -2606,6 +2614,7 @@ return '', test_name + @memoized def lookup_virtual_test_base(self, test_name): suite = self._lookup_virtual_suite(test_name) if not suite:
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/ios.py b/third_party/blink/tools/blinkpy/web_tests/port/ios.py index ab814c7..0944497 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/ios.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/ios.py
@@ -4,6 +4,7 @@ """Chromium iOS implementation of the Port interface.""" import logging +import socket from blinkpy.web_tests.port.ios_simulator_server_process import IOSSimulatorServerProcess from blinkpy.web_tests.port import base @@ -36,6 +37,7 @@ super(IOSPort, self).__init__(host, port_name, **kwargs) self.server_process_constructor = IOSSimulatorServerProcess self._version = port_name[port_name.index('ios-') + len('ios-'):] + self._stdio_redirect_port = self._get_available_port() def check_build(self, needs_http, printer): result = super(IOSPort, self).check_build(needs_http, printer) @@ -47,11 +49,10 @@ return result def cmd_line(self): - flags = self.additional_driver_flags() return [ self._path_to_simulator(), '-d', self.device_name(), '-c', - '%s -' % " ".join(flags) + '%s -' % self.additional_driver_flags() ] def reinstall_cmd_line(self): @@ -73,6 +74,14 @@ def _driver_class(self): return ChromiumIOSDriver + def _get_available_port(self): + # TODO(gyuyoung): Can we get a port in the iOS server process that it + # really binds to a socket? + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(('localhost', 0)) + port = int(s.getsockname()[1]) + return port + # # PROTECTED METHODS # @@ -80,6 +89,23 @@ def operating_system(self): return 'ios' + def num_workers(self, requested_num_workers): + # Only support a single worker because the iOS simulator is not able to + # run multiple instances of the same application at the same time. And, + # we do not support running multiple simulators for testing yet. + return min(1, requested_num_workers) + + def additional_driver_flags(self): + flags = super(IOSPort, self).additional_driver_flags() + flags += ['--no-sandbox'] + stdio_redirect_flag = '--stdio-redirect=127.0.0.1:' + str( + self._stdio_redirect_port) + flags += [stdio_redirect_flag] + return " ".join(flags) + + def stdio_redirect_port(self): + return self._stdio_redirect_port + def path_to_apache(self): import platform if platform.machine() == 'arm64': @@ -97,9 +123,9 @@ def setup_test_run(self): super(IOSPort, self).setup_test_run() - # Because the tests are being run on a simulator rather than directly on this - # device, re-deploy the content shell app to the simulator to ensure it is up - # to date. + # Because the tests are being run on a simulator rather than directly on + # this device, re-deploy the content shell app to the simulator to + # ensure it is up to date. self.host.executive.run_command(self.reinstall_cmd_line())
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process.py b/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process.py index ea58d5f..a923b2e 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process.py
@@ -4,23 +4,22 @@ import json import logging +import os +import select +import socket import time from blinkpy.web_tests.port.server_process import ServerProcess +from blinkpy.web_tests.port import driver _log = logging.getLogger(__name__) BOOT_STATE = 'Booted' +CONN_WAITING_TIMEOUT = 20 -# Define a custom version of ServerProcess for running tests on the iOS -# simulator. The default ServerProcess does not work as it uses -# stdin/stdout/stderr to communicate, which the iOS simulator does not -# allow for security. -# -# TODO(crbug.com/1421239): iOS port communicates with the content shell -# through a file handle temporarily. Socket connection should be used -# instead. + +# Custom version of ServerProcess that runs processes on the iOS simulator. class IOSSimulatorServerProcess(ServerProcess): def __init__(self, port_obj, @@ -32,16 +31,66 @@ super(IOSSimulatorServerProcess, self).__init__(port_obj, name, cmd, env, treat_no_data_as_crash, more_logging) - self._boot_simulator() - self._web_test_path_file = self._get_web_test_file_path() - if not self._web_test_path_file: - raise RuntimeError('_web_test_path_file does not exist.') + def _start(self): + if self._proc: + raise ValueError('%s already running' % self._name) + self._reset() - # Create a file at the path. - test_file_handle = open(self._web_test_path_file, 'wb') - test_file_handle.close() + # The iOS simulator doesn't allow to use stdin stream for packaged apps. + # Additionally, the stdout from run-test-suite not only includes + # additional data from the iOS test infrastructure but also combines + # stderr and stdout. As a result, when executing content_shell on the + # iOS simulator, it becomes impractical to employ stdin for transmitting + # a list of tests or to dependably utilize stdout for outputting + # results. To address this issue in the context of web tests, we employ + # a workaround by redirecting stdin and stdout to a TCP socket connected + # to the web test runner. Similar to Fuchsia, the runner also uses the + # --stdio-redirect flag to specify the address and port for stdin and + # stdout redirection. + listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + listen_socket.bind(('127.0.0.1', self._port.stdio_redirect_port())) + listen_socket.listen(1) + + proc = self._host.executive.popen(self._cmd, + stdin=self._host.executive.PIPE, + stdout=self._host.executive.PIPE, + stderr=self._host.executive.PIPE, + env=self._env) + + # Wait for incoming connection from the iOS content_shell. + fd = listen_socket.fileno() + + read_fds, _, _ = select.select([fd], [], [], CONN_WAITING_TIMEOUT) + while fd not in read_fds: + _log.error( + 'Timed out waiting connection from content_shell. Try to launch the content_shell again.' + ) + proc.kill() + # TODO(gyuyoung): There is sometimes no incoming connection when + # attempting to launch a content shell. We need to investigate why + # launching the content shell occasionally fails. To resolve the + # issue, consider repeatedly attempting to launch the content shell + # until it successfully launches. + proc = self._host.executive.popen(self._cmd, + stdin=self._host.executive.PIPE, + stdout=self._host.executive.PIPE, + stderr=self._host.executive.PIPE, + env=self._env) + read_fds, _, _ = select.select([fd], [], [], CONN_WAITING_TIMEOUT) + + stdio_socket, _ = listen_socket.accept() + fd = stdio_socket.fileno() # pylint: disable=no-member + stdin_pipe = os.fdopen(os.dup(fd), 'wb', 0) + stdout_pipe = os.fdopen(os.dup(fd), 'rb', 0) + stdio_socket.close() + + proc.stdin = stdin_pipe + proc.stdout = stdout_pipe + + self._set_proc(proc) def _boot_simulator(self): device = self._get_device(self._port.device_name()) @@ -59,53 +108,6 @@ break time.sleep(2) # Wait for 2 seconds before checking again. - def _get_web_test_file_path(self): - simulator_root = self._host.filesystem.expanduser( - '~/Library/Developer/CoreSimulator/Devices/') - udid = self._get_simulator_udid() - if not udid: - raise RuntimeError('The udid value of the Simulator is none.') - - app_data_path = self._host.filesystem.join( - simulator_root, udid, 'data/Containers/Data/Application') - - content_shell_dir = self._get_content_shell_dir(app_data_path) - if not content_shell_dir: - _log.error('Cannot find the content shell directory.') - return None - - content_shell_data_path = self._host.filesystem.join( - app_data_path, content_shell_dir) - content_shell_tmp_path = self._host.filesystem.join( - content_shell_data_path, 'tmp') - if not self._host.filesystem.exists(content_shell_tmp_path): - raise RuntimeError('%s path does not exist.' % - content_shell_tmp_path) - - return self._host.filesystem.join(content_shell_tmp_path, - 'webtest_test_name') - - def _get_content_shell_dir(self, app_data_path): - for app_dir in self._host.filesystem.listdir(app_data_path): - # Check if |app_dir| has the content shell directory. - content_shell_dir = self._host.filesystem.join( - app_data_path, app_dir, - 'Library/Application Support/Chromium Content Shell') - if self._host.filesystem.exists(content_shell_dir): - return app_dir - return None - - def _get_simulator_udid(self): - device = self._get_device(self._port.device_name()) - if not device: - _log.error('There is no available device.') - return None - udid = device.get('udid') - if not udid: - _log.error('Cannot find the udid of the iOS simulator.') - return None - return udid - def _get_device(self, device_name): devices = json.loads(self._run_simctl('list -j devices available')) if len(devices) == 0: @@ -134,14 +136,3 @@ prefix_commands = ['/usr/bin/xcrun', 'simctl'] command_array = prefix_commands + command.split() return self._host.executive.run_command(command_array) - - # - # PROTECTED METHODS - # - - def write(self, bytes): - super().write(bytes) - # iOS application can't communicate with the Mac host through stdin yet. - # Instead a file stream is used for the communication temporarily. - self._host.filesystem.write_binary_file(self._web_test_path_file, - bytes)
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process_unittest.py index d06bd0eb..891b6db 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/ios_simulator_server_process_unittest.py
@@ -3,15 +3,17 @@ # found in the LICENSE file. import json -import sys +import socket import subprocess +import sys +import threading import unittest from blinkpy.common.system.system_host import SystemHost from blinkpy.web_tests.port import ios_simulator_server_process from blinkpy.web_tests.port.factory import PortFactory -TEST_MESSAGE = b'writing test of a web test name' +TEST_FILE_NAME = b'dom/parent_node/append-on-document.html' class TestIOSSimulatorServerProcess(unittest.TestCase): @@ -30,6 +32,11 @@ except subprocess.CalledProcessError: return False + def _start_simulator_server( + self, + proc: ios_simulator_server_process.IOSSimulatorServerProcess): + proc.write(TEST_FILE_NAME) + def test_write(self): # Test only when the iOS simulator is installed on Mac. if sys.platform != 'darwin' or not self._is_ios_simulator_installed(): @@ -44,20 +51,29 @@ port = factory.get('ios') proc = ios_simulator_server_process.IOSSimulatorServerProcess( port, 'python', cmd) - proc.write(b'') + server = threading.Thread(target=self._start_simulator_server, + args=(proc, ), + name='simulator-server', + daemon=True) + # Start to the simulator server, and it sends a test file name to the + # client. + server.start() self.assertIsNone(proc.poll()) self.assertFalse(proc.has_crashed()) - # Check if the iOS simulator server process creates a test file for - # communicating between run_web_test.py and a content shell. - web_test_file_path = proc._get_web_test_file_path() - self.assertIsNotNone(web_test_file_path) + client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + # Connect to the server. + client_socket.connect(('127.0.0.1', port.stdio_redirect_port())) - proc.write(TEST_MESSAGE) - - test_file = open(web_test_file_path, 'r') - read_line = test_file.readline().strip() - self.assertEqual(read_line.encode(), TEST_MESSAGE) + # Check if the received data is the expected test file name. + received_data = client_socket.recv(1024) + self.assertEqual(received_data, TEST_FILE_NAME) + except socket.error as e: + raise ValueError('Connection error: {%s}' % e) + finally: + client_socket.close() + server.join() proc.stop(0)
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index 6a80c70..f94e9a1 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -1055,6 +1055,7 @@ crbug.com/1044715 [ Linux ] external/wpt/pointerevents/pointerevent_touch-action-inherit_parent-none_touch.html [ Slow ] crbug.com/1044715 [ Win ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch.html [ Slow ] crbug.com/1044715 [ Linux ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch.html [ Slow ] +crbug.com/1479003 [ Mac ] external/wpt/pointerevents/coalesced_events_attributes_under_load.html [ Slow ] crbug.com/1043396 [ Linux ] http/tests/devtools/network/network-eventsource.js [ Slow ] crbug.com/1043396 [ Mac10.15 Release ] http/tests/devtools/network/network-eventsource.js [ Slow ] crbug.com/1043396 [ Mac11 Release ] http/tests/devtools/network/network-eventsource.js [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 37bb59b..6f2e6db 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1311,10 +1311,6 @@ crbug.com/1219041 external/wpt/css/css-text/white-space/text-space-collapse-discard-001.xht [ Failure ] crbug.com/1219041 external/wpt/css/css-text/white-space/text-space-trim-trim-inner-001.xht [ Failure ] -# external/wpt/scroll-animations/ failures -crbug.com/1469282 [ Mac ] virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-range-animation.html [ Pass Timeout ] -crbug.com/1469282 [ Mac ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/scroll-timeline-range-animation.html [ Pass Timeout ] - # LayoutNG ref-tests that need to be updated (cannot be rebaselined). crbug.com/591099 [ Win ] virtual/text-antialias/ellipsis-with-self-painting-layer.html [ Failure ] crbug.com/1098801 virtual/text-antialias/whitespace/whitespace-in-pre.html [ Failure ] @@ -1522,7 +1518,6 @@ crbug.com/1163437 external/wpt/css/css-pseudo/grammar-spelling-errors-002.html [ Failure ] crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-001.html [ Failure ] crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-002.html [ Failure ] -crbug.com/1147859 [ Mac ] external/wpt/css/css-pseudo/highlight-painting-004.html [ Failure ] crbug.com/1172333 external/wpt/css/css-pseudo/first-letter-hi-001.html [ Failure ] crbug.com/1172333 external/wpt/css/css-pseudo/first-letter-digraph.html [ Failure ] crbug.com/1035708 wpt_internal/css/css-pseudo/grammar-error-color-003.html [ Failure ] @@ -1530,15 +1525,10 @@ crbug.com/1035708 external/wpt/css/css-pseudo/target-text-dynamic-004.html [ Failure ] crbug.com/1353352 fast/css3-text/css3-text-decoration/text-decoration-line-grammar-error.html [ Failure ] crbug.com/1353352 fast/css3-text/css3-text-decoration/text-decoration-line-spelling-error.html [ Failure ] -crbug.com/1147859 [ Mac ] external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html [ Failure ] -crbug.com/1147859 [ Mac ] external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html [ Failure ] crbug.com/1350475 external/wpt/css/css-pseudo/highlight-currentcolor-painting-text-shadow-001.html [ Failure ] crbug.com/1350475 external/wpt/css/css-pseudo/highlight-currentcolor-painting-text-shadow-002.html [ Failure ] crbug.com/1351020 [ Mac ] external/wpt/compat/webkit-text-fill-color-property-002.html [ Failure ] -# CSS highlight painting (HighlightOverlayPainting) -crbug.com/1147859 [ Mac ] external/wpt/css/css-pseudo/highlight-painting-003.html [ Failure ] - crbug.com/1205953 external/wpt/css/css-will-change/will-change-fixpos-cb-position-1.html [ Failure ] crbug.com/1207788 external/wpt/css/css-will-change/will-change-stacking-context-mask-1.html [ Failure ] @@ -2732,6 +2722,8 @@ crbug.com/626703 external/wpt/css/css-fonts/parsing/font-variant-invalid.html [ Crash ] crbug.com/1483059 [ Mac ] virtual/fetch-later/external/wpt/fetch/fetch-later/send-on-discard.tentative.https.window.html [ Failure Pass Timeout ] +crbug.com/1484043 [ Mac ] virtual/fetch-later/external/wpt/fetch/fetch-later/send-on-deactivate.tentative.https.window.html [ Pass Timeout ] +crbug.com/1484043 [ Win ] virtual/fetch-later/external/wpt/fetch/fetch-later/send-on-deactivate.tentative.https.window.html [ Pass Timeout ] # ====== New tests from wpt-importer added here ====== crbug.com/626703 external/wpt/css/css-shadow-parts/animation-part.html [ Failure ] @@ -2769,10 +2761,6 @@ crbug.com/626703 [ Win10.20h2 ] virtual/keepalive-in-browser-migration/external/wpt/fetch/metadata/generated/element-meta-refresh.optional.sub.html [ Timeout ] crbug.com/626703 [ Win ] virtual/shared-storage-fenced-frame-mparch-selecturl-limit/external/wpt/shared-storage-selecturl-limit/run-url-selection-operation-limit-multiple-origins.tentative.https.sub.html [ Timeout ] crbug.com/626703 [ Mac13 ] virtual/third-party-storage-partitioning/external/wpt/IndexedDB/idbobjectstore_getKey.any.html [ Timeout ] -crbug.com/626703 [ Mac10.15 ] virtual/fetch-later/external/wpt/fetch/fetch-later/send-on-deactivate.tentative.https.window.html [ Timeout ] -crbug.com/626703 [ Mac13 ] virtual/fetch-later/external/wpt/fetch/fetch-later/send-on-deactivate.tentative.https.window.html [ Timeout ] -crbug.com/626703 [ Mac11 ] virtual/fetch-later/external/wpt/fetch/fetch-later/send-on-deactivate.tentative.https.window.html [ Timeout ] -crbug.com/626703 [ Mac12 ] virtual/fetch-later/external/wpt/fetch/fetch-later/send-on-deactivate.tentative.https.window.html [ Timeout ] crbug.com/626703 external/wpt/css/css-transforms/backface-visibility-hidden-003.html [ Failure ] crbug.com/626703 external/wpt/css/css-transforms/backface-visibility-hidden-005.html [ Failure ] crbug.com/626703 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-003.html [ Failure ] @@ -2991,12 +2979,6 @@ crbug.com/626703 [ Mac13 Release ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/scroll-timelines/effect-updateTiming.html [ Timeout ] crbug.com/626703 [ Mac13 Release ] virtual/threaded/external/wpt/scroll-animations/scroll-timelines/effect-updateTiming.html [ Timeout ] crbug.com/626703 [ Mac13-arm64 Release ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ] -crbug.com/626703 [ Mac10.15 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Timeout ] -crbug.com/626703 [ Mac11 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Failure Timeout ] -crbug.com/626703 [ Mac12 Release ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Timeout ] -crbug.com/626703 [ Mac12-arm64 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Timeout ] -crbug.com/626703 [ Mac13 Release ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Timeout ] -crbug.com/626703 [ Mac13-arm64 Release ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Timeout ] crbug.com/626703 [ Mac12 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/animation-timeline-view-functional-notation.tentative.html [ Skip Timeout ] crbug.com/626703 [ Mac13 Release ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Timeout ] crbug.com/626703 [ Mac13-arm64 Release ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Timeout ] @@ -4481,7 +4463,6 @@ # Assorted virtual/threaded/.../wpt/scroll-animations tests crbug.com/1279648 virtual/threaded/external/wpt/scroll-animations/css/view-timeline-inset-animation.html [ Failure Pass Timeout ] -crbug.com/1409975 virtual/threaded/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Failure Pass Timeout ] crbug.com/1071189 [ Debug Linux ] editing/selection/programmatic-selection-on-mac-is-directionless.html [ Pass Timeout ] @@ -4951,7 +4932,6 @@ # pseudo-elements painting crbug.com/1163437 external/wpt/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html [ Failure ] crbug.com/1147859 external/wpt/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html [ Failure ] -crbug.com/1147859 [ Mac ] virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/forced-colors-mode-53.html [ Failure ] crbug.com/1454939 fast/events/touch/gesture/focus-selectionchange-on-tap.html [ Failure Pass ] crbug.com/1455239 http/tests/security/drag-drop-different-origin.html [ Failure Pass ] @@ -5777,7 +5757,6 @@ crbug.com/1479108 [ Mac11-arm64 ] virtual/threaded-no-composited-antialiasing/animations/composited-animations-rotate-zero-degrees.html [ Failure ] crbug.com/1479108 [ Mac12-arm64 ] virtual/threaded-no-composited-antialiasing/animations/composited-animations-rotate-zero-degrees.html [ Failure ] crbug.com/1479108 [ Mac13-arm64 ] virtual/threaded-no-composited-antialiasing/animations/composited-animations-rotate-zero-degrees.html [ Failure ] -crbug.com/1479003 [ Mac ] external/wpt/pointerevents/coalesced_events_attributes_under_load.html?mouse [ Timeout ] # Suppress http/tests/inspector-protocol/network/navigate-iframe-in2out.js test cluster crbug.com/1413112 [ Mac10.15 ] virtual/reduce-accept-language/http/tests/inspector-protocol/network/navigate-iframe-in2out.js [ Failure ] @@ -6258,9 +6237,6 @@ # Sheriff 2022-10-20 crbug.com/1376845 external/wpt/mediacapture-insertable-streams/MediaStreamTrackProcessor-backpressure.https.html [ Failure Pass ] -# Sheriff 2022-10-31 -crbug.com/1376679 virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative.html [ Crash Failure Pass Timeout ] - # Investigate the flake. crbug.com/1371395 external/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.html [ Failure Pass ] @@ -6685,7 +6661,6 @@ crbug.com/1411760 [ Mac ] virtual/composite-clip-path-animation/external/wpt/css/css-masking/clip-path/animations/clip-path-animation-fixed-position.html [ Failure Pass ] # Gardener 2023-07-26 -crbug.com/1467798 [ Mac11-arm64 ] virtual/threaded-prefer-compositing/external/wpt/scroll-animations/css/view-timeline-range-animation.html [ Failure Timeout ] crbug.com/1364187 http/tests/misc/scroll-cross-origin-iframes.html [ Failure Pass ] crbug.com/1467800 [ Mac11 ] virtual/prefetch/external/wpt/speculation-rules/prefetch/out-of-document-rule-set.https.html?include=StatusCode404 [ Failure Pass ] crbug.com/1467833 [ Mac12 ] virtual/compositor-threaded-percent-based-scrolling-dsf-2/virtual/percent-based-scrolling/max-percent-delta-page-zoom.html [ Crash Failure Pass Timeout ] @@ -6746,10 +6721,6 @@ # Gardener 2023-09-01 crbug.com/1477586 [ Mac13-arm64 ] virtual/threaded/http/tests/devtools/tracing/anonymous-image-object.js [ Failure Pass ] -# Gardener 2023-09-04 -crbug.com/1478028 [ Mac ] external/wpt/pointerevents/coalesced_events_attributes_under_load.html?pen [ Timeout ] -crbug.com/1478028 [ Linux ] external/wpt/pointerevents/coalesced_events_attributes_under_load.html?pen [ Timeout ] - # Gardener 2023-09-05 # Flaky on Webkit Linux Leak crbug.com/1478891 [ Linux ] fast/events/middleClickAutoscroll-nested-divs-forbidden.html [ Failure Pass ] @@ -6773,4 +6744,5 @@ # Gardener 2023-09-18 crbug.com/1482345 [ Mac11-arm64 Release ] fast/events/touch/touch-handler-count.html [ Failure Pass ] crbug.com/1482345 [ Mac12-arm64 Release ] fast/events/touch/touch-handler-count.html [ Failure Pass ] +crbug.com/1482345 [ Mac13-arm64 Release ] fast/events/touch/touch-handler-count.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 5f9a840..e27bc55f 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -2472,7 +2472,7 @@ "external/wpt/cookie-deprecation-label" ], "exclusive_tests": "ALL", - "args": ["--enable-features=CookieDeprecationFacilitatedTestingLabels:label/label_test", + "args": ["--enable-features=CookieDeprecationFacilitatedTesting:label/label_test", "--disable-threaded-compositing", "--disable-threaded-animation"], "expires": "Dec 31, 2023" },
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 19ee099..36e5df0a 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -1598,6 +1598,13 @@ null, {} ] + ], + "grid-dynamic.html": [ + "efc65859611fb04d2c4002fbe688291a221898f7", + [ + null, + {} + ] ] }, "detach-locked-slot-children-crash.html": [ @@ -191061,6 +191068,32 @@ ], {} ] + ], + "text-autospace-vertical-combine-001.html": [ + "bed306e159774446ac23ae5238fa654511a27067", + [ + null, + [ + [ + "/css/css-text/text-autospace/text-autospace-vertical-combine-001-ref.html", + "==" + ] + ], + {} + ] + ], + "text-autospace-vertical-upright-001.html": [ + "21d454e7133c1d979e7a666249533629562d9662", + [ + null, + [ + [ + "/css/css-text/text-autospace/text-autospace-vertical-upright-001-ref.html", + "==" + ] + ], + {} + ] ] }, "text-encoding": { @@ -281240,16 +281273,6 @@ } }, "support": { - ".cache": { - "gitignore2.json": [ - "95a0637bd1d208acedb8e436063da06bdfe4e137", - [] - ], - "mtime.json": [ - "ec8760fc2a126464bbb0ba32f9aa7b291e9f437a", - [] - ] - }, ".gitignore": [ "d93e645d547894b50149d3726de2654957b6e06f", [] @@ -332676,6 +332699,14 @@ "text-autospace-no-001.html.ini": [ "b2bc530c26109459e7fad707e8ffe890919aad93", [] + ], + "text-autospace-vertical-combine-001-ref.html": [ + "36c1cb45a1e808a8fbea68061de40b87eaa9ff08", + [] + ], + "text-autospace-vertical-upright-001-ref.html": [ + "1c9caec112a3f9e132a8b612f748a23556a56de2", + [] ] }, "text-encoding": { @@ -691906,7 +691937,7 @@ ] ], "send-redirect.htm": [ - "16b3231e25b4d78712f2f29df6ca5221c1964356", + "7d73f0f64cc4d7506e607f75d3bba37b9d3d74a9", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/pseudo-elements-011.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/pseudo-elements-011.html new file mode 100644 index 0000000..26dabbe1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/pseudo-elements-011.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<title>CSS Container Queries Test: ::highlight pseudo element on size container</title> +<link rel="help" href="https://drafts.csswg.org/css-contain-3/#query-container"> +<link rel="match" href="pseudo-elements-010-ref.html"> +<style> + #container { + width: 500px; + container-type: inline-size; + } + #container::highlight(hi) { + color: red; + background: transparent; + } + @container (width >= 400px) { + #container::highlight(hi) { + color: green; + background: transparent; + } + } +</style> +<div id="container">Highlight</div> +<script> + let highlight_range = document.createRange(); + highlight_range.selectNode(container); + CSS.highlights.set("hi", new Highlight(highlight_range)); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/pseudo-elements-012.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/pseudo-elements-012.html new file mode 100644 index 0000000..7c36d927 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/pseudo-elements-012.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>CSS Container Queries Test: ::highlight pseudo size container change</title> +<link rel="help" href="https://drafts.csswg.org/css-contain-3/#query-container"> +<link rel="match" href="pseudo-elements-010-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> + #container { + width: 300px; + container-type: inline-size; + } + #container::highlight(hi) { + color: red; + background: transparent; + } + @container (width >= 400px) { + #container::highlight(hi) { + color: green; + background: transparent; + } + } +</style> +<div id="container">Highlight</div> +<script> + let highlight_range = document.createRange(); + highlight_range.selectNode(container); + CSS.highlights.set("hi", new Highlight(highlight_range)); + + requestAnimationFrame(() => { + requestAnimationFrame(() => { + container.style.width = "500px"; + takeScreenshot(); + }); + }); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid-expected.txt deleted file mode 100644 index ade4b2f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -FAIL grid-template: none / 1px and "grid-template-areas: "a";" should be valid. assert_equals: expected "" but got "none / 1px" -FAIL grid-template: none / none and "grid-template-areas: "a";" should be valid. assert_equals: expected "" but got "none" -PASS grid-template: auto / 1px and "grid-template-areas: "a a a";" should be valid. -PASS grid-template: auto / auto and "grid-template-areas: "a a a";" should be valid. -PASS grid-template: 10px 20px 30px / 40px 50px 60px 70px and "grid-template-areas: "a . b ." "c d . e" "f g h .";" should be valid. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid.html.ini deleted file mode 100644 index 252da57f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-shorthand-areas-valid.html.ini +++ /dev/null
@@ -1,6 +0,0 @@ -[grid-template-shorthand-areas-valid.html] - [grid-template: none / 1px and "grid-template-areas: "a";" should be valid.] - expected: FAIL - - [grid-template: none / none and "grid-template-areas: "a";" should be valid.] - expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html index 8f347f1..9fdf11e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-text"> <link rel="match" href="highlight-currentcolor-painting-properties-001-ref.html"> <link rel="stylesheet" href="support/highlights.css"> +<meta name="fuzzy" content="0-50;0-3"> <style> div { color: lime;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html.ini deleted file mode 100644 index d528d983..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-001.html.ini +++ /dev/null
@@ -1,4 +0,0 @@ -[highlight-currentcolor-painting-properties-001.html] - expected: - if (product == "content_shell") and (os == "mac"): FAIL - if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html index bd5d5f4..8f66731 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html
@@ -6,6 +6,7 @@ <link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-text"> <link rel="match" href="highlight-currentcolor-painting-properties-002-ref.html"> <link rel="stylesheet" href="support/highlights.css"> +<meta name="fuzzy" content="0-50;0-3"> <style> div { color: lime;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html.ini b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html.ini deleted file mode 100644 index ea6638f..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-currentcolor-painting-properties-002.html.ini +++ /dev/null
@@ -1,4 +0,0 @@ -[highlight-currentcolor-painting-properties-002.html] - expected: - if (product == "content_shell") and (os == "mac"): FAIL - if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-003.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-003.html index b09ef52d..f479432 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-003.html
@@ -9,6 +9,7 @@ <meta name="assert" value="::selection overlay background and decorations are independent of those of the originating element, and originating element decorations lose their colour"> <script src="support/selections.js"></script> <link rel="stylesheet" href="support/highlights.css"> +<meta name="fuzzy" content="0-50;0-50"> <style> /* Topmost last:
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-003.html.ini b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-003.html.ini deleted file mode 100644 index d95c4b9..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-003.html.ini +++ /dev/null
@@ -1,4 +0,0 @@ -[highlight-painting-003.html] - expected: - if (product == "content_shell") and (os == "mac"): FAIL - if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-004.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-004.html index 26ded65..cbf01e8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-004.html
@@ -11,6 +11,7 @@ <meta name="assert" value="::selection overlay background and decorations are independent of those of the originating element, and originating element decorations lose their colour"> <script src="support/selections.js"></script> <link rel="stylesheet" href="support/highlights.css"> +<meta name="fuzzy" content="0-50;0-20"> <style> /* Topmost last:
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-004.html.ini b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-004.html.ini deleted file mode 100644 index fca58446..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-painting-004.html.ini +++ /dev/null
@@ -1,4 +0,0 @@ -[highlight-painting-004.html] - expected: - if (product == "content_shell") and (os == "mac"): FAIL - if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter-ref.html b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter-ref.html index 7dd4efaf..8a74bd2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter-ref.html
@@ -25,8 +25,10 @@ } </style> <div id="view-transition-mock"> - <div id="target"> +<!-- This box should be a scrollbar's width from the left edge and exactly aligned with the light green background. +--> + <div id="target"> </div> </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter.html b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter.html index db367a1..6e9bf56 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter.html +++ b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/snapshot-containing-block-includes-scrollbar-gutter.html
@@ -28,9 +28,11 @@ animation-duration: 300s; } </style> -<div id="target"> +<!-- This box should be a scrollbar's width from the left edge and exactly aligned with the light green background. +--> +<div id="target"> </div> <script> failIfNot(document.startViewTransition,
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/cross-origin.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/cross-origin.https.sub.window.js index ebaebb4d..a26d4ce 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/cross-origin.https.sub.window.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/cross-origin.https.sub.window.js
@@ -1,19 +1,32 @@ // META: script=/resources/testdriver.js // META: script=/common/utils.js // META: script=resources/fledge-util.js +// META: script=/common/subset-tests.js // META: timeout=long +// META: variant=?1-4 +// META: variant=?5-8 +// META: variant=?9-12 +// META: variant=?13-last "use strict;" const OTHER_ORIGIN1 = 'https://{{hosts[alt][]}}:{{ports[https][0]}}'; +const OTHER_ORIGIN2 = 'https://{{hosts[alt][]}}:{{ports[https][1]}}'; -function runInIframe(test, iframe, script) { +// Runs "script" in "iframe" via an eval call. The iframe must have been +// created by calling "createIframe()" below. "param" is passed to the +// context "script" is run in, so can be used to pass objects that +// "script" references that can't be serialized to a string, like +// fencedFrameConfigs. +async function runInIframe(test, iframe, script, param) { const messageUuid = generateUuid(test); + let receivedResponse = {}; - return new Promise(function(resolve, reject) { + let promise = new Promise(function(resolve, reject) { function WaitForMessage(event) { if (event.data.messageUuid != messageUuid) return; + receivedResponse = event.data; if (event.data.result === 'success') { resolve(); } else { @@ -21,8 +34,11 @@ } } window.addEventListener('message', WaitForMessage); - iframe.contentWindow.postMessage({messageUuid: messageUuid, script: script}, '*'); + iframe.contentWindow.postMessage( + {messageUuid: messageUuid, script: script, param: param}, '*'); }); + await promise; + return receivedResponse.returnValue; } // Creates an iframe and navigates to a URL on "origin", and waits for the URL @@ -64,7 +80,7 @@ // Join interest group in iframe tests. //////////////////////////////////////////////////////////////////////////////// -promise_test(async test => { +subsetTest(promise_test, async test => { const uuid = generateUuid(test); let iframe = await createIframe(test, document.location.origin); @@ -73,10 +89,10 @@ // Run an auction using window.location.origin as a bidder. The IG should // make a bid and win an auction. - let config = await runBasicFledgeTestExpectingWinner(test, uuid); + await runBasicFledgeTestExpectingWinner(test, uuid); }, 'Join interest group in same-origin iframe, default permissions.'); -promise_test(async test => { +subsetTest(promise_test, async test => { const uuid = generateUuid(test); let iframe = await createIframe(test, OTHER_ORIGIN1); @@ -88,7 +104,7 @@ // // TODO: Once the permission defaults to not being able to join InterestGroups in // cross-origin iframes, this auction should have no winner. - let config = await runBasicFledgeTestExpectingWinner( + await runBasicFledgeTestExpectingWinner( test, uuid, { interestGroupBuyers: [OTHER_ORIGIN1], scoreAd: `if (browserSignals.interestGroupOwner !== "${OTHER_ORIGIN1}") @@ -96,7 +112,7 @@ }); }, 'Join interest group in cross-origin iframe, default permissions.'); -promise_test(async test => { +subsetTest(promise_test, async test => { const uuid = generateUuid(test); let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group'); @@ -105,7 +121,7 @@ // Run an auction in this frame using the other origin as a bidder. The IG should // make a bid and win an auction. - let config = await runBasicFledgeTestExpectingWinner( + await runBasicFledgeTestExpectingWinner( test, uuid, { interestGroupBuyers: [OTHER_ORIGIN1], scoreAd: `if (browserSignals.interestGroupOwner !== "${OTHER_ORIGIN1}") @@ -113,7 +129,7 @@ }); }, 'Join interest group in cross-origin iframe with join-ad-interest-group permission.'); -promise_test(async test => { +subsetTest(promise_test, async test => { const uuid = generateUuid(test); let iframe = await createIframe(test, OTHER_ORIGIN1, "join-ad-interest-group 'none'"); @@ -124,18 +140,20 @@ `try { await joinInterestGroup(test_instance, "${uuid}"); } catch (e) { - return "success"; + assert_true(e instanceof DOMException, "DOMException thrown"); + assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown"); + return {result: "success"}; } return "exception unexpectedly not thrown";`); // Run an auction in this frame using the other origin as a bidder. Since the join // should have failed, the auction should have no winner. - let config = await runBasicFledgeTestExpectingNoWinner( + await runBasicFledgeTestExpectingNoWinner( test, uuid, { interestGroupBuyers: [OTHER_ORIGIN1] }); }, 'Join interest group in cross-origin iframe with join-ad-interest-group permission denied.'); -promise_test(async test => { +subsetTest(promise_test, async test => { const uuid = generateUuid(test); let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group'); @@ -148,5 +166,182 @@ // Run an auction with this page's origin as a bidder. Since the join // should have failed, the auction should have no winner. - let config = await runBasicFledgeTestExpectingNoWinner(test, uuid); + await runBasicFledgeTestExpectingNoWinner(test, uuid); }, "Join interest group owned by parent's origin in cross-origin iframe."); + +//////////////////////////////////////////////////////////////////////////////// +// Run auction in iframe tests. +//////////////////////////////////////////////////////////////////////////////// + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + await joinInterestGroup(test, uuid); + + let iframe = await createIframe(test, document.location.origin); + + // Join a same-origin InterestGroup in a iframe navigated to its origin. + await runInIframe(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`); + + // Run auction in same-origin iframe. This should succeed, by default. + await runInIframe( + test, iframe, + `await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");`); +}, 'Run auction in same-origin iframe, default permissions.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + // Join an interest group owned by the the main frame's origin. + await joinInterestGroup(test, uuid); + + let iframe = await createIframe(test, OTHER_ORIGIN1); + + // Run auction in cross-origin iframe. Currently, this is allowed by default. + await runInIframe( + test, iframe, + `await runBasicFledgeTestExpectingWinner( + test_instance, "${uuid}", + {interestGroupBuyers: ["${window.location.origin}"]});`); +}, 'Run auction in cross-origin iframe, default permissions.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + // Join an interest group owned by the the main frame's origin. + await joinInterestGroup(test, uuid); + + let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction"); + + // Run auction in cross-origin iframe that should allow the auction to occur. + await runInIframe( + test, iframe, + `await runBasicFledgeTestExpectingWinner( + test_instance, "${uuid}", + {interestGroupBuyers: ["${window.location.origin}"]});`); +}, 'Run auction in cross-origin iframe with run-ad-auction permission.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + // No need to join any interest groups in this case - running an auction + // should only throw an exception based on permissions policy, regardless + // of whether there are any interest groups can participate. + + let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction 'none'"); + + // Run auction in cross-origin iframe that should not allow the auction to occur. + await runInIframe( + test, iframe, + `try { + await runBasicFledgeAuction(test_instance, "${uuid}"); + } catch (e) { + assert_true(e instanceof DOMException, "DOMException thrown"); + assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown"); + return {result: "success"}; + } + throw "Attempting to run auction unexpectedly did not throw"`); +}, 'Run auction in cross-origin iframe with run-ad-auction permission denied.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + // Join an interest group owned by the the main frame's origin. + await joinInterestGroup(test, uuid); + + let iframe = await createIframe(test, OTHER_ORIGIN1, `run-ad-auction ${OTHER_ORIGIN1}`); + + await runInIframe( + test, iframe, + `await runBasicFledgeTestExpectingWinner( + test_instance, "${uuid}", + { interestGroupBuyers: ["${window.location.origin}"], + seller: "${OTHER_ORIGIN2}", + decisionLogicURL: createDecisionScriptURL("${uuid}", {origin: "${OTHER_ORIGIN2}"}) + });`); +}, 'Run auction in cross-origin iframe with run-ad-auction for iframe origin, which is different from seller origin.'); + +//////////////////////////////////////////////////////////////////////////////// +// Navigate fenced frame iframe tests. +//////////////////////////////////////////////////////////////////////////////// + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + + // Join an interest group and run an auction with a winner. + await joinInterestGroup(test, uuid); + let config = await runBasicFledgeTestExpectingWinner(test, uuid); + + // Try to navigate a fenced frame to the winning ad in a cross-origin iframe + // with no fledge-related permissions. + let iframe = await createIframe( + test, OTHER_ORIGIN1, "join-ad-interest-group 'none'; run-ad-auction 'none'"); + await runInIframe( + test, iframe, + `await createAndNavigateFencedFrame(test_instance, param);`, + /*param=*/config); + await waitForObservedRequests( + uuid, [createBidderReportURL(uuid), createSellerReportURL(uuid)]); +}, 'Run auction main frame, open winning ad in cross-origin iframe.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + + let iframe = await createIframe( + test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction"); + await runInIframe( + test, iframe, + `await joinInterestGroup(test_instance, "${uuid}"); + await runBasicFledgeAuctionAndNavigate(test_instance, "${uuid}"); + await waitForObservedRequests( + "${uuid}", [createBidderReportURL("${uuid}"), createSellerReportURL("${uuid}")])`); +}, 'Run auction in cross-origin iframe and open winning ad in nested fenced frame.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + + // Run an auction in an cross-origin iframe, and get the resulting FencedFrameConfig. + let iframe = await createIframe( + test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction"); + let config = await runInIframe( + test, iframe, + `await joinInterestGroup(test_instance, "${uuid}"); + let config = await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}"); + return {result: "success", returnValue: config};`); + assert_true(config != null, "Value not returned from auction in iframe"); + assert_true(config instanceof FencedFrameConfig, + `Wrong value type returned from auction: ${config.constructor.type}`); + + // Loading the winning ad in a fenced frame that's a child of the main frame should + // succeed. + await createAndNavigateFencedFrame(test, config); + await waitForObservedRequests( + uuid, + [ createBidderReportURL(uuid, '1', OTHER_ORIGIN1), + createSellerReportURL(uuid, '1', OTHER_ORIGIN1)]); +}, 'Run auction in cross-origin iframe and open winning ad in a fenced frame child of the main frame.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + + // Run an auction in an cross-origin iframe, and get the resulting FencedFrameConfig. + let iframe = await createIframe( + test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction"); + let config = await runInIframe( + test, iframe, + `await joinInterestGroup(test_instance, "${uuid}"); + let config = await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}"); + return {result: "success", returnValue: config};`); + assert_true(config != null, "Value not returned from auction in iframe"); + assert_true(config instanceof FencedFrameConfig, + `Wrong value type returned from auction: ${config.constructor.type}`); + + // Try to navigate a fenced frame to the winning ad in a cross-origin iframe + // with no fledge-related permissions. The iframe is a different origin from the + // first cross-origin iframe. + let iframe2 = await createIframe( + test, OTHER_ORIGIN2, "join-ad-interest-group 'none'; run-ad-auction 'none'"); + await runInIframe( + test, iframe2, + `await createAndNavigateFencedFrame(test_instance, param);`, + /*param=*/config); + await waitForObservedRequests( + uuid, + [ createBidderReportURL(uuid, '1', OTHER_ORIGIN1), + createSellerReportURL(uuid, '1', OTHER_ORIGIN1)]); +}, 'Run auction in cross-origin iframe and open winning ad in a fenced frame child of another cross-origin iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js index 9cfd0cb..7ed5b13 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js
@@ -33,24 +33,20 @@ // Create tracked bidder/seller URLs. The only difference is the prefix added // to the `id` passed to createTrackerURL. The optional `id` field allows // multiple bidder/seller report URLs to be distinguishable from each other. -function createBidderReportURL(uuid, id = '1') { - return createTrackerURL(window.location.origin, uuid, `track_get`, - `bidder_report_${id}`); +function createBidderReportURL(uuid, id = '1', origin = window.location.origin) { + return createTrackerURL(origin, uuid, `track_get`, `bidder_report_${id}`); } -function createSellerReportURL(uuid, id = '1') { - return createTrackerURL(window.location.origin, uuid, `track_get`, - `seller_report_${id}`); +function createSellerReportURL(uuid, id = '1', origin = window.location.origin) { + return createTrackerURL(origin, uuid, `track_get`, `seller_report_${id}`); } // Much like above ReportURL methods, except designed for beacons, which // are expected to be POSTs. -function createBidderBeaconURL(uuid, id = '1') { - return createTrackerURL(window.location.origin, uuid, `track_post`, - `bidder_beacon_${id}`); +function createBidderBeaconURL(uuid, id = '1', origin = window.location.origin) { + return createTrackerURL(origin, uuid, `track_post`, `bidder_beacon_${id}`); } -function createSellerBeaconURL(uuid, id = '1') { - return createTrackerURL(window.location.origin, uuid, `track_post`, - `seller_beacon_${id}`); +function createSellerBeaconURL(uuid, id = '1', origin = window.location.origin) { + return createTrackerURL(origin, uuid, `track_post`, `seller_beacon_${id}`); } // Generates a UUID and registers a cleanup method with the test fixture to @@ -149,7 +145,8 @@ // // The default reportResult() method is empty. function createDecisionScriptURL(uuid, params = {}) { - let url = new URL(`${BASE_URL}resources/decision-logic.sub.py`); + let origin = params.origin ? params.origin : new URL(BASE_URL).origin; + let url = new URL(`${origin}${RESOURCE_PATH}decision-logic.sub.py`); url.searchParams.append('uuid', uuid); if (params.scoreAd) url.searchParams.append('scoreAd', params.scoreAd); @@ -264,6 +261,16 @@ assert_true(result === null, 'Auction unexpectedly had a winner'); } +// Creates a fenced frame and applies fencedFrameConfig to it. Also adds a cleanup +// method to destroy the fenced frame at the end of the current test. +function createAndNavigateFencedFrame(test, fencedFrameConfig) { + let fencedFrame = document.createElement('fencedframe'); + fencedFrame.mode = 'opaque-ads'; + fencedFrame.config = fencedFrameConfig; + document.body.appendChild(fencedFrame); + test.add_cleanup(() => { document.body.removeChild(fencedFrame); }); +} + // Calls runBasicFledgeAuction(), expecting the auction to have a winner. // Creates a fenced frame that will be destroyed on completion of "test", and // navigates it to the URN URL returned by the auction. Does not wait for the @@ -272,12 +279,7 @@ auctionConfigOverrides = {}) { let config = await runBasicFledgeTestExpectingWinner(test, uuid, auctionConfigOverrides); - - let fencedFrame = document.createElement('fencedframe'); - fencedFrame.mode = 'opaque-ads'; - fencedFrame.config = config; - document.body.appendChild(fencedFrame); - test.add_cleanup(() => { document.body.removeChild(fencedFrame); }); + createAndNavigateFencedFrame(test, config); } // Joins an interest group and runs an auction, expecting a winner to be
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/iframe.sub.html b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/iframe.sub.html index 65479f0..0bc0ea35 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/iframe.sub.html +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/iframe.sub.html
@@ -36,14 +36,17 @@ let test_instance = new Test(); // Register a message event listener that listens for events with data - // in the format {messageUuid: <uuid>, script: <script>>}, and when such + // in the format {messageUuid: <uuid>, script: <script>}, and when such // a message is received, tries to eval the script and then returns a - // message in the format {messageUuid: <uuid>, result: <result>}. + // message in the format: + // {messageUuid: <uuid>, result: <result>, returnValue: <returnValue>} // // On success, <result> is "success", while on failure, it's an error // message. <script> is interpreted as a possibly asynchronous function // body. Exceptions are caught and their stringified value is returned - // as <result>. + // as <result>. <returnValue> is a value returned to the caller of + // the function that sent the message. It's up to the received script + // to set it, if a return value is needed. // // "messageUuid" serves to allow the listener to make sure the message // is intended for it. @@ -51,17 +54,18 @@ // If not a message for this listener, do nothing. if (!event.data.messageUuid) return; - let result = 'unexpected'; + let message = {result: 'unexpected'}; try { - result = await eval( + let param = event.data.param; + message = await eval( `(async () => { ${event.data.script}; - return 'success'; + return {result: 'success'}; })()`); } catch (e) { - result = e.toString(); + message.result = e.toString(); } - let message = {messageUuid: event.data.messageUuid, result: result}; + message.messageUuid = event.data.messageUuid; window.parent.postMessage(message, '*'); });
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/forced-colors-mode-53.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/forced-colors-mode-53.html index 4726c4b..3b31a59 100644 --- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/forced-colors-mode-53.html +++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/forced-colors-mode-53.html
@@ -4,6 +4,7 @@ <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced-color-adjust-prop"> <link rel="help" href="https://drafts.csswg.org/css-highlight-api-1/"> <link rel=match href="forced-colors-mode-53-ref.html"> +<meta name="fuzzy" content="0-5;0-3"> <style> span { background-color: lightgray;
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/coalesced_events_attributes_under_load.html b/third_party/blink/web_tests/external/wpt/pointerevents/coalesced_events_attributes_under_load.html index 442aecb..26274255 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/coalesced_events_attributes_under_load.html +++ b/third_party/blink/web_tests/external/wpt/pointerevents/coalesced_events_attributes_under_load.html
@@ -57,8 +57,8 @@ // Every pointerdown blocks the main thread for a certain time limit, // and then increases the time limit for next round in case the // current limit fails to cause event coalescing. - let now = performance.now(); - while (performance.now() < now + current_busyloop_ms) + let start = performance.now(); + while (performance.now() < start + current_busyloop_ms) continue; current_busyloop_ms *= 2; }); @@ -85,7 +85,7 @@ actions = actions.pointerUp(); await actions.send(); - await await pointerup_promise; + await pointerup_promise; } assert_true(coalesced_event_received, "Coalesed pointermoves received");
diff --git a/third_party/blink/web_tests/external/wpt/xhr/send-redirect.htm b/third_party/blink/web_tests/external/wpt/xhr/send-redirect.htm index 16b3231..7d73f0f 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/send-redirect.htm +++ b/third_party/blink/web_tests/external/wpt/xhr/send-redirect.htm
@@ -9,28 +9,37 @@ <body> <div id="log"></div> <script> + // https://fetch.spec.whatwg.org/#statuses + var redirect_codes = new Set([301, 302, 303, 307, 308]); function redirect(code) { - var test = async_test(document.title + " (" + code + ")") + var test = async_test(`${document.title} (${code} does ${redirect_codes.has(code)? "redirect": "not redirect"})`); test.step(function() { - var client = new XMLHttpRequest() + var client = new XMLHttpRequest(); client.onreadystatechange = function() { test.step(function() { if(client.readyState == 4) { - assert_equals(client.getResponseHeader("x-request-method"), "GET") - assert_equals(client.getResponseHeader("x-request-content-type"), "application/x-pony") - test.done() + if (redirect_codes.has(code)) { + assert_equals(client.getResponseHeader("x-request-method"), "GET"); + assert_equals(client.getResponseHeader("x-request-content-type"), "application/x-pony"); + assert_equals(client.status, 200); + } else { + assert_equals(client.getResponseHeader("x-request-method"), null); + assert_equals(client.getResponseHeader("x-request-content-type"), null); + assert_equals(client.status, code); + } + test.done(); } }) } - client.open("GET", "resources/redirect.py?location=content.py&code=" + code) - client.setRequestHeader("Content-Type", "application/x-pony") - client.send(null) + client.open("GET", "resources/redirect.py?location=content.py&code=" + code); + client.setRequestHeader("Content-Type", "application/x-pony"); + client.send(null); }) } - redirect("301") - redirect("302") - redirect("303") - redirect("307") + + for (var number of [300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 350, 399]) { + redirect(number); + } </script> </body> </html>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/third-party-cookie-phaseout-exclusion-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/third-party-cookie-phaseout-exclusion-expected.txt index bebd0969..fa4a462 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/third-party-cookie-phaseout-exclusion-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/third-party-cookie-phaseout-exclusion-expected.txt
@@ -1,7 +1,8 @@ Verifies that third-party cookie that is blocked by third-party phaseout files an issue. Number of cookies: 0 -Number of cookies: 0 +Number of cookies: 1 +Cookie blocked: true Issues: { issue : {
diff --git a/third_party/blink/web_tests/virtual/cookie-deprecation-label/README.md b/third_party/blink/web_tests/virtual/cookie-deprecation-label/README.md index 94745f3..eabcf40 100644 --- a/third_party/blink/web_tests/virtual/cookie-deprecation-label/README.md +++ b/third_party/blink/web_tests/virtual/cookie-deprecation-label/README.md
@@ -1,7 +1,7 @@ # Cookie Deprecation The tests are run with the flag ---enable-features=CookieDeprecationFacilitatedTestingLabels +--enable-features=CookieDeprecationFacilitatedTesting You can run these tests by targeting the following directory: -`virtual/cookie-deprecation/external/wpt/cookie-deprecation-label` +`virtual/cookie-deprecation-label/external/wpt/cookie-deprecation-label`
diff --git a/third_party/chromite b/third_party/chromite index 220e3a7..0a79963 160000 --- a/third_party/chromite +++ b/third_party/chromite
@@ -1 +1 @@ -Subproject commit 220e3a70773a42e87b7356e7ae3f70327df04101 +Subproject commit 0a79963e8dbec43dd3b16f43f81b3b8591972453
diff --git a/third_party/dawn b/third_party/dawn index 5ca21ed..9f1bd72 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 5ca21ed720844ddd5b10547f0758564cfc59997a +Subproject commit 9f1bd725eb44c9da63066842cd1fa6842d1157c8
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index 86e6e65..616289d 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit 86e6e655de96ade68a60ac01e940b9bfc5fb05ee +Subproject commit 616289d464d11fbcc8c8b063af4d2b6c372f5e14
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 94b88f0..614e1c8 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 94b88f0598f5c47288b7f5493490bbfe372dabaa +Subproject commit 614e1c8242dfa60a241368d72c31384c14afaba3
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index b4a4125..dfe1c22 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-13-2-24-gd7b63a966 -Revision: d7b63a966bdedeb52511913bc9d7de170b213d7e +Version: VER-2-13-2-25-gbabe6af16 +Revision: babe6af16740f3fa3c19ef4b689f29d574c5fbc8 CPEPrefix: cpe:/a:freetype:freetype:2.13.2 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/third_party/freetype/src b/third_party/freetype/src index d7b63a9..babe6af 160000 --- a/third_party/freetype/src +++ b/third_party/freetype/src
@@ -1 +1 @@ -Subproject commit d7b63a966bdedeb52511913bc9d7de170b213d7e +Subproject commit babe6af16740f3fa3c19ef4b689f29d574c5fbc8
diff --git a/third_party/libc++/src b/third_party/libc++/src index 7cee6b0..3e8a3b3 160000 --- a/third_party/libc++/src +++ b/third_party/libc++/src
@@ -1 +1 @@ -Subproject commit 7cee6b00d34adc4da2ff2a4d373e44fc27a9a223 +Subproject commit 3e8a3b3c5d497eb7250566a63432046baf95481a
diff --git a/third_party/libunwind/src b/third_party/libunwind/src index d9b4abf..244575f 160000 --- a/third_party/libunwind/src +++ b/third_party/libunwind/src
@@ -1 +1 @@ -Subproject commit d9b4abf6b6c3e4541766df4eedaf534ed1322a8e +Subproject commit 244575ffb656e4d2a2c88410c624dfbd5af68044
diff --git a/third_party/pdfium b/third_party/pdfium index 71c92d9..1dc2fc9 160000 --- a/third_party/pdfium +++ b/third_party/pdfium
@@ -1 +1 @@ -Subproject commit 71c92d906915cb0f0d8bedc5c81b154d954f0034 +Subproject commit 1dc2fc9894094165089a60b2fb75164e592bcb8c
diff --git a/third_party/perfetto b/third_party/perfetto index e5ad178..15336a4d 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit e5ad1783507a8eadfee5b8f8fad200a66db59fee +Subproject commit 15336a4d7f58ebec9421237bd888145095bf9aca
diff --git a/third_party/skia b/third_party/skia index 3829203..c641367 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 382920373b20cb807dfb2972ecfaf8eef22548a9 +Subproject commit c6413673d2d4d6e3a4837d3cecfe152243042415
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src index be1210e..cff8019 160000 --- a/third_party/webgpu-cts/src +++ b/third_party/webgpu-cts/src
@@ -1 +1 @@ -Subproject commit be1210e145e89e7a2943947d983f9592495e0f52 +Subproject commit cff8019fdd22c52e711ae90ed0659cf4ac0a8509
diff --git a/third_party/webrtc b/third_party/webrtc index 090699a..4b583c7 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit 090699a01bfc2f91af97e6461ff126bef996905a +Subproject commit 4b583c732301ea096a867287e974604d15a6af74
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp index 8d5c67a7..cb226a5 100644 --- a/tools/clang/plugins/FindBadConstructsAction.cpp +++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -22,10 +22,15 @@ const char kExcludeFieldsArgPrefix[] = "exclude-fields="; // Name of a cmdline parameter that can be used to add a regular expressions -// that matches paths that should be excluded from the raw_ptr checks. +// that matches paths that should be excluded from the raw pointer usage checks. const char kRawPtrExcludePathArgPrefix[] = "raw-ptr-exclude-path="; // Name of a cmdline parameter that can be used to add a regular expressions +// that matches paths that should be excluded from the bad raw_ptr casts checks. +const char kBadRawPtrCastExcludePathArgPrefix[] = + "check-bad-raw-ptr-cast-exclude-path="; + +// Name of a cmdline parameter that can be used to add a regular expressions // that matches function names that should be excluded from the bad raw_ptr cast // checks. All implicit casts in CallExpr to the specified functions are // excluded from the check. Use if you know that function does not break a @@ -75,6 +80,9 @@ } else if (arg.startswith(kCheckBadRawPtrCastExcludeFuncArgPrefix)) { options_.check_bad_raw_ptr_cast_exclude_funcs.push_back( arg.substr(strlen(kCheckBadRawPtrCastExcludeFuncArgPrefix)).str()); + } else if (arg.startswith(kBadRawPtrCastExcludePathArgPrefix)) { + options_.check_bad_raw_ptr_cast_exclude_paths.push_back( + arg.substr(strlen(kBadRawPtrCastExcludePathArgPrefix)).str()); } else if (arg == "check-base-classes") { // TODO(rsleevi): Remove this once http://crbug.com/123295 is fixed. options_.check_base_classes = true;
diff --git a/tools/clang/plugins/FindBadRawPtrPatterns.cpp b/tools/clang/plugins/FindBadRawPtrPatterns.cpp index 3650264..964d7110 100644 --- a/tools/clang/plugins/FindBadRawPtrPatterns.cpp +++ b/tools/clang/plugins/FindBadRawPtrPatterns.cpp
@@ -247,30 +247,37 @@ MatchFinder match_finder; std::vector<std::string> paths_to_exclude_lines; - std::vector<std::string> separate_repository_paths; + std::vector<std::string> check_bad_raw_ptr_cast_exclude_paths; for (auto* const line : kRawPtrManualPathsToIgnore) { paths_to_exclude_lines.push_back(line); } for (auto* const line : kSeparateRepositoryPaths) { paths_to_exclude_lines.push_back(line); - separate_repository_paths.push_back(line); + check_bad_raw_ptr_cast_exclude_paths.push_back(line); } paths_to_exclude_lines.insert(paths_to_exclude_lines.end(), options.raw_ptr_paths_to_exclude_lines.begin(), options.raw_ptr_paths_to_exclude_lines.end()); + check_bad_raw_ptr_cast_exclude_paths.insert( + check_bad_raw_ptr_cast_exclude_paths.end(), + options.check_bad_raw_ptr_cast_exclude_paths.begin(), + options.check_bad_raw_ptr_cast_exclude_paths.end()); FilterFile exclude_fields(options.exclude_fields_file, "exclude-fields"); FilterFile exclude_lines(paths_to_exclude_lines); - FilterFile exclude_separate_repositories(separate_repository_paths); - FilterFile check_bad_raw_ptr_cast_exclude_funcs( - options.check_bad_raw_ptr_cast_exclude_funcs); + StackAllocatedPredicate stack_allocated_predicate; RawPtrAndRefExclusionsOptions exclusion_options{ &exclude_fields, &exclude_lines, options.check_raw_ptr_to_stack_allocated, &stack_allocated_predicate}; - BadCastMatcher bad_cast_matcher(compiler, exclude_separate_repositories, - check_bad_raw_ptr_cast_exclude_funcs); + FilterFile filter_check_bad_raw_ptr_cast_exclude_paths( + check_bad_raw_ptr_cast_exclude_paths); + FilterFile filter_check_bad_raw_ptr_cast_exclude_funcs( + options.check_bad_raw_ptr_cast_exclude_funcs); + BadCastMatcher bad_cast_matcher(compiler, + filter_check_bad_raw_ptr_cast_exclude_paths, + filter_check_bad_raw_ptr_cast_exclude_funcs); if (options.check_bad_raw_ptr_cast) { bad_cast_matcher.Register(match_finder); }
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h index e7efe86..edcf7861 100644 --- a/tools/clang/plugins/Options.h +++ b/tools/clang/plugins/Options.h
@@ -24,6 +24,7 @@ std::string exclude_fields_file; std::vector<std::string> raw_ptr_paths_to_exclude_lines; std::vector<std::string> check_bad_raw_ptr_cast_exclude_funcs; + std::vector<std::string> check_bad_raw_ptr_cast_exclude_paths; }; } // namespace chrome_checker
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.cpp b/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.cpp index 6454aabc..4ec6082 100644 --- a/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.cpp +++ b/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.cpp
@@ -62,4 +62,8 @@ // Casts that |isInLocationListedInFilterFile(...)| should be excluded. #line 1 "../../internal/fake_loc/bad_raw_ptr_cast_implicit_exclusion.cpp" (void)reinterpret_cast<RawPtrWrapper*>(p); + + // Casts in allowlisted paths should be excluded. +#line 1 "../../ppapi/fake_loc/bad_raw_ptr_cast_implicit_exclusion.cpp" + (void)reinterpret_cast<RawPtrWrapper*>(p); }
diff --git a/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.flags b/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.flags index cf4bfa4..c119bb057 100644 --- a/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.flags +++ b/tools/clang/plugins/tests/bad_raw_ptr_cast_implicit_exclusion.flags
@@ -1 +1 @@ --Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast-exclude-func=test::AllowlistedFunc -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast-exclude-func=test::AllowlistedConstructor::AllowlistedConstructor +-Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast-exclude-func=test::AllowlistedFunc -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast-exclude-func=test::AllowlistedConstructor::AllowlistedConstructor -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast-exclude-path=ppapi/
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 67bfab2..da3c03d 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -7,6 +7,10 @@ # * all keys must be quoted (use single quotes, please); # * comments are allowed, using '#' syntax; and # * trailing commas are allowed. +# +# To generate expecations files in ./mb_config_expectations/, run the following +# from chromium/src directory: +# ./tools/mb/mb.py train -f ./tools/mb/mb_config.pyl { # Paths to gn_args_locations.json relative to the directory containing mb_config.pyl.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 8854bad..e2e0a6e 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -13332,11 +13332,6 @@ <int value="1" label="Using share group"/> </enum> -<enum name="BooleanShowing"> - <int value="0" label="Not Showing"/> - <int value="1" label="Showing"/> -</enum> - <enum name="BooleanShown"> <obsolete> Removed as of 06/2022 @@ -30578,13 +30573,6 @@ <int value="4" label="START_STICKY"/> </enum> -<enum name="DownloadNotPreferredOpeningInBrowserReason"> - <int value="0" label="TOTAL_DOWNLOAD_CHECKED"/> - <int value="1" label="DOWNLOAD_PATH_EMPTY"/> - <int value="2" label="NOT_PREFERRED_IN_DELEGATE"/> - <int value="3" label="CANNOT_BE_HANDLED_SAFELY"/> -</enum> - <enum name="DownloadOpenMethod"> <int value="0" label="Opened with plaform handler by default"/> <int value="1" label="Opened in browser by default"/> @@ -103440,7 +103428,7 @@ <int value="1" label="AutofillCreditCardEnabled"/> <int value="2" label="AutofillEnabledDeprecated"/> <int value="3" label="AutofillHasSeenIban"/> - <int value="4" label="AutofillIBANEnabled"/> + <int value="4" label="AutofillIBANEnabled (obsolete)"/> <int value="5" label="AutofillLastVersionDeduped"/> <int value="6" label="AutofillLastVersionDisusedAddressesDeleted"/> <int value="7" label="AutofillProfileEnabled"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index c32a99f..c446d8e 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -7275,7 +7275,7 @@ </summary> </histogram> -<histogram name="Ash.VideoConferenceTray.StopScreenSharingButton.Click" +<histogram name="Ash.VideoConferenceTray.StopScreenShareButton.Click" enum="BooleanClicked" expires_after="2024-03-16"> <owner>leandre@google.com</owner> <owner>cros-status-area-eng@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml index 64c049b..c10810d 100644 --- a/tools/metrics/histograms/metadata/download/histograms.xml +++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -155,12 +155,10 @@ <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> - Records each time a download command is executed on download bubble. For V1, - it is logged when the main button is clicked. For V2, it is logged when the - quick action is clicked. Actions on the security subpage is also included. - Actions on context menu are excluded. Clicking the trasparent button is also - excluded. This histogram is added for debugging purpose and will be removed - afterwards. + Records each time a download command is executed on download bubble. It is + logged when a quick action is clicked on the primary view or a button is + clicked on the subpage. Actions on context menu are excluded. Clicking the + trasparent button is also excluded. </summary> </histogram> @@ -242,30 +240,6 @@ <summary>Records why the download is canceled.</summary> </histogram> -<histogram name="Download.Complete.IsOpenWhenCompleteSet" enum="BooleanSet" - expires_after="2024-03-17"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records each time a non-temporary download is completed. If it is set to - true, this download will open immediately. This can happen if the user has - clicked the open button before the download is completed. This histogram is - added for debugging purpose and will be removed afterwards. - </summary> -</histogram> - -<histogram name="Download.Complete.IsShouldOpenFileBasedOnExtensionSet" - enum="BooleanSet" expires_after="2024-03-17"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records each time a non-temporary download is completed. If it is set to - true, this download will open immediately. This can happen if the user has - set auto open for this file type. This histogram is added for debugging - purpose and will be removed afterwards. - </summary> -</histogram> - <histogram name="Download.ContentType.Audio" enum="DownloadAudioType" expires_after="never"> <!-- expires-never: Monitors download system health. --> @@ -770,21 +744,6 @@ <summary>Network connection type when starting a new download.</summary> </histogram> -<histogram name="Download.NotPreferredOpeningInBrowserReasons" - enum="DownloadNotPreferredOpeningInBrowserReason" - expires_after="2024-03-17"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records each time when determining whether the download should be opened in - browser. For new download, it is logged when determining download target. - For old download, it is logged when the download is going to open or the - context menu is going to show. Logged at most one time for each download. - This histogram is added for debugging purpose and will be removed - afterwards. - </summary> -</histogram> - <histogram name="Download.Open.ContentType" enum="DownloadContentType" expires_after="2024-02-11"> <owner>drubery@chromium.org</owner> @@ -796,22 +755,6 @@ </summary> </histogram> -<histogram name="Download.OpenButtonPressed.IsDownloadCompleted" - enum="BooleanCompleted" expires_after="2024-03-17"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records each time a download open button is pressed, either on download - shelf or download bubble. If the open button is pressed before the download - is completed, the download will be auto opened when it is completed. If the - open button is pressed when the download is already completed, the download - will open immediately, either in browser or in system handler. The total - count of this histogram is useful to compare whether download bubble has - changed user behavior on clicking the open button. This histogram is added - for debugging purpose and will be removed afterwards. - </summary> -</histogram> - <histogram name="Download.OpenDownloads.PerProfileType" enum="BrowserProfileType" expires_after="2024-02-25"> <owner>sideyilmaz@chromium.org</owner> @@ -1151,47 +1094,6 @@ </summary> </histogram> -<histogram name="Download.Session.IsDownloadBubbleShowingWhenSession{Status}" - enum="BooleanShowing" expires_after="2024-02-20"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records if the download bubble is showing when session {Status}. See the - description in Session.TotalDuration for how session ends is defined. This - histogram is added for debugging purpose and will be removed afterwards. - </summary> - <token key="Status"> - <variant name="Ends" summary="ends"/> - <variant name="Starts" summary="starts"/> - </token> -</histogram> - -<histogram name="Download.Session.TotalDurationIncludingBubbleTime" units="ms" - expires_after="2024-03-17"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Similar to Session.TotalDuration, but add the time when the download bubble - is showing into the total session duration. In rare cases where the user - leaves Chrome when the bubble is showing, it may include that duration too. - This histogram is added for debugging purpose and will be removed - afterwards. - </summary> -</histogram> - -<histogram name="Download.SetAlwaysOpenTo" enum="BooleanEnabled" - expires_after="2024-03-17"> - <owner>xinghuilu@chromium.org</owner> - <owner>chrome-counter-abuse-alerts@google.com</owner> - <summary> - Records each time the auto open setting is changed by the user. If it is set - to true, this type of download will be auto opened once it is completed. - This setting is false by default. Changes on this setting are preserved - across startup. This histogram is added for debugging purpose and will be - removed afterwards. - </summary> -</histogram> - <histogram name="Download.Shelf.DragEvent" enum="Download.Shelf.DragEvent" expires_after="M77"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index c161139..8a1c52950 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -4857,7 +4857,7 @@ </histogram> <histogram name="DemoMode.IdleLogoutWarningEvent" - enum="DemoModeIdleLogoutWarningEvent" expires_after="2023-08-27"> + enum="DemoModeIdleLogoutWarningEvent" expires_after="2024-05-24"> <owner>llin@chromium.org</owner> <owner>xiqiruan@chromium.org</owner> <owner>yilkal@chromium.org</owner> @@ -4871,7 +4871,7 @@ </histogram> <histogram name="DemoMode.ResourcesRemoval.Reason" - enum="DemoModeResourcesRemovalReason" expires_after="M121"> + enum="DemoModeResourcesRemovalReason" expires_after="2024-05-24"> <owner>llin@chromium.org</owner> <owner>xiqiruan@chromium.org</owner> <owner>yilkal@chromium.org</owner> @@ -4885,7 +4885,7 @@ </histogram> <histogram name="DemoMode.ResourcesRemoval.Result" - enum="DemoModeResourcesRemovalResult" expires_after="M121"> + enum="DemoModeResourcesRemovalResult" expires_after="2024-05-24"> <owner>llin@chromium.org</owner> <owner>xiqiruan@chromium.org</owner> <owner>yilkal@chromium.org</owner> @@ -14719,7 +14719,7 @@ </histogram> <histogram name="WrenchMenu.TimeToAction.{Action}" units="ms" - expires_after="2023-10-01"> + expires_after="2024-10-01"> <owner>ainslie@chromium.org</owner> <owner>edwardjung@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index 70ecf62d3..97dd6592 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -979,7 +979,7 @@ </histogram> <histogram name="PasswordManager.BulkCheck.InsecureCredentials.Unmuted.Count" - units="credentials" expires_after="2023-11-01"> + units="credentials" expires_after="2024-03-01"> <owner>eic@google.com</owner> <owner>noemies@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml index a0f21ef..7839c3dc 100644 --- a/tools/metrics/histograms/metadata/platform/histograms.xml +++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -647,6 +647,18 @@ </summary> </histogram> +<histogram name="Platform.Hibernate.DroppedPagesWithZeroesPercent" units="%" + expires_after="2024-06-08"> + <owner>mka@chromium.org</owner> + <owner>bgeffon@chromium.org</owner> + <owner>chromeos-hibernate@google.com</owner> + <summary> + The percentage of pages that were dropped by the kernel from the hibernate + image because their content was all zeroes. Recorded after a successful + suspend to hibernate. + </summary> +</histogram> + <histogram name="Platform.Hibernate.Event" enum="CrosHibernateCycleEvent" expires_after="2024-06-08"> <owner>mka@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml index 348e46946..fda5bdc 100644 --- a/tools/metrics/histograms/metadata/signin/histograms.xml +++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -1133,7 +1133,7 @@ <histogram name="Signin.Reconciler.RejectedRequestsDueToThrottler.{RequestType}" - units="requests" expires_after="2023-09-30"> + units="requests" expires_after="2024-03-30"> <owner>droger@chromium.org</owner> <owner>msarda@chromium.org</owner> <owner>msalama@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml index 6edddc4e1..d75d0f9a 100644 --- a/tools/metrics/histograms/metadata/startup/histograms.xml +++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -580,7 +580,7 @@ </histogram> <histogram name="Startup.ConsecutiveDidFinishLaunchingWithoutLaunch" - units="count" expires_after="2023-10-04"> + units="count" expires_after="2024-09-18"> <owner>olivierrobin@chromium.org</owner> <owner>ajuma@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml index cbecb184..8d27949 100644 --- a/tools/metrics/histograms/metadata/sync/histograms.xml +++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -1397,38 +1397,6 @@ <summary>The type of event that triggered sync initialization.</summary> </histogram> -<histogram name="Sync.Startup.PolicyLoadStartupDelay" units="ms" - expires_after="2022-10-17"> - <obsolete> - Expired in M108. - </obsolete> - <owner>ydago@chromium.org</owner> - <owner>treib@chromium.org</owner> - <component>Services>Sync</component> - <summary> - The time spent waiting for policies to load before starting the sync engine. - This is recorded every time the sync engine is started after having to wait - for the browser policies from all sources to be loaded. In case the policy - service already had all of its policies loaded by the time the sync ending - starts, this records base::TimeDelta(). - </summary> -</histogram> - -<histogram name="Sync.Startup.PolicyLoadTimeout2" enum="BooleanTimedOut" - expires_after="2022-10-17"> - <obsolete> - Expired in M108. - </obsolete> - <owner>ydago@chromium.org</owner> - <owner>treib@chromium.org</owner> - <component>Services>Sync</component> - <summary> - Records if the policy load delay before starting the sync engine was timed - out. In case of a timeout, the sync engine attempts to start ignoring - potential policy restrictions. - </summary> -</histogram> - <histogram name="Sync.Startup.SignedInWithoutAccountInfo2" enum="BooleanIsSignedIn" expires_after="2024-06-15"> <owner>mastiz@chromium.org</owner>
diff --git a/ui/base/cocoa/permissions_utils.mm b/ui/base/cocoa/permissions_utils.mm index 86e982ce..c9c887eb 100644 --- a/ui/base/cocoa/permissions_utils.mm +++ b/ui/base/cocoa/permissions_utils.mm
@@ -11,7 +11,6 @@ #include "base/apple/foundation_util.h" #include "base/apple/scoped_cftyperef.h" #include "base/mac/mac_util.h" -#include "base/mac/wrap_cg_display.h" #include "base/task/thread_pool.h" namespace ui { @@ -68,7 +67,7 @@ // fail if the user denies permission, or if our application is already // in the system permission and is unchecked. base::apple::ScopedCFTypeRef<CGDisplayStreamRef> stream( - wrapCGDisplayStreamCreate( + CGDisplayStreamCreate( CGMainDisplayID(), 1, 1, 'BGRA', nullptr, ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef){
diff --git a/ui/base/ime/linux/input_method_auralinux.cc b/ui/base/ime/linux/input_method_auralinux.cc index ec47877..5942198 100644 --- a/ui/base/ime/linux/input_method_auralinux.cc +++ b/ui/base/ime/linux/input_method_auralinux.cc
@@ -6,7 +6,6 @@ #include "base/auto_reset.h" #include "base/environment.h" -#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/strings/utf_offset_string_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -15,7 +14,6 @@ #include "ui/base/ime/linux/linux_input_method_context_factory.h" #include "ui/base/ime/text_input_client.h" #include "ui/base/ime/text_input_flags.h" -#include "ui/base/ui_base_features.h" #include "ui/events/event.h" namespace { @@ -634,15 +632,8 @@ return; } } - { - bool set_composition_text_called = false; - if (base::FeatureList::IsEnabled( - features::kRedundantImeCompositionClearing)) { - set_composition_text_called = UpdateCompositionIfTextSelected(); - } - if (!set_composition_text_called) { - UpdateCompositionIfChanged(last_commit_result_ == CommitResult::kSuccess); - } + if (!UpdateCompositionIfTextSelected()) { + UpdateCompositionIfChanged(last_commit_result_ == CommitResult::kSuccess); } last_commit_result_.reset(); }
diff --git a/ui/base/metadata/metadata_macros_internal.h b/ui/base/metadata/metadata_macros_internal.h index ea161fd0..6a18d89 100644 --- a/ui/base/metadata/metadata_macros_internal.h +++ b/ui/base/metadata/metadata_macros_internal.h
@@ -17,6 +17,7 @@ // Metadata Accessors --------------------------------------------------------- #define METADATA_ACCESSORS_INTERNAL(class_name) \ + using kMetadataTag = class_name; \ static const char kViewClassName[]; \ const char* GetClassName() const override; \ static ui::metadata::ClassMetaData* MetaData(); \ @@ -38,6 +39,7 @@ // obtain the proper result from the static_cast<>. See |AsClass(void* obj)| // in property_metadata.h for additional info. #define METADATA_ACCESSORS_INTERNAL_BASE(class_name) \ + using kMetadataTag = class_name; \ static const char kViewClassName[]; \ virtual const char* GetClassName() const; \ static ui::metadata::ClassMetaData* MetaData(); \
diff --git a/ui/base/metadata/metadata_unittest.cc b/ui/base/metadata/metadata_unittest.cc index 1f594f4..989854c 100644 --- a/ui/base/metadata/metadata_unittest.cc +++ b/ui/base/metadata/metadata_unittest.cc
@@ -14,6 +14,7 @@ #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/metadata/metadata_types.h" +#include "ui/base/metadata/metadata_utils.h" #include "ui/gfx/geometry/insets.h" namespace UM = ui::metadata; @@ -111,6 +112,9 @@ METADATA_HEADER(ClassPropertyMetaDataTestClass); }; +// Test view which doesn't have metadata attached. +struct MetadataTestClassNoMetadata : public MetadataTestBaseClass {}; + DEFINE_UI_CLASS_PROPERTY_KEY(int, kIntKey, -1) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Insets, kOwnedInsetsKey1, nullptr) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Insets, kOwnedInsetsKey2, nullptr) @@ -258,3 +262,13 @@ verify(); } + +TEST_F(MetadataTest, TestHasMetaData) { + EXPECT_FALSE(UM::kHasClassMetadata<MetadataTestClassNoMetadata>); + EXPECT_TRUE(UM::kHasClassMetadata<ClassPropertyMetaDataTestClass>); + EXPECT_TRUE(UM::kHasClassMetadata<ClassPropertyMetaDataTestClass*>); + EXPECT_TRUE(UM::kHasClassMetadata<ClassPropertyMetaDataTestClass&>); + EXPECT_TRUE(UM::kHasClassMetadata<const ClassPropertyMetaDataTestClass>); + EXPECT_TRUE(UM::kHasClassMetadata<const ClassPropertyMetaDataTestClass*>); + EXPECT_TRUE(UM::kHasClassMetadata<const ClassPropertyMetaDataTestClass&>); +}
diff --git a/ui/base/metadata/metadata_utils.h b/ui/base/metadata/metadata_utils.h index 3425d46..52b9f72 100644 --- a/ui/base/metadata/metadata_utils.h +++ b/ui/base/metadata/metadata_utils.h
@@ -11,16 +11,30 @@ namespace ui::metadata { +template <typename T, typename = void> +static constexpr bool kHasClassMetadata = false; +template <typename T> +static constexpr bool kHasClassMetadata< + T, + std::void_t< + typename std::remove_cvref_t<std::remove_pointer_t<T>>::kMetadataTag>> = + std::is_same_v< + typename std::remove_cvref_t<std::remove_pointer_t<T>>::kMetadataTag, + typename std::remove_cvref_t<std::remove_pointer_t<T>>>; + template <typename V, typename B> bool IsClass(const B* instance) { if (!instance) { return false; } + static_assert(kHasClassMetadata<V>, + "Template param V doesn't implement metadata. Make sure class " + "publicly calls METADATA_HEADER in the declaration."); static_assert(std::is_base_of_v<B, V>, "Only classes derived from template param B allowed"); - const ui::metadata::ClassMetaData* child = instance->GetClassMetaData(); - for (const ui::metadata::ClassMetaData* parent = V::MetaData(); - child && child != parent; child = child->parent_class_meta_data()) + const ClassMetaData* child = instance->GetClassMetaData(); + for (const ClassMetaData* parent = V::MetaData(); child && child != parent; + child = child->parent_class_meta_data()) ; return !!child; }
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index 0344d8b..680d1f3e 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc
@@ -135,12 +135,6 @@ } #endif // BUILDFLAG(IS_CHROMEOS_ASH) -#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX) -BASE_FEATURE(kRedundantImeCompositionClearing, - "RedundantImeCompositionClearing", - base::FEATURE_ENABLED_BY_DEFAULT); -#endif // BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX) - // Update of the virtual keyboard settings UI as described in // https://crbug.com/876901. BASE_FEATURE(kInputMethodSettingsUiUpdate,
diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h index a66b18d..a87fa6d9 100644 --- a/ui/base/ui_base_features.h +++ b/ui/base/ui_base_features.h
@@ -143,11 +143,6 @@ COMPONENT_EXPORT(UI_BASE_FEATURES) bool AreF11AndF12ShortcutsEnabled(); #endif // BUILDFLAG(IS_CHROMEOS_ASH) -#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX) -COMPONENT_EXPORT(UI_BASE_FEATURES) -BASE_DECLARE_FEATURE(kRedundantImeCompositionClearing); -#endif // BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX) - // Indicates whether DrmOverlayManager should used the synchronous API to // perform pageflip tests. COMPONENT_EXPORT(UI_BASE_FEATURES)
diff --git a/ui/base/wayland/color_manager_util.h b/ui/base/wayland/color_manager_util.h index fa1dd422..9aac42a 100644 --- a/ui/base/wayland/color_manager_util.h +++ b/ui/base/wayland/color_manager_util.h
@@ -111,6 +111,9 @@ kDefaultSinceVersion)}, {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_SRGB, TransferVersion(gfx::ColorSpace::TransferID::SRGB, kDefaultSinceVersion)}, + {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_SRGB_HDR, + TransferVersion(gfx::ColorSpace::TransferID::SRGB_HDR, + ZCR_COLOR_MANAGER_V1_EOTF_NAMES_SRGB_HDR_SINCE_VERSION)}, {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_BT709, TransferVersion(gfx::ColorSpace::TransferID::BT709, ZCR_COLOR_MANAGER_V1_EOTF_NAMES_BT709_SINCE_VERSION)}, @@ -195,7 +198,7 @@ base::MakeFixedFlatMap<zcr_color_manager_v1_eotf_names, TransferFnVersion>( {{ZCR_COLOR_MANAGER_V1_EOTF_NAMES_LINEAR, TransferFnVersion(SkNamedTransferFn::kLinear, kDefaultSinceVersion)}, - {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_SRGB, + {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_SRGB_HDR, TransferFnVersion(SkNamedTransferFnExt::kSRGB, kDefaultSinceVersion)}, {ZCR_COLOR_MANAGER_V1_EOTF_NAMES_PQ, TransferFnVersion(SkNamedTransferFn::kPQ, kDefaultSinceVersion)},
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.cc b/ui/views/accessibility/view_ax_platform_node_delegate.cc index af5ee76..96a8e2d8 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate.cc
@@ -305,8 +305,7 @@ data_.AddState(ax::mojom::State::kIgnored); #if BUILDFLAG(IS_WIN) - if (features::IsUiaProviderEnabled() && - view()->GetViewAccessibility().needs_ax_tree_manager()) { + if (view()->GetViewAccessibility().needs_ax_tree_manager()) { view()->GetViewAccessibility().EnsureAtomicViewAXTreeManager(); } #endif // BUILDFLAG(IS_WIN)
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_win.cc b/ui/views/accessibility/view_ax_platform_node_delegate_win.cc index 2f40ce1..c37339f7 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate_win.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate_win.cc
@@ -108,7 +108,6 @@ } void ViewAXPlatformNodeDelegateWin::EnsureAtomicViewAXTreeManager() { - DCHECK(features::IsUiaProviderEnabled()); DCHECK(needs_ax_tree_manager()); if (atomic_view_ax_tree_manager_) { return;
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm index 65e513f28..8b7fa02 100644 --- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm +++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -4,9 +4,6 @@ #include "ui/views/cocoa/native_widget_mac_ns_window_host.h" -#include <AvailabilityMacros.h> -#include <AvailabilityVersions.h> - #include <tuple> #include <utility> @@ -58,16 +55,6 @@ using remote_cocoa::mojom::NativeWidgetNSWindowInitParams; using remote_cocoa::mojom::WindowVisibilityState; -#if !defined(MAC_OS_VERSION_14_0) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_14_0 - -@interface NSApplication () -- (void)yieldActivationToApplicationWithBundleIdentifier: - (NSString*)bundleIdentifier API_AVAILABLE(macos(14.0)); -@end - -#endif - namespace views { namespace {
diff --git a/v8 b/v8 index 42b3dee..160c55f 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 42b3deee7cc595ffeb9b77505cabe460f7e71b91 +Subproject commit 160c55f1d4b89c8a9e249130838d9e729325b528
diff --git a/weblayer/API_OWNERS b/weblayer/API_OWNERS deleted file mode 100644 index 6351802..0000000 --- a/weblayer/API_OWNERS +++ /dev/null
@@ -1,11 +0,0 @@ -# WebLayer API owners are responsible for the direction, consistency, and -# overall usability of the WebLayer API. -# -blundell@chromium.org -boliu@chromium.org -cduvall@chromium.org -jam@chromium.org -peconn@chromium.org -peter@chromium.org -rayankans@chromium.org -sky@chromium.org
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn deleted file mode 100644 index 5035a582..0000000 --- a/weblayer/BUILD.gn +++ /dev/null
@@ -1,908 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -import("//components/captive_portal/core/features.gni") - -import("//build/config/cronet/config.gni") -import("//build/config/features.gni") -import("//build/config/locales.gni") -import("//build/config/sanitizers/sanitizers.gni") -import("//build/config/ui.gni") -import("//build/config/win/console_app.gni") -import("//build/config/win/manifest.gni") -import("//components/services/screen_ai/buildflags/features.gni") -import("//components/signin/features.gni") -import("//components/spellcheck/spellcheck_build_features.gni") -import("//device/vr/buildflags/buildflags.gni") -import("//gpu/vulkan/features.gni") -import("//media/media_options.gni") -import("//mojo/public/tools/bindings/mojom.gni") -import("//pdf/features.gni") -import("//printing/buildflags/buildflags.gni") -import("//tools/grit/grit_rule.gni") -import("//tools/grit/repack.gni") -import("//tools/v8_context_snapshot/v8_context_snapshot.gni") -if (is_android) { - import("//build/config/android/config.gni") - import("//build/config/android/rules.gni") - import("//build/config/features.gni") - import("//components/safe_browsing/buildflags.gni") - import("//third_party/jni_zero/jni_zero.gni") -} else if (is_mac) { - import("//build/apple/tweak_info_plist.gni") - import("//build/config/mac/rules.gni") - import("//content/public/app/mac_helpers.gni") - import("//third_party/icu/config.gni") - import("//ui/gl/features.gni") - import("//v8/gni/v8.gni") -} - -assert(!is_cronet_build) - -source_set("android_descriptors") { - sources = [ "browser/android_descriptors.h" ] - public_deps = [ "//content/public/common:content_descriptors" ] -} - -if (is_android) { - weblayer_components_strings_java_resources = - [ "java/res/values/components_strings.xml" ] + - process_file_template( - android_bundle_locales_as_resources, - [ "java/res/values-{{source_name_part}}/components_strings.xml" ]) - - grit("generate_components_strings") { - source = "../components/components_strings.grd" - - defines = [ - "enable_arcore=$enable_arcore", - "enable_pdf=$enable_pdf", - "enable_print_preview=$enable_print_preview", - "enable_screen_ai_service=$enable_screen_ai_service", - "enable_search_engine_choice=$enable_search_engine_choice", - "enable_vr=$enable_vr", - "use_blink=$use_blink", - ] - - # components_strings contains strings from all components. WebLayer - # will never display most of them, so we try to limit the included - # strings. - allowlist = rebase_path("grit_strings_allowlist.txt", root_build_dir) - inputs = [ "//weblayer/grit_strings_allowlist.txt" ] - grit_flags = [ - "-w", - allowlist, - ] - outputs = - weblayer_components_strings_java_resources + - [ "grit/components_strings.h" ] + - process_file_template(all_chrome_locales, - [ "components_strings_{{source_name_part}}.pak" ]) - } - - grit("generate_components_branded_strings") { - source = "../components/components_chromium_strings.grd" - - # components_branded_strings contains Chromium-specific strings. WebLayer - # will never display most of them, so we try to limit the included - # strings. - allowlist = rebase_path("grit_strings_allowlist.txt", root_build_dir) - inputs = [ "//weblayer/grit_strings_allowlist.txt" ] - grit_flags = [ - "-w", - allowlist, - ] - outputs = [ "grit/components_branded_strings.h" ] + - process_file_template( - all_chrome_locales, - [ "components_chromium_strings_{{source_name_part}}.pak" ]) - } - - repack_locales("weblayer_locales") { - input_locales = platform_pak_locales - output_locales = platform_pak_locales - source_patterns = [ - "${root_gen_dir}/components/strings/components_locale_settings_", - "${root_gen_dir}/device/bluetooth/strings/bluetooth_strings_", - "${root_gen_dir}/weblayer/components_chromium_strings_", - "${root_gen_dir}/weblayer/components_strings_", - ] - deps = [ - ":generate_components_branded_strings", - ":generate_components_strings", - "//components/strings:components_locale_settings", - "//device/bluetooth/strings", - ] - output_dir = "$root_out_dir/weblayer/locales" - } - - android_assets("locale_pak_assets") { - disable_compression = true - renaming_sources = [ "$root_out_dir/weblayer/locales/en-US.pak" ] - renaming_destinations = [ "stored-locales/weblayer/en-US.pak" ] - treat_as_locale_paks = true - deps = [ ":weblayer_locales" ] - } - - android_assets("bundle_locale_pak_assets") { - disable_compression = true - renaming_sources = [] - renaming_destinations = [] - foreach(_locale, platform_pak_locales) { - renaming_sources += [ "$root_out_dir/weblayer/locales/$_locale.pak" ] - renaming_destinations += [ "locales/$_locale.pak" ] - } - treat_as_locale_paks = true - deps = [ ":weblayer_locales" ] - } - - java_strings_grd_prebuilt("components_java_strings") { - resource_overlay = true - grit_output_dir = "$root_gen_dir/weblayer/java/res" - generated_files = - rebase_path(weblayer_components_strings_java_resources, "java/res", ".") - deps = [ ":generate_components_strings" ] - } -} - -mojom("common_mojom") { - disable_variants = true - - sources = [ - "common/error_page_helper.mojom", - "common/renderer_configuration.mojom", - ] - deps = [ - "//components/content_settings/common:mojom", - "//components/content_settings/core/common:mojo_bindings", - ] -} - -source_set("weblayer_lib_base") { - sources = [ - "app/content_main_delegate_impl.cc", - "app/content_main_delegate_impl.h", - "app/main.cc", - "browser/accept_languages_service_factory.cc", - "browser/accept_languages_service_factory.h", - "browser/autocomplete_scheme_classifier_impl.cc", - "browser/autocomplete_scheme_classifier_impl.h", - "browser/autofill_client_impl.cc", - "browser/autofill_client_impl.h", - "browser/background_download_service_factory.cc", - "browser/background_download_service_factory.h", - "browser/background_fetch/background_fetch_delegate_factory.cc", - "browser/background_fetch/background_fetch_delegate_factory.h", - "browser/background_fetch/background_fetch_delegate_impl.cc", - "browser/background_fetch/background_fetch_delegate_impl.h", - "browser/background_fetch/background_fetch_download.cc", - "browser/background_fetch/background_fetch_download.h", - "browser/background_fetch/background_fetch_permission_context.cc", - "browser/background_fetch/background_fetch_permission_context.h", - "browser/background_sync/background_sync_controller_factory.cc", - "browser/background_sync/background_sync_controller_factory.h", - "browser/background_sync/background_sync_delegate_impl.cc", - "browser/background_sync/background_sync_delegate_impl.h", - "browser/bluetooth/weblayer_bluetooth_chooser_context_factory.cc", - "browser/bluetooth/weblayer_bluetooth_chooser_context_factory.h", - "browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc", - "browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h", - "browser/browser_context_impl.cc", - "browser/browser_context_impl.h", - "browser/browser_fragment_impl.cc", - "browser/browser_fragment_impl.h", - "browser/browser_fragment_list.cc", - "browser/browser_fragment_list.h", - "browser/browser_fragment_list_observer.h", - "browser/browser_impl.cc", - "browser/browser_impl.h", - "browser/browser_list.cc", - "browser/browser_list.h", - "browser/browser_list_observer.h", - "browser/browser_main_parts_impl.cc", - "browser/browser_main_parts_impl.h", - "browser/browser_process.cc", - "browser/browser_process.h", - "browser/browsing_data_remover_delegate.cc", - "browser/browsing_data_remover_delegate.h", - "browser/browsing_data_remover_delegate_factory.cc", - "browser/browsing_data_remover_delegate_factory.h", - "browser/client_hints_factory.cc", - "browser/client_hints_factory.h", - "browser/content_browser_client_impl.cc", - "browser/content_browser_client_impl.h", - "browser/content_browser_client_impl_receiver_bindings.cc", - "browser/content_settings_manager_delegate.cc", - "browser/content_settings_manager_delegate.h", - "browser/cookie_manager_impl.cc", - "browser/cookie_manager_impl.h", - "browser/cookie_settings_factory.cc", - "browser/cookie_settings_factory.h", - "browser/download_impl.cc", - "browser/download_impl.h", - "browser/download_manager_delegate_impl.cc", - "browser/download_manager_delegate_impl.h", - "browser/favicon/favicon_backend_wrapper.cc", - "browser/favicon/favicon_backend_wrapper.h", - "browser/favicon/favicon_fetcher_impl.cc", - "browser/favicon/favicon_fetcher_impl.h", - "browser/favicon/favicon_service_impl.cc", - "browser/favicon/favicon_service_impl.h", - "browser/favicon/favicon_service_impl_factory.cc", - "browser/favicon/favicon_service_impl_factory.h", - "browser/favicon/favicon_service_impl_observer.h", - "browser/favicon/favicon_tab_helper.cc", - "browser/favicon/favicon_tab_helper.h", - "browser/feature_list_creator.cc", - "browser/feature_list_creator.h", - "browser/file_select_helper.cc", - "browser/file_select_helper.h", - "browser/heavy_ad_service_factory.cc", - "browser/heavy_ad_service_factory.h", - "browser/host_content_settings_map_factory.cc", - "browser/host_content_settings_map_factory.h", - "browser/i18n_util.cc", - "browser/i18n_util.h", - "browser/insecure_form_controller_client.cc", - "browser/insecure_form_controller_client.h", - "browser/navigation_controller_impl.cc", - "browser/navigation_controller_impl.h", - "browser/navigation_entry_data.cc", - "browser/navigation_entry_data.h", - "browser/navigation_error_navigation_throttle.cc", - "browser/navigation_error_navigation_throttle.h", - "browser/navigation_impl.cc", - "browser/navigation_impl.h", - "browser/navigation_ui_data_impl.cc", - "browser/navigation_ui_data_impl.h", - "browser/no_state_prefetch/no_state_prefetch_link_manager_factory.cc", - "browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h", - "browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.cc", - "browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.h", - "browser/no_state_prefetch/no_state_prefetch_manager_factory.cc", - "browser/no_state_prefetch/no_state_prefetch_manager_factory.h", - "browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.cc", - "browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.h", - "browser/no_state_prefetch/no_state_prefetch_utils.cc", - "browser/no_state_prefetch/no_state_prefetch_utils.h", - "browser/no_state_prefetch/prerender_controller_impl.cc", - "browser/no_state_prefetch/prerender_controller_impl.h", - "browser/no_state_prefetch/prerender_tab_helper.cc", - "browser/no_state_prefetch/prerender_tab_helper.h", - "browser/origin_trials_factory.cc", - "browser/origin_trials_factory.h", - "browser/page_impl.cc", - "browser/page_impl.h", - "browser/page_load_metrics_initialize.cc", - "browser/page_load_metrics_initialize.h", - "browser/page_load_metrics_observer_impl.cc", - "browser/page_load_metrics_observer_impl.h", - "browser/page_specific_content_settings_delegate.cc", - "browser/page_specific_content_settings_delegate.h", - "browser/password_manager_driver_factory.cc", - "browser/password_manager_driver_factory.h", - "browser/permissions/geolocation_permission_context_delegate.cc", - "browser/permissions/geolocation_permission_context_delegate.h", - "browser/permissions/origin_keyed_permission_action_service_factory.cc", - "browser/permissions/origin_keyed_permission_action_service_factory.h", - "browser/permissions/permission_decision_auto_blocker_factory.cc", - "browser/permissions/permission_decision_auto_blocker_factory.h", - "browser/permissions/permission_manager_factory.cc", - "browser/permissions/permission_manager_factory.h", - "browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.cc", - "browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.h", - "browser/permissions/weblayer_nfc_permission_context_delegate.cc", - "browser/permissions/weblayer_nfc_permission_context_delegate.h", - "browser/permissions/weblayer_permissions_client.cc", - "browser/permissions/weblayer_permissions_client.h", - "browser/persistence/browser_persistence_common.cc", - "browser/persistence/browser_persistence_common.h", - "browser/persistence/browser_persister.cc", - "browser/persistence/browser_persister.h", - "browser/persistence/browser_persister_file_utils.cc", - "browser/persistence/browser_persister_file_utils.h", - "browser/persistent_download.cc", - "browser/persistent_download.h", - "browser/popup_navigation_delegate_impl.cc", - "browser/popup_navigation_delegate_impl.h", - "browser/profile_disk_operations.cc", - "browser/profile_disk_operations.h", - "browser/profile_impl.cc", - "browser/profile_impl.h", - "browser/reduce_accept_language_factory.cc", - "browser/reduce_accept_language_factory.h", - "browser/signin_url_loader_throttle.cc", - "browser/signin_url_loader_throttle.h", - "browser/ssl_error_controller_client.cc", - "browser/ssl_error_controller_client.h", - "browser/stateful_ssl_host_state_delegate_factory.cc", - "browser/stateful_ssl_host_state_delegate_factory.h", - "browser/subresource_filter_profile_context_factory.cc", - "browser/subresource_filter_profile_context_factory.h", - "browser/system_network_context_manager.cc", - "browser/system_network_context_manager.h", - "browser/tab_impl.cc", - "browser/tab_impl.h", - "browser/tracking_protection_settings_factory.cc", - "browser/tracking_protection_settings_factory.h", - "browser/translate_client_impl.cc", - "browser/translate_client_impl.h", - "browser/translate_ranker_factory.cc", - "browser/translate_ranker_factory.h", - "browser/web_contents_view_delegate_impl.cc", - "browser/web_contents_view_delegate_impl.h", - "browser/web_data_service_factory.cc", - "browser/web_data_service_factory.h", - "browser/weblayer_browser_interface_binders.cc", - "browser/weblayer_browser_interface_binders.h", - "browser/weblayer_features.cc", - "browser/weblayer_features.h", - "browser/weblayer_field_trials.cc", - "browser/weblayer_field_trials.h", - "browser/weblayer_metrics_service_accessor.h", - "browser/weblayer_page_load_metrics_memory_tracker_factory.cc", - "browser/weblayer_page_load_metrics_memory_tracker_factory.h", - "browser/weblayer_security_blocking_page_factory.cc", - "browser/weblayer_security_blocking_page_factory.h", - "browser/weblayer_speech_recognition_manager_delegate.cc", - "browser/weblayer_speech_recognition_manager_delegate.h", - "browser/weblayer_variations_service_client.cc", - "browser/weblayer_variations_service_client.h", - "browser/webui/net_export_ui.cc", - "browser/webui/net_export_ui.h", - "browser/webui/web_ui_controller_factory.cc", - "browser/webui/web_ui_controller_factory.h", - "browser/webui/weblayer_internals_ui.cc", - "browser/webui/weblayer_internals_ui.h", - "common/content_client_impl.cc", - "common/content_client_impl.h", - "common/features.cc", - "common/features.h", - "common/isolated_world_ids.h", - "common/weblayer_paths.cc", - "common/weblayer_paths.h", - "public/browser.cc", - "public/browser.h", - "public/browser_observer.h", - "public/browser_restore_observer.h", - "public/common/switches.cc", - "public/common/switches.h", - "public/cookie_manager.h", - "public/download.h", - "public/download_delegate.h", - "public/error_page.h", - "public/error_page_delegate.h", - "public/favicon_fetcher.h", - "public/favicon_fetcher_delegate.h", - "public/fullscreen_delegate.h", - "public/google_account_access_token_fetch_delegate.h", - "public/google_accounts_delegate.h", - "public/main.h", - "public/navigation.h", - "public/navigation_controller.h", - "public/navigation_observer.h", - "public/new_tab_delegate.h", - "public/page.h", - "public/prerender_controller.h", - "public/profile.h", - "public/tab.h", - "public/tab_observer.h", - "renderer/content_renderer_client_impl.cc", - "renderer/content_renderer_client_impl.h", - "renderer/error_page_helper.cc", - "renderer/error_page_helper.h", - "renderer/url_loader_throttle_provider.cc", - "renderer/url_loader_throttle_provider.h", - "renderer/weblayer_render_frame_observer.cc", - "renderer/weblayer_render_frame_observer.h", - "renderer/weblayer_render_thread_observer.cc", - "renderer/weblayer_render_thread_observer.h", - ] - - configs += [ "//build/config:precompiled_headers" ] - - public_deps = [ ":android_descriptors" ] - deps = [ - ":common_mojom", - "//base", - "//base:base_static", - "//base/third_party/dynamic_annotations", - "//build:chromeos_buildflags", - "//components/autofill/content/browser", - "//components/autofill/content/renderer", - "//components/autofill/core/browser", - "//components/autofill/core/common", - "//components/autofill/core/common:features", - "//components/background_fetch", - "//components/background_sync", - "//components/base32", - "//components/blocked_content", - "//components/browsing_data/content", - "//components/captive_portal/core:buildflags", - "//components/cdm/renderer", - "//components/client_hints/browser", - "//components/content_capture/browser", - "//components/content_capture/common", - "//components/content_capture/renderer", - "//components/content_relationship_verification", - "//components/content_settings/browser", - "//components/content_settings/common:mojom", - "//components/content_settings/common:mojom", - "//components/content_settings/core/browser", - "//components/content_settings/renderer", - "//components/crash/content/browser", - "//components/crash/core/app", - "//components/crash/core/common", - "//components/download/content/factory", - "//components/download/content/public", - "//components/download/public/background_service:public", - "//components/download/public/task:public", - "//components/embedder_support", - "//components/embedder_support:browser_util", - "//components/embedder_support/origin_trials", - "//components/error_page/common", - "//components/error_page/content/browser", - "//components/favicon/content", - "//components/favicon/core", - "//components/favicon/core:database", - "//components/favicon_base", - "//components/find_in_page", - "//components/heavy_ad_intervention", - "//components/infobars/content", - "//components/infobars/core", - "//components/keyed_service/content", - "//components/language/core/browser", - "//components/leveldb_proto", - "//components/metrics", - "//components/net_log", - "//components/network_time", - "//components/no_state_prefetch/browser", - "//components/no_state_prefetch/common", - "//components/no_state_prefetch/common:mojo_bindings", - "//components/no_state_prefetch/renderer", - "//components/omnibox/browser:browser", - "//components/origin_trials:browser", - "//components/origin_trials:common", - "//components/page_info", - "//components/page_load_metrics/browser", - "//components/page_load_metrics/browser/observers/ad_metrics", - "//components/page_load_metrics/renderer", - "//components/password_manager/content/browser", - "//components/payments/content:content", - "//components/payments/core", - "//components/performance_manager", - "//components/permissions", - "//components/policy/core/browser", - "//components/pref_registry:pref_registry", - "//components/prefs", - "//components/profile_metrics", - "//components/reduce_accept_language/browser", - "//components/safe_browsing:buildflags", - "//components/safe_browsing/content/browser", - "//components/safe_browsing/content/browser:client_side_detection", - "//components/safe_browsing/content/browser/web_ui", - "//components/safe_browsing/content/common:interfaces", - "//components/safe_browsing/content/renderer:throttles", - "//components/safe_browsing/content/renderer/phishing_classifier", - "//components/safe_browsing/core/browser:safe_browsing_metrics_collector", - "//components/safe_browsing/core/browser/db:database_manager", - "//components/safe_browsing/core/common", - "//components/security_interstitials/content:security_interstitial_page", - "//components/security_interstitials/content/renderer:security_interstitial_page_controller", - "//components/security_interstitials/core", - "//components/security_state/content", - "//components/services/storage/public/mojom", - "//components/sessions", - "//components/signin/core/browser", - "//components/site_engagement/content", - "//components/site_isolation", - "//components/spellcheck:buildflags", - "//components/ssl_errors", - "//components/startup_metric_utils", - "//components/strings", - "//components/subresource_filter/content/browser", - "//components/subresource_filter/content/renderer", - "//components/subresource_filter/core/browser", - "//components/subresource_filter/core/browser", - "//components/subresource_filter/core/common", - "//components/translate/content/browser", - "//components/translate/content/renderer", - "//components/translate/core/browser", - "//components/translate/core/common", - "//components/ukm", - "//components/ukm/content", - "//components/unified_consent:unified_consent", - "//components/user_prefs", - "//components/variations", - "//components/variations:variations_mojom", - "//components/variations/net", - "//components/variations/proto", - "//components/variations/service", - "//components/version_info", - "//components/viz/common", - "//components/web_cache/browser", - "//components/webapps/browser", - "//components/webapps/renderer", - "//components/webdata_services", - "//components/webrtc", - "//content:content_resources", - "//content/public/app", - "//content/public/browser", - "//content/public/child", - "//content/public/common", - "//content/public/renderer", - "//content/public/utility", - "//device/base:base", - "//device/vr/buildflags", - "//gpu/config", - "//net", - "//net:net_resources", - "//sandbox", - "//services/cert_verifier/public/mojom", - "//services/metrics/public/cpp:metrics_cpp", - "//services/network/public/cpp", - "//services/network/public/mojom", - "//services/preferences/tracked", - "//skia", - "//third_party/blink/public:blink_headers", - "//third_party/blink/public/common", - "//third_party/blink/public/strings", - "//third_party/icu", - "//ui/base", - "//ui/base/clipboard", - "//ui/base/ime/init", - "//ui/display", - "//ui/events:events_base", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gfx/ipc", - "//ui/gfx/ipc/geometry", - "//ui/gfx/ipc/skia", - "//ui/gl", - "//ui/platform_window", - "//ui/shell_dialogs", - "//ui/webui", - "//url", - "//v8", - "//weblayer:resources", - "//weblayer/browser/webui:mojo_bindings", - ] - - if (enable_captive_portal_detection) { - sources += [ - "browser/captive_portal_service_factory.cc", - "browser/captive_portal_service_factory.h", - ] - deps += [ "//components/captive_portal/content" ] - } - - if (enable_arcore) { - assert(is_android) - sources += [ - "browser/xr/xr_integration_client_impl.cc", - "browser/xr/xr_integration_client_impl.h", - ] - deps += [ - "//components/webxr/android", - "//device/vr/android/arcore", - ] - } - - if (use_browser_spellchecker) { - deps += [ - "//components/spellcheck/browser", - "//components/spellcheck/renderer", - ] - } - - if (is_android) { - sources += [ - "app/jni_onload.cc", - "app/jni_onload.h", - "browser/android/application_info_helper.cc", - "browser/android/application_info_helper.h", - "browser/android/exception_filter.cc", - "browser/android/exception_filter.h", - "browser/android/metrics/uma_utils.cc", - "browser/android/metrics/uma_utils.h", - "browser/android/metrics/weblayer_metrics_service_client.cc", - "browser/android/metrics/weblayer_metrics_service_client.h", - "browser/android/permission_request_utils.cc", - "browser/android/permission_request_utils.h", - "browser/android/resource_mapper.cc", - "browser/android/resource_mapper.h", - "browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.cc", - "browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.h", - "browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.cc", - "browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.h", - "browser/browser_list_proxy.cc", - "browser/browser_list_proxy.h", - "browser/component_updater/registration.cc", - "browser/component_updater/registration.h", - "browser/content_view_render_view.cc", - "browser/content_view_render_view.h", - "browser/devtools_manager_delegate_android.cc", - "browser/devtools_manager_delegate_android.h", - "browser/devtools_server_android.cc", - "browser/devtools_server_android.h", - "browser/download_callback_proxy.cc", - "browser/download_callback_proxy.h", - "browser/error_page_callback_proxy.cc", - "browser/error_page_callback_proxy.h", - "browser/favicon/favicon_callback_proxy.cc", - "browser/favicon/favicon_callback_proxy.h", - "browser/fullscreen_callback_proxy.cc", - "browser/fullscreen_callback_proxy.h", - "browser/google_account_access_token_fetcher_proxy.cc", - "browser/google_account_access_token_fetcher_proxy.h", - "browser/google_accounts_callback_proxy.cc", - "browser/google_accounts_callback_proxy.h", - "browser/http_auth_handler_impl.cc", - "browser/http_auth_handler_impl.h", - "browser/infobar_container_android.cc", - "browser/infobar_container_android.h", - "browser/javascript_tab_modal_dialog_manager_delegate_android.cc", - "browser/javascript_tab_modal_dialog_manager_delegate_android.h", - "browser/media/local_presentation_manager_factory.cc", - "browser/media/local_presentation_manager_factory.h", - "browser/media/media_router_factory.cc", - "browser/media/media_router_factory.h", - "browser/new_tab_callback_proxy.cc", - "browser/new_tab_callback_proxy.h", - "browser/proxying_url_loader_factory_impl.cc", - "browser/proxying_url_loader_factory_impl.h", - "browser/safe_browsing/client_side_detection_service_factory.cc", - "browser/safe_browsing/client_side_detection_service_factory.h", - "browser/safe_browsing/real_time_url_lookup_service_factory.cc", - "browser/safe_browsing/real_time_url_lookup_service_factory.h", - "browser/safe_browsing/safe_browsing_metrics_collector_factory.cc", - "browser/safe_browsing/safe_browsing_metrics_collector_factory.h", - "browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc", - "browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h", - "browser/safe_browsing/safe_browsing_service.cc", - "browser/safe_browsing/safe_browsing_service.h", - "browser/safe_browsing/safe_browsing_token_fetcher_impl.cc", - "browser/safe_browsing/safe_browsing_token_fetcher_impl.h", - "browser/safe_browsing/url_checker_delegate_impl.cc", - "browser/safe_browsing/url_checker_delegate_impl.h", - "browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc", - "browser/safe_browsing/weblayer_client_side_detection_host_delegate.h", - "browser/safe_browsing/weblayer_client_side_detection_service_delegate.cc", - "browser/safe_browsing/weblayer_client_side_detection_service_delegate.h", - "browser/safe_browsing/weblayer_ping_manager_factory.cc", - "browser/safe_browsing/weblayer_ping_manager_factory.h", - "browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc", - "browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.h", - "browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.cc", - "browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.h", - "browser/safe_browsing/weblayer_ui_manager_delegate.cc", - "browser/safe_browsing/weblayer_ui_manager_delegate.h", - "browser/safe_browsing/weblayer_user_population_helper.cc", - "browser/safe_browsing/weblayer_user_population_helper.h", - "browser/site_engagement/site_engagement_service_factory.cc", - "browser/site_engagement/site_engagement_service_factory.h", - "browser/tab_callback_proxy.cc", - "browser/tab_callback_proxy.h", - "browser/translate_compact_infobar.cc", - "browser/translate_compact_infobar.h", - "browser/tts_environment_android_impl.cc", - "browser/tts_environment_android_impl.h", - "browser/verdict_cache_manager_factory.cc", - "browser/verdict_cache_manager_factory.h", - "browser/webapps/webapk_install_scheduler.cc", - "browser/webapps/webapk_install_scheduler.h", - "browser/webapps/webapk_install_scheduler_bridge.cc", - "browser/webapps/webapk_install_scheduler_bridge.h", - "browser/webapps/webapps_utils.cc", - "browser/webapps/webapps_utils.h", - "browser/webapps/weblayer_app_banner_manager_android.cc", - "browser/webapps/weblayer_app_banner_manager_android.h", - "browser/webapps/weblayer_webapps_client.cc", - "browser/webapps/weblayer_webapps_client.h", - "browser/weblayer_factory_impl_android.cc", - "browser/weblayer_factory_impl_android.h", - "browser/weblayer_impl_android.cc", - "browser/weblayer_impl_android.h", - "browser/webrtc/media_stream_manager.cc", - "browser/webrtc/media_stream_manager.h", - "common/crash_reporter/crash_keys.cc", - "common/crash_reporter/crash_keys.h", - "common/crash_reporter/crash_reporter_client.cc", - "common/crash_reporter/crash_reporter_client.h", - ] - deps += [ - "//cc/slim", - "//components/android_autofill/browser", - "//components/android_autofill/browser:android", - "//components/android_system_error_page", - "//components/browser_ui/accessibility/android", - "//components/browser_ui/client_certificate/android", - "//components/browser_ui/contacts_picker/android", - "//components/browser_ui/photo_picker/android", - "//components/browser_ui/share/android", - "//components/browser_ui/site_settings/android", - "//components/browser_ui/sms/android", - "//components/cdm/browser", - "//components/component_updater/android:embedded_component_loader", - "//components/component_updater/installer_policies", - "//components/content_capture/android", - "//components/content_settings/android", - "//components/crash/android:crash_android", - "//components/crash/android:crashpad_main", - "//components/embedder_support/android:context_menu", - "//components/embedder_support/android:util", - "//components/embedder_support/android:web_contents_delegate", - "//components/embedder_support/android/metrics", - "//components/external_intents/android", - "//components/favicon/android", - "//components/image_fetcher:android", - "//components/infobars/android", - "//components/installedapp/android", - "//components/javascript_dialogs", - "//components/location/android:settings", - "//components/media_router/browser", - "//components/metrics", - "//components/metrics:content", - "//components/minidump_uploader", - "//components/navigation_interception", - "//components/page_info/android", - "//components/payments/content/android", - "//components/permissions/android:native", - "//components/resources:android_resources", - "//components/safe_browsing/android:remote_database_manager", - "//components/safe_browsing/android:safe_browsing_api_handler", - "//components/safe_browsing/content/browser/triggers", - "//components/safe_browsing/core/browser", - "//components/safe_browsing/core/browser:token_fetcher", - "//components/safe_browsing/core/browser:verdict_cache_manager", - "//components/safe_browsing/core/browser/db:allowlist_checker_client", - "//components/safe_browsing/core/browser/db:database_manager", - "//components/safe_browsing/core/browser/hashprefix_realtime:hash_realtime_utils", - "//components/safe_browsing/core/browser/realtime:policy_engine", - "//components/safe_browsing/core/browser/realtime:url_lookup_service", - "//components/safe_browsing/core/common", - "//components/safe_browsing/core/common/proto:client_model_proto", - "//components/safe_browsing/core/common/proto:csd_proto", - "//components/security_interstitials/content:security_interstitial_page", - "//components/security_interstitials/core:unsafe_resource", - "//components/security_interstitials/core/", - "//components/security_state/content/android", - "//components/site_engagement/content", - "//components/subresource_filter/android", - "//components/translate/content/android", - "//components/version_info/android:channel_getter", - "//components/webauthn/android", - "//google_apis", - "//services/resource_coordinator/public/cpp/memory_instrumentation:browser", - "//ui/android", - "//url:gurl_android", - "//weblayer/browser/java:base_module_jni", - "//weblayer/browser/java:jni", - ] - - # Necessary to avoid GN errors in Cast builds, where this target isn't defined. - if (safe_browsing_mode > 0) { - deps += [ "//components/safe_browsing/content/browser:safe_browsing_blocking_page" ] - } - } else { - deps += [ "//ui/views/controls/webview" ] - } - - if (enable_vulkan) { - deps += [ "//gpu/vulkan/init" ] - } - if (mojo_media_host == "browser") { - deps += [ "//media/mojo/services" ] - } - - if (is_win) { - deps += [ "//content:sandbox_helper_win" ] - if (win_console_app) { - defines = [ "WIN_CONSOLE_APP" ] - } - } - - if (is_linux || is_chromeos) { - deps += [ - "//build/config/freetype", - "//third_party/fontconfig", - ] - } - - if (toolkit_views) { - deps += [ "//ui/views" ] - } - - if (use_aura) { - deps += [ - "//ui/aura", - "//ui/events", - "//ui/strings", - "//ui/wm", - ] - } -} - -if (is_android) { - source_set("weblayer_android_test_jni_impl") { - testonly = true - sources = [ - "browser/test/test_infobar.cc", - "browser/test/test_infobar.h", - "browser/test/test_weblayer_impl.cc", - ] - deps = [ - ":weblayer_lib_base", - "//base", - "//base/test:test_support", - "//components/content_settings/core/browser", - "//components/infobars/android", - "//components/infobars/content", - "//components/infobars/core", - "//components/translate/core/browser", - "//content/public/browser", - "//content/public/test/android:content_native_test_support", - "//content/test:test_support", - "//testing/gtest", - "//weblayer/browser/java:test_jni", - ] - } - - static_library("weblayer_lib_webview_test") { - testonly = true - public_deps = [ ":weblayer_lib_base" ] - deps = [ - ":weblayer_android_test_jni_impl", - "//base", - "//weblayer/browser/java:jni", - ] - - # Explicit dependency required for JNI registration to be able to - # find the native side functions. - if (is_component_build) { - deps += [ - "//device/gamepad", - "//media/midi", - "//ui/events/devices", - ] - } - } - - # Lib used in Monochrome which does not support manual JNI registration. - # Separate from the standalone WebView version to reduce APK size. - static_library("weblayer_lib") { - public_deps = [ ":weblayer_lib_base" ] - deps = [ "//weblayer/browser/java:jni" ] - } - - shared_library_with_jni("libweblayer_test") { - testonly = true - sources = [ "app/entry_point.cc" ] - deps = [ - ":weblayer_lib_webview_test", - "//base", - "//components/android_autofill/browser/test_support:native", - "//content/public/app", - ] - configs -= [ "//build/config/android:hide_all_but_jni_onload" ] - configs += [ "//build/config/android:hide_all_but_jni" ] - java_targets = [ "//weblayer/shell/android:weblayer_support_apk" ] - } -} else { - source_set("weblayer_lib") { - public_deps = [ ":weblayer_lib_base" ] - } -} - -grit("resources") { - source = "weblayer_resources.grd" - use_brotli = true - - outputs = [ - "grit/weblayer_resources.h", - "weblayer_resources.pak", - ] - deps = [ "//weblayer/browser/webui:mojo_bindings_js__generator" ] -} -# TODO(jam): move weblayer_shell_resources_grit and copy_shell_resources here in -# a way that's shareable?
diff --git a/weblayer/DEPS b/weblayer/DEPS deleted file mode 100644 index c4959fb..0000000 --- a/weblayer/DEPS +++ /dev/null
@@ -1,11 +0,0 @@ -include_rules = [ - "+components/content_settings/core/browser", - "+components/embedder_support/android/common", - "+components/js_injection", - "+components/omnibox/browser", - "+components/page_info/android", - "+components/payments/core", - "+components/security_state/core/security_state.h", - "+device/vr/buildflags", - "+third_party/metrics_proto/omnibox_input_type.pb.h", -]
diff --git a/weblayer/DIR_METADATA b/weblayer/DIR_METADATA deleted file mode 100644 index 49848114..0000000 --- a/weblayer/DIR_METADATA +++ /dev/null
@@ -1,12 +0,0 @@ -# Metadata information for this directory. -# -# For more information on DIR_METADATA files, see: -# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md -# -# For the schema of this file, see Metadata message: -# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto - -monorail { - component: "Internals>WebLayer" -} -team_email: "weblayer-dev@chromium.org" \ No newline at end of file
diff --git a/weblayer/OWNERS b/weblayer/OWNERS deleted file mode 100644 index e12457e..0000000 --- a/weblayer/OWNERS +++ /dev/null
@@ -1,13 +0,0 @@ -set noparent -blundell@chromium.org -boliu@chromium.org -cduvall@chromium.org -estade@chromium.org -jam@chromium.org -peter@chromium.org -rayankans@chromium.org -rmcelrath@chromium.org -sky@chromium.org - -# Translation artifacts: -per-file ....xtb=file://tools/translation/TRANSLATION_OWNERS \ No newline at end of file
diff --git a/weblayer/README.md b/weblayer/README.md deleted file mode 100644 index 9afa21b..0000000 --- a/weblayer/README.md +++ /dev/null
@@ -1,106 +0,0 @@ -# WebEngine - -WebEngine is an embedded web UI component offering a modern, secure set of web -embedding capabilities as part of Android. - -WebEngine is based on the WebLayer project; a high level embedding API to -support building a browser. - -Note: The WebLayer API is deprecated as of M108, and WebLayer is being merged -into the WebEngine project. - -Unlike `src/content`, which is only concerned with a sandboxed multi-process web -platform, WebLayer includes modern browser features and Google integration. -It's the reusable version of Chrome, which might share some portions of the UI -and also its support for all the modern HTML5 and browser features (e.g. UI for -permissions, autofill, safe browsing etc...). - -While it's built on top of `src/content`, the expectation is that the API will -hide the Content API. - -WebEngine further abstracts away the full set of capabilities of WebLayer, with -a simple API surface focused on the following goals: - -* Security - protecting the web content by adding a security barrier between the - embedder/host and the web content -* Performance - improving the embedder/host's responsiveness by offloading the - browser initialization -* Stability - decoupling browser crashes from the embedder/host crashes -* Modernness - receiving full web platform support for free, while hiding - subprocesses and the Content API. - -Most of these goals can be achieved via moving the _browser_ component to run -in a sandbox. While such as a sandbox does not yet exist within Android, -WebEngine is still being developed with the aim to eventually create a security -boundary between the embedder/host app and the browser. A non-sandboxed mode -with the same API surface is being developed for compatibility, and a sandboxed -mode with a limited makeshift sandbox is also being developed for testing. - -Note: _weblayer_ is still referenced a lot in this directory, all references will -eventually be changed to _webengine_. - -## Resources and Documentation - -Bug tracker: [Internals>WebLayer](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3AInternals%3EWebLayer) - -## Directory Structure - -`public` the C++ and Java public API. These are the only files an app should use - -`shell` sample app - -`test` test harnesses and test-only helper code - -`tools` helper scripts - -`app` internal code which runs at the beginning of each process - -`browser` internal code which runs in the browser process - -`common` internal code which runs in the browser and child processes - -`renderer` internal code which runs in the renderer process - -`utility` internal code which runs in the utility process - -## Setting Up Your Build Environment - -If you haven't done this already, you first need to set up an Android build. -[Android build instructions](https://source.chromium.org/chromium/chromium/src/+/main:docs/android_build_instructions.md). - -## Building and Testing - -To run the sample app: - -``` - $ autoninja -C out/Default run_webengine_shell_local - $ out/Default/bin/run_webengine_shell_local -``` - -To run the sample app with a browsing sandbox (limited capabilities): - -``` - $ autoninja -C out/Default run_webengine_shell - $ out/Default/bin/run_webengine_shell -``` - -To run instrumentation tests: - -``` - $ autoninja -C out/Default webengine_support_instrumentation_test_apk - $ out/Default/bin/run_webengine_support_instrumentation_test_apk -``` - -The scripts will build and install all necessary APKs. - - -## Command line flags - -Command line flags can be set via the build/android/adb_system_webengine_command_line script. - -### Useful flags: - -Force enabling metrics reporting: -``` - $ build/android/adb_system_webengine_command_line --force-enable-metrics-reporting -```
diff --git a/weblayer/app/DEPS b/weblayer/app/DEPS deleted file mode 100644 index df64399..0000000 --- a/weblayer/app/DEPS +++ /dev/null
@@ -1,16 +0,0 @@ -include_rules = [ - "+components/autofill/core/common", - "+components/content_capture/common", - "+components/startup_metric_utils/common", - "+components/variations", - "+components/version_info", - "+components/viz/common", - "+components/translate/core/common", - "+content/public", - "+device/base/features.h", - "+media/base/media_switches.h", - "+sandbox", - "+services/network/public/cpp", - "+third_party/blink/public", - "+ui/base", -]
diff --git a/weblayer/app/content_main_delegate_impl.cc b/weblayer/app/content_main_delegate_impl.cc deleted file mode 100644 index ebccd53..0000000 --- a/weblayer/app/content_main_delegate_impl.cc +++ /dev/null
@@ -1,444 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/app/content_main_delegate_impl.h" - -#include <iostream> -#include <tuple> - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/containers/contains.h" -#include "base/containers/flat_set.h" -#include "base/cpu.h" -#include "base/files/file_util.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/strings/string_split.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "components/content_capture/common/content_capture_features.h" -#include "components/startup_metric_utils/common/startup_metric_utils.h" -#include "components/translate/core/common/translate_util.h" -#include "components/variations/variations_ids_provider.h" -#include "content/public/app/initialize_mojo_core.h" -#include "content/public/browser/browser_main_runner.h" -#include "content/public/common/content_features.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/main_function_params.h" -#include "content/public/common/url_constants.h" -#include "media/base/media_switches.h" -#include "services/network/public/cpp/features.h" -#include "third_party/abseil-cpp/absl/types/variant.h" -#include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/platform/web_runtime_features.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/ui_base_paths.h" -#include "weblayer/browser/background_fetch/background_fetch_delegate_factory.h" -#include "weblayer/browser/content_browser_client_impl.h" -#include "weblayer/common/content_client_impl.h" -#include "weblayer/common/weblayer_paths.h" -#include "weblayer/public/common/switches.h" -#include "weblayer/renderer/content_renderer_client_impl.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/apk_assets.h" -#include "base/android/build_info.h" -#include "base/android/bundle_utils.h" -#include "base/android/java_exception_reporter.h" -#include "base/android/locale_utils.h" -#include "base/i18n/rtl.h" -#include "base/posix/global_descriptors.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/viz/common/features.h" -#include "content/public/browser/android/compositor.h" -#include "ui/base/resource/resource_bundle_android.h" -#include "ui/base/ui_base_switches.h" -#include "weblayer/browser/android/application_info_helper.h" -#include "weblayer/browser/android/exception_filter.h" -#include "weblayer/browser/android_descriptors.h" -#include "weblayer/common/crash_reporter/crash_keys.h" -#include "weblayer/common/crash_reporter/crash_reporter_client.h" -#endif - -#if BUILDFLAG(IS_WIN) -#include <windows.h> - -#include <initguid.h> -#include "base/logging_win.h" -#endif - -namespace weblayer { - -namespace { - -void InitLogging(MainParams* params) { - if (params->log_filename.empty()) - return; - - logging::LoggingSettings settings; - settings.logging_dest = logging::LOG_TO_ALL; - settings.log_file_path = params->log_filename.value().c_str(); - settings.delete_old = logging::DELETE_OLD_LOG_FILE; - logging::InitLogging(settings); - logging::SetLogItems(true /* Process ID */, true /* Thread ID */, - true /* Timestamp */, false /* Tick count */); -} - -// Enables each feature in |features_to_enable| unless it is already set in the -// command line, and similarly disables each feature in |features_to_disable| -// unless it is already set in the command line. -void ConfigureFeaturesIfNotSet( - const std::vector<const base::Feature*>& features_to_enable, - const std::vector<const base::Feature*>& features_to_disable) { - auto* cl = base::CommandLine::ForCurrentProcess(); - std::vector<std::string> enabled_features; - base::flat_set<std::string> feature_names_enabled_via_command_line; - std::string enabled_features_str = - cl->GetSwitchValueASCII(::switches::kEnableFeatures); - for (const auto& f : - base::FeatureList::SplitFeatureListString(enabled_features_str)) { - enabled_features.emplace_back(f); - - // "<" is used as separator for field trial/groups. - std::vector<base::StringPiece> parts = base::SplitStringPiece( - f, "<", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - // Split with supplied params should always return at least one entry. - DCHECK(!parts.empty()); - if (parts[0].length() > 0) - feature_names_enabled_via_command_line.insert(std::string(parts[0])); - } - - std::vector<std::string> disabled_features; - std::string disabled_features_str = - cl->GetSwitchValueASCII(::switches::kDisableFeatures); - for (const auto& f : - base::FeatureList::SplitFeatureListString(disabled_features_str)) { - disabled_features.emplace_back(f); - } - - for (const auto* feature : features_to_enable) { - if (!base::Contains(disabled_features, feature->name) && - !base::Contains(feature_names_enabled_via_command_line, - feature->name)) { - enabled_features.push_back(feature->name); - } - } - cl->AppendSwitchASCII(::switches::kEnableFeatures, - base::JoinString(enabled_features, ",")); - - for (const auto* feature : features_to_disable) { - if (!base::Contains(disabled_features, feature->name) && - !base::Contains(feature_names_enabled_via_command_line, - feature->name)) { - disabled_features.push_back(feature->name); - } - } - cl->AppendSwitchASCII(::switches::kDisableFeatures, - base::JoinString(disabled_features, ",")); -} - -} // namespace - -ContentMainDelegateImpl::ContentMainDelegateImpl(MainParams params) - : params_(std::move(params)) { -#if !BUILDFLAG(IS_ANDROID) - // On non-Android, the application start time is recorded in this constructor, - // which runs early during application lifetime. On Android, the application - // start time is sampled when the Java code is entered, and it is retrieved - // from C++ after initializing the JNI (see - // BrowserMainPartsImpl::PreMainMessageLoopRun()). - startup_metric_utils::GetCommon().RecordApplicationStartTime( - base::TimeTicks::Now()); -#endif -} - -ContentMainDelegateImpl::~ContentMainDelegateImpl() = default; - -absl::optional<int> ContentMainDelegateImpl::BasicStartupComplete() { - // Disable features which are not currently supported in WebLayer. This allows - // sites to do feature detection, and prevents crashes in some not fully - // implemented features. - base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); - // TODO(crbug.com/1025610): make notifications work with WebLayer. - // This also turns off Push messaging. - cl->AppendSwitch(::switches::kDisableNotifications); - - std::vector<const base::Feature*> enabled_features = { -#if BUILDFLAG(IS_ANDROID) - // Overlay promotion requires some guarantees we don't have on WebLayer - // (e.g. ensuring fullscreen, no movement of the parent view). Given that - // we're unsure about the benefits when used embedded in a parent app, we - // will only promote to overlays if needed for secure videos. - &media::kUseAndroidOverlayForSecureOnly, -#endif - }; - - std::vector<const base::Feature*> disabled_features = { - // TODO(crbug.com/1313771): Support Digital Goods API. - &::features::kDigitalGoodsApi, - // TODO(crbug.com/1091212): make Notification triggers work with - // WebLayer. - &::features::kNotificationTriggers, - // TODO(crbug.com/1091211): Support PeriodicBackgroundSync on WebLayer. - &::features::kPeriodicBackgroundSync, - // TODO(crbug.com/1174856): Support Portals. - &blink::features::kPortals, - // TODO(crbug.com/1144912): Support BackForwardCache on WebLayer. - &::features::kBackForwardCache, - // TODO(crbug.com/1247836): Enable TFLite/Optimization Guide on WebLayer. - &translate::kTFLiteLanguageDetectionEnabled, - -#if BUILDFLAG(IS_ANDROID) - &::features::kDynamicColorGamut, -#else - // WebOTP is supported only on Android in WebLayer. - &::features::kWebOTP, -#endif - }; - -#if BUILDFLAG(IS_ANDROID) - if (base::android::BuildInfo::GetInstance()->sdk_int() >= - base::android::SDK_VERSION_OREO) { - enabled_features.push_back( - &autofill::features::kAutofillExtractAllDatalists); - } - - if (GetApplicationMetadataAsBoolean( - "org.chromium.weblayer.ENABLE_LOGGING_OF_JS_CONSOLE_MESSAGES", - /*default_value=*/false)) { - enabled_features.push_back(&features::kLogJsConsoleMessages); - } -#endif - - ConfigureFeaturesIfNotSet(enabled_features, disabled_features); - - // TODO(crbug.com/1338402): Add support for WebLayer. Disabling autofill is - // not yet supported. - blink::WebRuntimeFeatures::EnableAnonymousIframe(false); - -#if BUILDFLAG(IS_ANDROID) - content::Compositor::Initialize(); -#endif - - InitLogging(¶ms_); - - RegisterPathProvider(); - - return absl::nullopt; -} - -bool ContentMainDelegateImpl::ShouldCreateFeatureList(InvokedIn invoked_in) { -#if BUILDFLAG(IS_ANDROID) - // On android WebLayer is in charge of creating its own FeatureList in the - // browser process. - return absl::holds_alternative<InvokedInChildProcess>(invoked_in); -#else - // TODO(weblayer-dev): Support feature lists on desktop. - return true; -#endif -} - -bool ContentMainDelegateImpl::ShouldInitializeMojo(InvokedIn invoked_in) { - return ShouldCreateFeatureList(invoked_in); -} - -variations::VariationsIdsProvider* -ContentMainDelegateImpl::CreateVariationsIdsProvider() { - // As the embedder supplies the set of ids, the signed-in state does not make - // sense and is ignored. - return variations::VariationsIdsProvider::Create( - variations::VariationsIdsProvider::Mode::kIgnoreSignedInState); -} - -void ContentMainDelegateImpl::PreSandboxStartup() { -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if defined(ARCH_CPU_ARM_FAMILY) && \ - (BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || \ - BUILDFLAG(IS_CHROMEOS_LACROS)) - // Create an instance of the CPU class to parse /proc/cpuinfo and cache - // cpu_brand info. - base::CPU cpu_info; -#endif - - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - const bool is_browser_process = - command_line.GetSwitchValueASCII(::switches::kProcessType).empty(); - if (is_browser_process && - command_line.HasSwitch(switches::kWebEngineUserDataDir)) { - base::FilePath path = - command_line.GetSwitchValuePath(switches::kWebEngineUserDataDir); - if (base::DirectoryExists(path) || base::CreateDirectory(path)) { - // Profile needs an absolute path, which we would normally get via - // PathService. In this case, manually ensure the path is absolute. - if (!path.IsAbsolute()) - path = base::MakeAbsoluteFilePath(path); - } else { - LOG(ERROR) << "Unable to create data-path directory: " << path.value(); - } - CHECK(base::PathService::OverrideAndCreateIfNeeded( - DIR_USER_DATA, path, true /* is_absolute */, false /* create */)); - } - - InitializeResourceBundle(); - -#if BUILDFLAG(IS_ANDROID) - EnableCrashReporter( - command_line.GetSwitchValueASCII(::switches::kProcessType)); - if (is_browser_process) { - base::android::SetJavaExceptionFilter( - base::BindRepeating(&WebLayerJavaExceptionFilter)); - } - SetWebLayerCrashKeys(); -#endif -} - -absl::optional<int> ContentMainDelegateImpl::PostEarlyInitialization( - InvokedIn invoked_in) { - if (absl::holds_alternative<InvokedInBrowserProcess>(invoked_in)) { - browser_client_->CreateFeatureListAndFieldTrials(); - } - if (!ShouldInitializeMojo(invoked_in)) { - // Since we've told Content not to initialize Mojo on its own, we must do it - // here manually. - content::InitializeMojoCore(); - } - return absl::nullopt; -} - -absl::variant<int, content::MainFunctionParams> -ContentMainDelegateImpl::RunProcess( - const std::string& process_type, - content::MainFunctionParams main_function_params) { - // For non-browser process, return and have the caller run the main loop. - if (!process_type.empty()) - return std::move(main_function_params); - -#if !BUILDFLAG(IS_ANDROID) - // On non-Android, we can return |main_function_params| back and have the - // caller run BrowserMain() normally. - return std::move(main_function_params); -#else - // On Android, we defer to the system message loop when the stack unwinds. - // So here we only create (and leak) a BrowserMainRunner. The shutdown - // of BrowserMainRunner doesn't happen in Chrome Android and doesn't work - // properly on Android at all. - auto main_runner = content::BrowserMainRunner::Create(); - // In browser tests, the |main_function_params| contains a |ui_task| which - // will execute the testing. The task will be executed synchronously inside - // Initialize() so we don't depend on the BrowserMainRunner being Run(). - int initialize_exit_code = - main_runner->Initialize(std::move(main_function_params)); - DCHECK_LT(initialize_exit_code, 0) - << "BrowserMainRunner::Initialize failed in MainDelegate"; - std::ignore = main_runner.release(); - // Return 0 as BrowserMain() should not be called after this, bounce up to - // the system message loop for ContentShell, and we're already done thanks - // to the |ui_task| for browser tests. - return 0; -#endif -} - -void ContentMainDelegateImpl::InitializeResourceBundle() { -#if BUILDFLAG(IS_ANDROID) - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - - bool is_browser_process = - command_line.GetSwitchValueASCII(::switches::kProcessType).empty(); - if (is_browser_process) { - // If we're not being loaded from a bundle, locales will be loaded from the - // webview stored-locales directory. Otherwise, we are in Monochrome, and - // we load both chrome and webview's locale assets. - if (base::android::BundleUtils::IsBundle()) - ui::SetLoadSecondaryLocalePaks(true); - else - ui::SetLocalePaksStoredInApk(true); - // Passing an empty |pref_locale| yields the system default locale. - std::string locale = ui::ResourceBundle::InitSharedInstanceWithLocale( - {} /*pref_locale*/, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES); - - if (locale.empty()) { - LOG(WARNING) << "Failed to load locale .pak from apk."; - } - - // Try to directly mmap the resources.pak from the apk. Fall back to load - // from file, using PATH_SERVICE, otherwise. - base::FilePath pak_file_path; - base::PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &pak_file_path); - pak_file_path = pak_file_path.AppendASCII("resources.pak"); - ui::LoadMainAndroidPackFile("assets/resources.pak", pak_file_path); - - // The English-only workaround is not needed for bundles, since bundles will - // contain assets for all locales. - if (!base::android::BundleUtils::IsBundle()) { - constexpr char kWebLayerLocalePath[] = - "assets/stored-locales/weblayer/en-US.pak"; - base::MemoryMappedFile::Region region; - int fd = base::android::OpenApkAsset(kWebLayerLocalePath, ®ion); - CHECK_GE(fd, 0) << "Could not find " << kWebLayerLocalePath << " in APK."; - ui::ResourceBundle::GetSharedInstance() - .LoadSecondaryLocaleDataWithPakFileRegion(base::File(fd), region); - base::GlobalDescriptors::GetInstance()->Set( - kWebLayerSecondaryLocalePakDescriptor, fd, region); - } - } else { - base::i18n::SetICUDefaultLocale( - command_line.GetSwitchValueASCII(::switches::kLang)); - - auto* global_descriptors = base::GlobalDescriptors::GetInstance(); - int pak_fd = global_descriptors->Get(kWebLayerLocalePakDescriptor); - base::MemoryMappedFile::Region pak_region = - global_descriptors->GetRegion(kWebLayerLocalePakDescriptor); - ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(base::File(pak_fd), - pak_region); - - pak_fd = global_descriptors->Get(kWebLayerSecondaryLocalePakDescriptor); - pak_region = - global_descriptors->GetRegion(kWebLayerSecondaryLocalePakDescriptor); - ui::ResourceBundle::GetSharedInstance() - .LoadSecondaryLocaleDataWithPakFileRegion(base::File(pak_fd), - pak_region); - - std::vector<std::pair<int, ui::ResourceScaleFactor>> extra_paks = { - {kWebLayerMainPakDescriptor, ui::kScaleFactorNone}, - {kWebLayer100PercentPakDescriptor, ui::k100Percent}}; - - for (const auto& pak_info : extra_paks) { - pak_fd = global_descriptors->Get(pak_info.first); - pak_region = global_descriptors->GetRegion(pak_info.first); - ui::ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion( - base::File(pak_fd), pak_region, pak_info.second); - } - } -#else - base::FilePath pak_file; - bool r = base::PathService::Get(base::DIR_ASSETS, &pak_file); - DCHECK(r); - pak_file = pak_file.AppendASCII(params_.pak_name); - ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file); -#endif -} - -content::ContentClient* ContentMainDelegateImpl::CreateContentClient() { - content_client_ = std::make_unique<ContentClientImpl>(); - return content_client_.get(); -} - -content::ContentBrowserClient* -ContentMainDelegateImpl::CreateContentBrowserClient() { - browser_client_ = std::make_unique<ContentBrowserClientImpl>(¶ms_); - return browser_client_.get(); -} - -content::ContentRendererClient* -ContentMainDelegateImpl::CreateContentRendererClient() { - renderer_client_ = std::make_unique<ContentRendererClientImpl>(); - return renderer_client_.get(); -} - -} // namespace weblayer
diff --git a/weblayer/app/content_main_delegate_impl.h b/weblayer/app/content_main_delegate_impl.h deleted file mode 100644 index 6a78a5b..0000000 --- a/weblayer/app/content_main_delegate_impl.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_APP_CONTENT_MAIN_DELEGATE_IMPL_H_ -#define WEBLAYER_APP_CONTENT_MAIN_DELEGATE_IMPL_H_ - -#include <memory> - -#include "base/compiler_specific.h" -#include "build/build_config.h" -#include "content/public/app/content_main_delegate.h" -#include "weblayer/public/main.h" - -namespace weblayer { -class ContentBrowserClientImpl; -class ContentClientImpl; -class ContentRendererClientImpl; - -class ContentMainDelegateImpl : public content::ContentMainDelegate { - public: - explicit ContentMainDelegateImpl(MainParams params); - - ContentMainDelegateImpl(const ContentMainDelegateImpl&) = delete; - ContentMainDelegateImpl& operator=(const ContentMainDelegateImpl&) = delete; - - ~ContentMainDelegateImpl() override; - - // ContentMainDelegate implementation: - absl::optional<int> BasicStartupComplete() override; - bool ShouldCreateFeatureList(InvokedIn invoked_in) override; - bool ShouldInitializeMojo(InvokedIn invoked_in) override; - variations::VariationsIdsProvider* CreateVariationsIdsProvider() override; - void PreSandboxStartup() override; - absl::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override; - absl::variant<int, content::MainFunctionParams> RunProcess( - const std::string& process_type, - content::MainFunctionParams main_function_params) override; - content::ContentClient* CreateContentClient() override; - content::ContentBrowserClient* CreateContentBrowserClient() override; - content::ContentRendererClient* CreateContentRendererClient() override; - - private: - void InitializeResourceBundle(); - - MainParams params_; - std::unique_ptr<ContentBrowserClientImpl> browser_client_; - std::unique_ptr<ContentRendererClientImpl> renderer_client_; - std::unique_ptr<ContentClientImpl> content_client_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_APP_CONTENT_MAIN_DELEGATE_IMPL_H_
diff --git a/weblayer/app/entry_point.cc b/weblayer/app/entry_point.cc deleted file mode 100644 index cf69f1b..0000000 --- a/weblayer/app/entry_point.cc +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/android/jni_android.h" -#include "base/android/library_loader/library_loader_hooks.h" -#include "weblayer/app/jni_onload.h" - -namespace { - -bool NativeInit(base::android::LibraryProcessType) { - return weblayer::OnJNIOnLoadInit(); -} - -} // namespace - -JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { - base::android::InitVM(vm); - base::android::SetNativeInitializationHook(&NativeInit); - return JNI_VERSION_1_4; -}
diff --git a/weblayer/app/jni_onload.cc b/weblayer/app/jni_onload.cc deleted file mode 100644 index 9fe9b56..0000000 --- a/weblayer/app/jni_onload.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/public/app/content_jni_onload.h" -#include "content/public/app/content_main.h" -#include "weblayer/app/content_main_delegate_impl.h" - -namespace weblayer { - -class MainDelegateImpl : public MainDelegate { - public: - void PreMainMessageLoopRun() override {} - void PostMainMessageLoopRun() override {} - void SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) override {} -}; - -// This is called by the VM when the shared library is first loaded. -bool OnJNIOnLoadInit() { - if (!content::android::OnJNIOnLoadInit()) - return false; - - weblayer::MainParams params; - params.delegate = new weblayer::MainDelegateImpl; - - content::SetContentMainDelegate( - new weblayer::ContentMainDelegateImpl(params)); - return true; -} - -} // namespace weblayer
diff --git a/weblayer/app/jni_onload.h b/weblayer/app/jni_onload.h deleted file mode 100644 index cc32c39..0000000 --- a/weblayer/app/jni_onload.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_APP_JNI_ONLOAD_H_ -#define WEBLAYER_APP_JNI_ONLOAD_H_ - -namespace weblayer { - -bool OnJNIOnLoadInit(); - -} // namespace weblayer - -#endif // WEBLAYER_APP_JNI_ONLOAD_H_
diff --git a/weblayer/app/main.cc b/weblayer/app/main.cc deleted file mode 100644 index 37f850c1..0000000 --- a/weblayer/app/main.cc +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/public/main.h" - -#include "build/build_config.h" -#include "content/public/app/content_main.h" -#include "weblayer/app/content_main_delegate_impl.h" - -#if BUILDFLAG(IS_WIN) -#include "base/win/win_util.h" -#include "content/public/app/sandbox_helper_win.h" -#include "sandbox/win/src/sandbox_types.h" -#endif - -namespace weblayer { - -MainParams::MainParams() = default; -MainParams::MainParams(const MainParams& other) = default; -MainParams::~MainParams() = default; - -#if !BUILDFLAG(IS_ANDROID) -int Main(MainParams params -#if BUILDFLAG(IS_WIN) -#if !defined(WIN_CONSOLE_APP) - , - HINSTANCE instance -#endif -#else - , - int argc, - const char** argv -#endif -) { - ContentMainDelegateImpl delegate(std::move(params)); - content::ContentMainParams content_params(&delegate); - -#if BUILDFLAG(IS_WIN) -#if defined(WIN_CONSOLE_APP) - HINSTANCE instance = GetModuleHandle(nullptr); -#endif - sandbox::SandboxInterfaceInfo sandbox_info = {nullptr}; - content::InitializeSandboxInfo(&sandbox_info); - content_params.instance = instance; - content_params.sandbox_info = &sandbox_info; -#else - content_params.argc = argc; - content_params.argv = argv; -#endif - - return content::ContentMain(std::move(content_params)); -} -#endif // !BUILDFLAG(IS_ANDROID) - -} // namespace weblayer
diff --git a/weblayer/browser/DEPS b/weblayer/browser/DEPS deleted file mode 100644 index fdff216..0000000 --- a/weblayer/browser/DEPS +++ /dev/null
@@ -1,130 +0,0 @@ -include_rules = [ - "+cc", - "+components/android_autofill/browser", - "+components/autofill/content/browser", - "+components/autofill/content/common", - "+components/autofill/core/browser", - "+components/autofill/core/common", - "+components/background_fetch", - "+components/background_sync", - "+components/base32", - "+components/blocked_content", - "+components/browsing_data/content", - "+components/browser_ui", - "+components/captive_portal", - "+components/cdm/browser", - "+components/client_hints/browser", - "+components/component_updater/android", - "+components/content_capture/browser", - "+components/content_settings/browser", - "+components/content_settings/common", - "+components/content_settings/core/common", - "+components/crash/content/browser", - "+components/crash/core/common", - "+components/content_relationship_verification", - "+components/download/content/factory", - "+components/download/content/public", - "+components/download/public/background_service", - "+components/download/public/common", - "+components/download/public/task", - "+components/embedder_support", - "+components/error_page/common", - "+components/error_page/content/browser", - "+components/favicon_base", - "+components/favicon", - "+components/find_in_page", - "+components/heavy_ad_intervention", - "+components/infobars/android", - "+components/infobars/content", - "+components/infobars/core", - "+components/installedapp/android", - "+components/javascript_dialogs", - "+components/keep_alive_registry", - "+components/keyed_service/content", - "+components/keyed_service/core", - "+components/language/core/browser", - "+components/leveldb_proto/public", - "+components/media_router", - "+components/metrics", - "+components/navigation_interception", - "+components/net_log", - "+components/network_session_configurator", - "+components/network_time", - "+components/page_load_metrics/browser", - "+components/payments/content", - "+components/password_manager/content/browser", - "+components/performance_manager/embedder", - "+components/performance_manager/public", - "+components/origin_trials", - "+components/permissions", - "+components/pref_registry", - "+components/prefs", - "+components/privacy_sandbox", - "+components/profile_metrics", - "+components/no_state_prefetch/browser", - "+components/no_state_prefetch/common", - "+components/reduce_accept_language/browser", - "+components/resources/android", - "+components/safe_browsing/android", - "+components/safe_browsing/content/browser", - "+components/safe_browsing/core", - "+components/safe_browsing/core/common", - "+components/security_interstitials", - "+components/security_state/content/content_utils.h", - "+components/security_state/core/security_state.h", - "+components/sessions", - "+components/signin/core/browser", - "+components/signin/public", - "+components/site_engagement/content", - "+components/site_isolation", - "+components/spellcheck/browser", - "+components/ssl_errors", - "+components/startup_metric_utils/browser", - "+components/startup_metric_utils/common", - "+components/strings", - "+components/subresource_filter/android", - "+components/subresource_filter/content/browser", - "+components/subresource_filter/core/browser", - "+components/subresource_filter/core/common", - "+components/subresource_filter/core/mojom", - "+components/translate/content/android", - "+components/translate/content/browser", - "+components/translate/core/browser", - "+components/translate/core/common", - "+components/ukm", - "+components/unified_consent/pref_names.h", - "+components/url_formatter", - "+components/user_prefs", - "+components/variations", - "+components/version_info", - "+components/web_cache/browser", - "+components/webdata_services", - "+components/webapps/browser", - "+components/webrtc", - "+components/webxr", - "+content/public", - "+device/vr/public", - "+google_apis", - "+mojo/public", - "+net", - "+sandbox", - "+services/cert_verifier/public/mojom", - "+services/metrics/public/cpp", - "+services/network/network_service.h", - "+services/network/public", - "+services/service_manager", - "+storage/browser/quota", - "+third_party/blink/public/common", - "+third_party/blink/public/mojom", - "+third_party/skia", - "+ui/aura", - "+ui/android", - "+ui/base", - "+ui/display", - "+ui/events", - "+ui/gfx", - "+ui/shell_dialogs", - "+ui/views", - "+ui/webui", - "+ui/wm", -]
diff --git a/weblayer/browser/OWNERS b/weblayer/browser/OWNERS deleted file mode 100644 index d9811ae..0000000 --- a/weblayer/browser/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -per-file weblayer_browser_interface_binders.*=set noparent -per-file weblayer_browser_interface_binders.*=file://ipc/SECURITY_OWNERS -per-file content_browser_client_impl_receiver_bindings.*=set noparent -per-file content_browser_client_impl_receiver_bindings.*=file://ipc/SECURITY_OWNERS
diff --git a/weblayer/browser/accept_languages_service_factory.cc b/weblayer/browser/accept_languages_service_factory.cc deleted file mode 100644 index 70b26b2..0000000 --- a/weblayer/browser/accept_languages_service_factory.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/accept_languages_service_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/language/core/browser/accept_languages_service.h" -#include "components/language/core/browser/pref_names.h" -#include "components/prefs/pref_service.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" - -namespace weblayer { - -// static -language::AcceptLanguagesService* -AcceptLanguagesServiceFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<language::AcceptLanguagesService*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -AcceptLanguagesServiceFactory* AcceptLanguagesServiceFactory::GetInstance() { - static base::NoDestructor<AcceptLanguagesServiceFactory> factory; - return factory.get(); -} - -AcceptLanguagesServiceFactory::AcceptLanguagesServiceFactory() - : BrowserContextKeyedServiceFactory( - "AcceptLanguagesService", - BrowserContextDependencyManager::GetInstance()) {} - -AcceptLanguagesServiceFactory::~AcceptLanguagesServiceFactory() = default; - -std::unique_ptr<KeyedService> -AcceptLanguagesServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser_context) const { - return std::make_unique<language::AcceptLanguagesService>( - user_prefs::UserPrefs::Get(browser_context), - language::prefs::kAcceptLanguages); -} - -content::BrowserContext* AcceptLanguagesServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/accept_languages_service_factory.h b/weblayer/browser/accept_languages_service_factory.h deleted file mode 100644 index 1334863..0000000 --- a/weblayer/browser/accept_languages_service_factory.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ACCEPT_LANGUAGES_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_ACCEPT_LANGUAGES_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace language { -class AcceptLanguagesService; -} - -namespace weblayer { - -// AcceptLanguagesServiceFactory is a way to associate an -// AcceptLanguagesService instance to a BrowserContext. -class AcceptLanguagesServiceFactory : public BrowserContextKeyedServiceFactory { - public: - AcceptLanguagesServiceFactory(const AcceptLanguagesServiceFactory&) = delete; - AcceptLanguagesServiceFactory& operator=( - const AcceptLanguagesServiceFactory&) = delete; - - static language::AcceptLanguagesService* GetForBrowserContext( - content::BrowserContext* browser_context); - static AcceptLanguagesServiceFactory* GetInstance(); - - private: - friend class base::NoDestructor<AcceptLanguagesServiceFactory>; - - AcceptLanguagesServiceFactory(); - ~AcceptLanguagesServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedServi> e* BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ACCEPT_LANGUAGES_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/ad_tagging_browsertest.cc b/weblayer/browser/ad_tagging_browsertest.cc deleted file mode 100644 index 8fd3325..0000000 --- a/weblayer/browser/ad_tagging_browsertest.cc +++ /dev/null
@@ -1,154 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -#include "build/build_config.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/content_settings/core/common/content_settings.h" -#include "components/content_settings/core/common/content_settings_types.h" -#include "components/subresource_filter/content/browser/ad_tagging_browser_test_utils.h" -#include "components/subresource_filter/content/browser/subresource_filter_observer_test_utils.h" -#include "components/subresource_filter/core/common/test_ruleset_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/test/subresource_filter_browser_test_harness.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -// Tests of ad tagging integration in WebLayer. A minimal port of //chrome's -// ad_tagging_browsertest.cc. -class AdTaggingBrowserTest : public SubresourceFilterBrowserTest { - public: - AdTaggingBrowserTest() = default; - ~AdTaggingBrowserTest() override = default; - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("ad_script.js"), - subresource_filter::testing::CreateSuffixRule("ad=true")}); - } - - GURL GetURL(const std::string& page) { - return embedded_test_server()->GetURL("/ad_tagging/" + page); - } -}; - -IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, - AdContentSettingAllowed_AdTaggingDisabled) { - HostContentSettingsMapFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()) - ->SetDefaultContentSetting(ContentSettingsType::ADS, - CONTENT_SETTING_ALLOW); - - subresource_filter::TestSubresourceFilterObserver observer(web_contents()); - NavigateAndWaitForCompletion(GetURL("frame_factory.html"), shell()); - - // Create an ad frame. - GURL ad_url = GetURL("frame_factory.html?2&ad=true"); - content::RenderFrameHost* ad_frame = - subresource_filter::CreateSrcFrame(web_contents(), ad_url); - - // Verify that we are not evaluating subframe loads. - EXPECT_FALSE(observer.GetChildFrameLoadPolicy(ad_url).has_value()); - EXPECT_FALSE(observer.GetIsAdFrame(ad_frame->GetFrameTreeNodeId())); - - // Child frame created by ad script. - content::RenderFrameHost* ad_frame_tagged_by_script = - subresource_filter::CreateSrcFrameFromAdScript( - web_contents(), GetURL("frame_factory.html?1")); - - // No frames should be detected by script heuristics. - EXPECT_FALSE( - observer.GetIsAdFrame(ad_frame_tagged_by_script->GetFrameTreeNodeId())); -} - -// TODO(crbug.com/1210190): This test is flaky. -IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, - DISABLED_AdContentSettingBlocked_AdTaggingEnabled) { - HostContentSettingsMapFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()) - ->SetDefaultContentSetting(ContentSettingsType::ADS, - CONTENT_SETTING_BLOCK); - - subresource_filter::TestSubresourceFilterObserver observer(web_contents()); - NavigateAndWaitForCompletion(GetURL("frame_factory.html"), shell()); - - // Create an ad frame. - GURL ad_url = GetURL("frame_factory.html?2&ad=true"); - content::RenderFrameHost* ad_frame = - subresource_filter::CreateSrcFrame(web_contents(), ad_url); - - // Verify that we are evaluating subframe loads. - EXPECT_TRUE(observer.GetChildFrameLoadPolicy(ad_url).has_value()); - EXPECT_TRUE(observer.GetIsAdFrame(ad_frame->GetFrameTreeNodeId())); - - // Child frame created by ad script. - content::RenderFrameHost* ad_frame_tagged_by_script = - subresource_filter::CreateSrcFrameFromAdScript( - web_contents(), GetURL("frame_factory.html?1")); - - // Frames should be detected by script heuristics. - EXPECT_TRUE( - observer.GetIsAdFrame(ad_frame_tagged_by_script->GetFrameTreeNodeId())); -} - -// TODO(crbug.com/1210190): This test is flaky. -IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, DISABLED_FramesByURL) { - subresource_filter::TestSubresourceFilterObserver observer(web_contents()); - - // Main frame. - NavigateAndWaitForCompletion(GetURL("frame_factory.html"), shell()); - EXPECT_FALSE(observer.GetIsAdFrame( - web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId())); - - // (1) Vanilla child. - content::RenderFrameHost* vanilla_child = subresource_filter::CreateSrcFrame( - web_contents(), GetURL("frame_factory.html?1")); - EXPECT_FALSE(observer.GetIsAdFrame(vanilla_child->GetFrameTreeNodeId())); - - // (2) Ad child. - content::RenderFrameHost* ad_child = subresource_filter::CreateSrcFrame( - web_contents(), GetURL("frame_factory.html?2&ad=true")); - EXPECT_TRUE(observer.GetIsAdFrame(ad_child->GetFrameTreeNodeId())); - EXPECT_TRUE(subresource_filter::EvidenceForFrameComprises( - ad_child, /*parent_is_ad=*/false, - blink::mojom::FilterListResult::kMatchedBlockingRule, - blink::mojom::FrameCreationStackEvidence::kNotCreatedByAdScript)); - - // (3) Ad child of 2. - content::RenderFrameHost* ad_child_2 = subresource_filter::CreateSrcFrame( - ad_child, GetURL("frame_factory.html?sub=1&3&ad=true")); - EXPECT_TRUE(observer.GetIsAdFrame(ad_child_2->GetFrameTreeNodeId())); - EXPECT_TRUE(subresource_filter::EvidenceForFrameComprises( - ad_child_2, /*parent_is_ad=*/true, - blink::mojom::FilterListResult::kMatchedBlockingRule, - blink::mojom::FrameCreationStackEvidence::kCreatedByAdScript)); - - // (4) Vanilla child of 2. - content::RenderFrameHost* vanilla_child_2 = - subresource_filter::CreateSrcFrame(ad_child, - GetURL("frame_factory.html?4")); - EXPECT_TRUE(observer.GetIsAdFrame(vanilla_child_2->GetFrameTreeNodeId())); - EXPECT_TRUE(subresource_filter::EvidenceForFrameComprises( - vanilla_child_2, /*parent_is_ad=*/true, - blink::mojom::FilterListResult::kMatchedNoRules, - blink::mojom::FrameCreationStackEvidence::kCreatedByAdScript)); - - // (5) Vanilla child of 1. This tests something subtle. - // frame_factory.html?ad=true loads the same script that frame_factory.html - // uses to load frames. This tests that even though the script is tagged as an - // ad in the ad iframe, it's not considered an ad in the main frame, hence - // it's able to create an iframe that's not labeled as an ad. - content::RenderFrameHost* vanilla_child_3 = - subresource_filter::CreateSrcFrame(vanilla_child, - GetURL("frame_factory.html?5")); - EXPECT_FALSE(observer.GetIsAdFrame(vanilla_child_3->GetFrameTreeNodeId())); -} - -} // namespace weblayer
diff --git a/weblayer/browser/ads_page_load_metrics_observer_browsertest.cc b/weblayer/browser/ads_page_load_metrics_observer_browsertest.cc deleted file mode 100644 index 4a2c0dc..0000000 --- a/weblayer/browser/ads_page_load_metrics_observer_browsertest.cc +++ /dev/null
@@ -1,539 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> - -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/heavy_ad_intervention/heavy_ad_features.h" -#include "components/heavy_ad_intervention/heavy_ad_service.h" -#include "components/page_load_metrics/browser/ads_page_load_metrics_test_waiter.h" -#include "components/page_load_metrics/browser/observers/ad_metrics/ad_intervention_browser_test_utils.h" -#include "components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h" -#include "components/page_load_metrics/browser/observers/ad_metrics/frame_tree_data.h" -#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" -#include "components/subresource_filter/core/browser/subresource_filter_features.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "components/subresource_filter/core/common/test_ruleset_utils.h" -#include "components/ukm/test_ukm_recorder.h" -#include "content/public/common/content_switches.h" -#include "content/public/test/test_navigation_observer.h" -#include "net/test/embedded_test_server/controllable_http_response.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "weblayer/browser/heavy_ad_service_factory.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/subresource_filter_browser_test_harness.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -const char kAdsInterventionRecordedHistogram[] = - "SubresourceFilter.PageLoad.AdsInterventionTriggered"; - -const char kCrossOriginHistogramId[] = - "PageLoad.Clients.Ads.FrameCounts.AdFrames.PerFrame." - "OriginStatus"; - -const char kHeavyAdInterventionTypeHistogramId[] = - "PageLoad.Clients.Ads.HeavyAds.InterventionType2"; - -} // namespace - -class AdsPageLoadMetricsObserverBrowserTest - : public SubresourceFilterBrowserTest { - public: - AdsPageLoadMetricsObserverBrowserTest() { - scoped_feature_list_.InitWithFeaturesAndParameters( - {{subresource_filter::kAdTagging, {}}}, {}); - } - - ~AdsPageLoadMetricsObserverBrowserTest() override = default; - - std::unique_ptr<page_load_metrics::PageLoadMetricsTestWaiter> - CreatePageLoadMetricsTestWaiter() { - return std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( - web_contents()); - } - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")}); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -// Test that an embedded ad is same origin. -// TODO(crbug.com/1210190): This test is flaky. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - DISABLED_OriginStatusMetricEmbedded) { - base::HistogramTester histogram_tester; - auto waiter = CreatePageLoadMetricsTestWaiter(); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/ads_observer/srcdoc_embedded_ad.html"), - shell()); - // NOTE: The corresponding test in //chrome waits for 4 resources; the fourth - // resource waited for is a favicon fetch that doesn't happen in WebLayer. - waiter->AddMinimumCompleteResourcesExpectation(3); - waiter->Wait(); - NavigateAndWaitForCompletion(GURL(url::kAboutBlankURL), shell()); - histogram_tester.ExpectUniqueSample( - kCrossOriginHistogramId, page_load_metrics::OriginStatus::kSame, 1); -} - -// Test that an empty embedded ad isn't reported at all. -// TODO(crbug.com/1226500): This test is flaky. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - DISABLED_OriginStatusMetricEmbeddedEmpty) { - base::HistogramTester histogram_tester; - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL( - "/ads_observer/srcdoc_embedded_ad_empty.html"), - shell()); - NavigateAndWaitForCompletion(GURL(url::kAboutBlankURL), shell()); - histogram_tester.ExpectTotalCount(kCrossOriginHistogramId, 0); -} - -// Test that an ad with the same origin as the main page is same origin. -// TODO(crbug.com/1210190): This test is flaky. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - DISABLED_OriginStatusMetricSame) { - // Set the frame's resource as a rule. - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("pixel.png")}); - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto waiter = CreatePageLoadMetricsTestWaiter(); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/ads_observer/same_origin_ad.html"), - shell()); - // NOTE: The corresponding test in //chrome waits for 4 resources; the fourth - // resource waited for is a favicon fetch that doesn't // happen in WebLayer. - waiter->AddMinimumCompleteResourcesExpectation(3); - waiter->Wait(); - - NavigateAndWaitForCompletion(GURL(url::kAboutBlankURL), shell()); - histogram_tester.ExpectUniqueSample( - kCrossOriginHistogramId, page_load_metrics::OriginStatus::kSame, 1); - auto entries = - ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdFrameLoad::kStatus_CrossOriginName, - static_cast<int>(page_load_metrics::OriginStatus::kSame)); -} - -// Test that an ad with a different origin as the main page is cross origin. -// TODO(crbug.com/1210190): This test is flaky. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - DISABLED_OriginStatusMetricCross) { - // Note: Cannot navigate cross-origin without dynamically generating the URL. - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto waiter = CreatePageLoadMetricsTestWaiter(); - - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/iframe_blank.html"), shell()); - // Note that the initial iframe is not an ad, so the metric doesn't observe - // it initially as same origin. However, on re-navigating to a cross - // origin site that has an ad at its origin, the ad on that page is cross - // origin from the original page. - NavigateIframeToURL(web_contents(), "test", - embedded_test_server()->GetURL( - "a.com", "/ads_observer/same_origin_ad.html")); - - // Wait until all resource data updates are sent. Note that there is one more - // than in the tests above due to the navigation to same_origin_ad.html being - // itself made in an iframe. - waiter->AddMinimumCompleteResourcesExpectation(4); - waiter->Wait(); - NavigateAndWaitForCompletion(GURL(url::kAboutBlankURL), shell()); - histogram_tester.ExpectUniqueSample( - kCrossOriginHistogramId, page_load_metrics::OriginStatus::kCross, 1); - auto entries = - ukm_recorder.GetEntriesByName(ukm::builders::AdFrameLoad::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdFrameLoad::kStatus_CrossOriginName, - static_cast<int>(page_load_metrics::OriginStatus::kCross)); -} - -// This test harness does not start the test server and allows -// ControllableHttpResponses to be declared. -class AdsPageLoadMetricsObserverResourceBrowserTest - : public SubresourceFilterBrowserTest { - public: - AdsPageLoadMetricsObserverResourceBrowserTest() { - scoped_feature_list_.InitWithFeaturesAndParameters( - {{subresource_filter::kAdsInterventionsEnforced, {}}, - {subresource_filter::kAdTagging, {}}, - {heavy_ad_intervention::features::kHeavyAdIntervention, {}}, - {heavy_ad_intervention::features::kHeavyAdPrivacyMitigations, - {{"host-threshold", "3"}}}}, - {}); - } - - ~AdsPageLoadMetricsObserverResourceBrowserTest() override = default; - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("ad_script.js"), - subresource_filter::testing::CreateSuffixRule("ad_script_2.js"), - subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")}); - } - - protected: - std::unique_ptr<page_load_metrics::AdsPageLoadMetricsTestWaiter> - CreateAdsPageLoadMetricsTestWaiter() { - return std::make_unique<page_load_metrics::AdsPageLoadMetricsTestWaiter>( - web_contents()); - } - - // This function loads a |large_resource| and if |will_block| is set, then - // checks to see the resource is blocked, otherwise, it uses the |waiter| to - // wait until the resource is loaded. - void LoadHeavyAdResourceAndWaitOrError( - net::test_server::ControllableHttpResponse* large_resource, - page_load_metrics::PageLoadMetricsTestWaiter* waiter, - bool will_block) { - // Create a frame for the large resource. - EXPECT_TRUE(ExecJs(web_contents(), - "createAdFrame('/ads_observer/" - "ad_with_incomplete_resource.html', '');")); - - if (will_block) { - // If we expect the resource to be blocked, load a resource large enough - // to trigger the intervention and ensure that the navigation failed. - content::TestNavigationObserver error_observer( - web_contents(), net::ERR_BLOCKED_BY_CLIENT); - page_load_metrics::LoadLargeResource( - large_resource, page_load_metrics::kMaxHeavyAdNetworkSize); - error_observer.WaitForNavigationFinished(); - EXPECT_FALSE(error_observer.last_navigation_succeeded()); - } else { - // Otherwise load the resource, ensuring enough bytes were loaded. - int64_t current_network_bytes = waiter->current_network_bytes(); - page_load_metrics::LoadLargeResource( - large_resource, page_load_metrics::kMaxHeavyAdNetworkSize); - waiter->AddMinimumNetworkBytesExpectation( - current_network_bytes + page_load_metrics::kMaxHeavyAdNetworkSize); - waiter->Wait(); - } - } - - private: - // SubresourceFilterBrowserTest: - bool StartEmbeddedTestServerAutomatically() override { return false; } - - base::test::ScopedFeatureList scoped_feature_list_; -}; - -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest, - ReceivedAdResources) { - ASSERT_TRUE(embedded_test_server()->Start()); - - auto waiter = CreateAdsPageLoadMetricsTestWaiter(); - - NavigateAndWaitForCompletion(embedded_test_server()->GetURL( - "foo.com", "/ad_tagging/frame_factory.html"), - shell()); - - // Two subresources should have been reported as ads. - waiter->AddMinimumAdResourceExpectation(2); - waiter->Wait(); -} - -// Verifies that the frame is navigated to the intervention page when a -// heavy ad intervention triggers. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest, - HeavyAdInterventionEnabled_ErrorPageLoaded) { - base::HistogramTester histogram_tester; - auto incomplete_resource_response = - std::make_unique<net::test_server::ControllableHttpResponse>( - embedded_test_server(), "/ads_observer/incomplete_resource.js", - true /*relative_url_is_prefix*/); - ASSERT_TRUE(embedded_test_server()->Start()); - - // Create a navigation observer that will watch for the intervention to - // navigate the frame. - content::TestNavigationObserver error_observer(web_contents(), - net::ERR_BLOCKED_BY_CLIENT); - - auto waiter = CreateAdsPageLoadMetricsTestWaiter(); - GURL url = embedded_test_server()->GetURL( - "/ads_observer/ad_with_incomplete_resource.html"); - NavigateAndWaitForCompletion(url, shell()); - - // Load a resource large enough to trigger the intervention. - page_load_metrics::LoadLargeResource( - incomplete_resource_response.get(), - page_load_metrics::kMaxHeavyAdNetworkSize); - - // Wait for the intervention page navigation to finish on the frame. - error_observer.WaitForNavigationFinished(); - - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 1); - - // Check that the ad frame was navigated to the intervention page. - EXPECT_FALSE(error_observer.last_navigation_succeeded()); - - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 1); - histogram_tester.ExpectBucketCount( - "Blink.UseCounter.Features", - blink::mojom::WebFeature::kHeavyAdIntervention, 1); -} - -// Check that the Heavy Ad Intervention fires the correct number of times to -// protect privacy, and that after that limit is hit, the Ads Intervention -// Framework takes over for future navigations. -// TODO(crbug.com/1210190): This test is flaky. -IN_PROC_BROWSER_TEST_F( - AdsPageLoadMetricsObserverResourceBrowserTest, - DISABLED_HeavyAdInterventionBlocklistFull_InterventionBlocked) { - std::vector<std::unique_ptr<net::test_server::ControllableHttpResponse>> - http_responses(4); - for (auto& http_response : http_responses) { - http_response = - std::make_unique<net::test_server::ControllableHttpResponse>( - embedded_test_server(), "/ads_observer/incomplete_resource.js", - false /*relative_url_is_prefix*/); - } - base::HistogramTester histogram_tester; - ASSERT_TRUE(embedded_test_server()->Start()); - - // Create a waiter for the navigation and navigate. - auto waiter = CreateAdsPageLoadMetricsTestWaiter(); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL( - "foo.com", "/ad_tagging/frame_factory.html"), - shell()); - - // Load and block the resource. The ads intervention framework should not - // be triggered at this point. - LoadHeavyAdResourceAndWaitOrError(http_responses[0].get(), waiter.get(), - /*will_block=*/true); - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 1); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - - // Block a second resource on the page. The ads intervention framework should - // not be triggered at this point. - LoadHeavyAdResourceAndWaitOrError(http_responses[1].get(), waiter.get(), - /*will_block=*/true); - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 2); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - - // Create a new waiter for the next navigation and navigate. - waiter = CreateAdsPageLoadMetricsTestWaiter(); - // Set query to ensure that it's not treated as a reload as preview metrics - // are not recorded for reloads. - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL( - "foo.com", "/ad_tagging/frame_factory.html?avoid_reload"), - shell()); - - // Load and block the resource. The ads intervention framework should - // be triggered at this point. - LoadHeavyAdResourceAndWaitOrError(http_responses[2].get(), waiter.get(), - /*will_block=*/true); - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 3); - histogram_tester.ExpectUniqueSample( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kHeavyAdsInterventionAtHostLimit, - 1); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - - // Reset the waiter and navigate again. Check we show the Ads Intervention UI. - waiter.reset(); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL( - "foo.com", "/ad_tagging/frame_factory.html"), - shell()); - histogram_tester.ExpectUniqueSample( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kHeavyAdsInterventionAtHostLimit, - 1); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 1); -} - -// Check that clearing browsing data resets the number of times that the Heavy -// Ad Intervention has been triggered. -// TODO(crbug.com/1210190): This test is flaky. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceBrowserTest, - DISABLED_ClearBrowsingDataClearsHeavyAdBlocklist) { - std::vector<std::unique_ptr<net::test_server::ControllableHttpResponse>> - http_responses(4); - for (auto& http_response : http_responses) { - http_response = - std::make_unique<net::test_server::ControllableHttpResponse>( - embedded_test_server(), "/ads_observer/incomplete_resource.js", - false /*relative_url_is_prefix*/); - } - base::HistogramTester histogram_tester; - ASSERT_TRUE(embedded_test_server()->Start()); - - // Create a waiter for the navigation and navigate. - auto waiter = CreateAdsPageLoadMetricsTestWaiter(); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL( - "foo.com", "/ad_tagging/frame_factory.html"), - shell()); - - // Load and block the resource. The ads intervention framework should not - // be triggered at this point. - LoadHeavyAdResourceAndWaitOrError(http_responses[0].get(), waiter.get(), - /*will_block=*/true); - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 1); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - - // Block a second resource on the page. The ads intervention framework should - // not be triggered at this point. - LoadHeavyAdResourceAndWaitOrError(http_responses[1].get(), waiter.get(), - /*will_block=*/true); - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 2); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - - // Clear browsing data and wait for the heavy ad blocklist to be cleared and - // reloaded (note that waiting for the latter event is necessary as until the - // blocklist is loaded all hosts are treated as blocklisted, which - // interferes with the flow below). - auto* heavy_ad_service = HeavyAdServiceFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); - - base::RunLoop on_browsing_data_cleared_run_loop; - base::RunLoop on_blocklist_cleared_run_loop; - base::RunLoop on_blocklist_reloaded_run_loop; - - // First clear browsing data and wait for the blocklist to be cleared. - heavy_ad_service->NotifyOnBlocklistCleared( - on_blocklist_cleared_run_loop.QuitClosure()); - base::Time now = base::Time::Now(); - GetProfile()->ClearBrowsingData( - {BrowsingDataType::COOKIES_AND_SITE_DATA}, now - base::Days(1), now, - on_browsing_data_cleared_run_loop.QuitClosure()); - on_blocklist_cleared_run_loop.Run(); - - // Then wait for the blocklist to be reloaded before proceeding. - heavy_ad_service->NotifyOnBlocklistLoaded( - on_blocklist_reloaded_run_loop.QuitClosure()); - on_blocklist_reloaded_run_loop.Run(); - - // Create a new waiter for the next navigation and navigate. - waiter = CreateAdsPageLoadMetricsTestWaiter(); - // Set query to ensure that it's not treated as a reload as preview metrics - // are not recorded for reloads. - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL( - "foo.com", "/ad_tagging/frame_factory.html?avoid_reload"), - shell()); - - // Load and block the resource. The ads intervention framework should not be - // triggered at this point as the heavy ad blocklist was cleared as part of - // clearing browsing data. - LoadHeavyAdResourceAndWaitOrError(http_responses[2].get(), waiter.get(), - /*will_block=*/true); - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 3); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - - // Reset the waiter and navigate again. Check we don't show the Ads - // Intervention UI. - waiter.reset(); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL( - "foo.com", "/ad_tagging/frame_factory.html"), - shell()); - // Note that the below metric will not have been updated due to this - // navigation being trated as a reload. - histogram_tester.ExpectUniqueSample( - kHeavyAdInterventionTypeHistogramId, - page_load_metrics::HeavyAdStatus::kNetwork, 3); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); -} - -class AdsPageLoadMetricsObserverResourceIncognitoBrowserTest - : public AdsPageLoadMetricsObserverResourceBrowserTest { - public: - AdsPageLoadMetricsObserverResourceIncognitoBrowserTest() { - SetShellStartsInIncognitoMode(); - } -}; - -// Verifies that the blocklist is setup correctly and the intervention triggers -// in incognito mode. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverResourceIncognitoBrowserTest, - HeavyAdInterventionIncognitoMode_InterventionFired) { - base::HistogramTester histogram_tester; - auto incomplete_resource_response = - std::make_unique<net::test_server::ControllableHttpResponse>( - embedded_test_server(), "/ads_observer/incomplete_resource.js", - true /*relative_url_is_prefix*/); - ASSERT_TRUE(embedded_test_server()->Start()); - - // Create a navigation observer that will watch for the intervention to - // navigate the frame. - content::TestNavigationObserver error_observer(web_contents(), - net::ERR_BLOCKED_BY_CLIENT); - - // Create a waiter for the incognito contents. - auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( - web_contents()); - GURL url = embedded_test_server()->GetURL( - "/ads_observer/ad_with_incomplete_resource.html"); - NavigateAndWaitForCompletion(url, shell()); - - // Load a resource large enough to trigger the intervention. - page_load_metrics::LoadLargeResource( - incomplete_resource_response.get(), - page_load_metrics::kMaxHeavyAdNetworkSize); - - // Wait for the intervention page navigation to finish on the frame. - error_observer.WaitForNavigationFinished(); - - // Check that the ad frame was navigated to the intervention page. - EXPECT_FALSE(error_observer.last_navigation_succeeded()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/access_token_fetch_browsertest.cc b/weblayer/browser/android/access_token_fetch_browsertest.cc deleted file mode 100644 index 1b9736e..0000000 --- a/weblayer/browser/android/access_token_fetch_browsertest.cc +++ /dev/null
@@ -1,240 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/android/scoped_java_ref.h" -#include "base/functional/bind.h" -#include "base/functional/callback.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/google_account_access_token_fetch_delegate.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browsertests_jni/AccessTokenFetchTestBridge_jni.h" -#include "weblayer/test/weblayer_browsertests_jni/GoogleAccountAccessTokenFetcherTestStub_jni.h" - -namespace weblayer { - -// Callback passed to GoogleAccountAccessTokenFetcherDelegate to be invoked on -// access token fetch completion. -void OnAccessTokenFetched(base::OnceClosure quit_closure, - std::string* target_token, - const std::string& received_token) { - *target_token = received_token; - std::move(quit_closure).Run(); -} - -// Utility to convert an array of Java strings to a set of std::string. -std::set<std::string> ConvertJavaStringArrayToStringSet( - const base::android::JavaRef<jobjectArray>& jstring_array) { - JNIEnv* env = base::android::AttachCurrentThread(); - - std::vector<std::string> string_array; - base::android::AppendJavaStringArrayToStringVector(env, jstring_array, - &string_array); - - return std::set<std::string>(string_array.begin(), string_array.end()); -} - -// Utility to return the scopes from the most recent access token request to -// |java_client_stub|. -std::set<std::string> GetMostRecentRequestScopes( - base::android::ScopedJavaLocalRef<jobject> java_client_stub) { - JNIEnv* env = base::android::AttachCurrentThread(); - - return ConvertJavaStringArrayToStringSet( - Java_GoogleAccountAccessTokenFetcherTestStub_getMostRecentRequestScopes( - env, java_client_stub)); -} - -// Utility to return the scopes from the most recent invalid access token -// notification to |java_client_stub|. -std::set<std::string> GetScopesForMostRecentInvalidToken( - base::android::ScopedJavaLocalRef<jobject> java_client_stub) { - JNIEnv* env = base::android::AttachCurrentThread(); - - return ConvertJavaStringArrayToStringSet( - Java_GoogleAccountAccessTokenFetcherTestStub_getScopesForMostRecentInvalidToken( - env, java_client_stub)); -} - -// Utility to return the token from the most recent invalid access token -// notification to |java_client_stub|. -std::string GetMostRecentInvalidToken( - base::android::ScopedJavaLocalRef<jobject> java_client_stub) { - JNIEnv* env = base::android::AttachCurrentThread(); - - return base::android::ConvertJavaStringToUTF8( - env, - Java_GoogleAccountAccessTokenFetcherTestStub_getMostRecentInvalidToken( - env, java_client_stub)); -} - -// Tests proper operation of access token fetches initiated from C++ when the -// embedder has set a client for access token fetches in Java. -class AccessTokenFetchBrowserTest : public WebLayerBrowserTest { - public: - AccessTokenFetchBrowserTest() {} - ~AccessTokenFetchBrowserTest() override = default; - - protected: - ProfileImpl* profile() { - auto* tab_impl = static_cast<TabImpl*>(shell()->tab()); - return tab_impl->profile(); - } - - GoogleAccountAccessTokenFetchDelegate* access_token_fetch_delegate() { - return profile()->access_token_fetch_delegate(); - } -}; - -// Tests that when the embedder hasn't set a -// GoogleAccountAccessTokenFetcherClient instance in Java, access token fetches -// from C++ on Android result in the empty string being returned. -IN_PROC_BROWSER_TEST_F(AccessTokenFetchBrowserTest, - NoGoogleAccountAccessTokenFetcherClientSetInJava) { - base::RunLoop run_loop; - std::string access_token = "dummy"; - - access_token_fetch_delegate()->FetchAccessToken( - {"scope1"}, base::BindOnce(&OnAccessTokenFetched, run_loop.QuitClosure(), - &access_token)); - - run_loop.Run(); - - EXPECT_EQ("", access_token); -} - -// Tests that when the embedder sets a Java client that returns a given access -// token, access token fetches initiated from C++ resolve to that token. -IN_PROC_BROWSER_TEST_F(AccessTokenFetchBrowserTest, SuccessfulFetch) { - base::RunLoop run_loop; - std::string access_token = ""; - std::string kTokenFromResponse = "token"; - std::set<std::string> kScopes = {"scope1", "scope2"}; - - JNIEnv* env = base::android::AttachCurrentThread(); - - base::android::ScopedJavaLocalRef<jobject> java_client_stub = - Java_AccessTokenFetchTestBridge_installGoogleAccountAccessTokenFetcherTestStub( - env, profile()->GetJavaProfile()); - - access_token_fetch_delegate()->FetchAccessToken( - kScopes, base::BindOnce(&OnAccessTokenFetched, run_loop.QuitClosure(), - &access_token)); - EXPECT_EQ("", access_token); - - EXPECT_EQ( - 1, Java_GoogleAccountAccessTokenFetcherTestStub_getNumOutstandingRequests( - env, java_client_stub)); - int request_id = - Java_GoogleAccountAccessTokenFetcherTestStub_getMostRecentRequestId( - env, java_client_stub); - - auto most_recent_request_scopes = - GetMostRecentRequestScopes(java_client_stub); - EXPECT_EQ(kScopes, most_recent_request_scopes); - - Java_GoogleAccountAccessTokenFetcherTestStub_respondWithTokenForRequest( - env, java_client_stub, request_id, - base::android::ConvertUTF8ToJavaString(env, kTokenFromResponse)); - run_loop.Run(); - - EXPECT_EQ(kTokenFromResponse, access_token); -} - -// Tests correct operation when there are multiple ongoing fetches. -IN_PROC_BROWSER_TEST_F(AccessTokenFetchBrowserTest, MultipleFetches) { - base::RunLoop run_loop1; - base::RunLoop run_loop2; - std::string access_token1 = ""; - std::string access_token2 = ""; - std::string kTokenFromResponse1 = "token1"; - std::string kTokenFromResponse2 = "token2"; - std::set<std::string> kScopes1 = {"scope1", "scope2"}; - std::set<std::string> kScopes2 = {"scope3"}; - - JNIEnv* env = base::android::AttachCurrentThread(); - - base::android::ScopedJavaLocalRef<jobject> java_client_stub = - Java_AccessTokenFetchTestBridge_installGoogleAccountAccessTokenFetcherTestStub( - env, profile()->GetJavaProfile()); - - access_token_fetch_delegate()->FetchAccessToken( - kScopes1, base::BindOnce(&OnAccessTokenFetched, run_loop1.QuitClosure(), - &access_token1)); - EXPECT_EQ( - 1, Java_GoogleAccountAccessTokenFetcherTestStub_getNumOutstandingRequests( - env, java_client_stub)); - int request_id1 = - Java_GoogleAccountAccessTokenFetcherTestStub_getMostRecentRequestId( - env, java_client_stub); - auto most_recent_request_scopes1 = - GetMostRecentRequestScopes(java_client_stub); - EXPECT_EQ(kScopes1, most_recent_request_scopes1); - - EXPECT_EQ("", access_token1); - EXPECT_EQ("", access_token2); - - access_token_fetch_delegate()->FetchAccessToken( - kScopes2, base::BindOnce(&OnAccessTokenFetched, run_loop2.QuitClosure(), - &access_token2)); - - EXPECT_EQ( - 2, Java_GoogleAccountAccessTokenFetcherTestStub_getNumOutstandingRequests( - env, java_client_stub)); - int request_id2 = - Java_GoogleAccountAccessTokenFetcherTestStub_getMostRecentRequestId( - env, java_client_stub); - auto most_recent_request_scopes2 = - GetMostRecentRequestScopes(java_client_stub); - EXPECT_EQ(kScopes2, most_recent_request_scopes2); - - EXPECT_EQ("", access_token1); - EXPECT_EQ("", access_token2); - - Java_GoogleAccountAccessTokenFetcherTestStub_respondWithTokenForRequest( - env, java_client_stub, request_id2, - base::android::ConvertUTF8ToJavaString(env, kTokenFromResponse2)); - run_loop2.Run(); - - EXPECT_EQ("", access_token1); - EXPECT_EQ(kTokenFromResponse2, access_token2); - - Java_GoogleAccountAccessTokenFetcherTestStub_respondWithTokenForRequest( - env, java_client_stub, request_id1, - base::android::ConvertUTF8ToJavaString(env, kTokenFromResponse1)); - run_loop1.Run(); - - EXPECT_EQ(kTokenFromResponse1, access_token1); - EXPECT_EQ(kTokenFromResponse2, access_token2); -} - -// Tests that when the C++ delegate is notified that an access token has been -// identified as invalid, that information is forwarded to the Java side. -IN_PROC_BROWSER_TEST_F(AccessTokenFetchBrowserTest, - AccessTokenIdentifiedAsInvalid) { - const std::string kInvalidToken = "token"; - const std::set<std::string> kScopesForInvalidToken = {"scope1", "scope2"}; - - JNIEnv* env = base::android::AttachCurrentThread(); - - base::android::ScopedJavaLocalRef<jobject> java_client_stub = - Java_AccessTokenFetchTestBridge_installGoogleAccountAccessTokenFetcherTestStub( - env, profile()->GetJavaProfile()); - - EXPECT_EQ(std::set<std::string>(), - GetScopesForMostRecentInvalidToken(java_client_stub)); - EXPECT_EQ("", GetMostRecentInvalidToken(java_client_stub)); - - access_token_fetch_delegate()->OnAccessTokenIdentifiedAsInvalid( - kScopesForInvalidToken, kInvalidToken); - - EXPECT_EQ(kScopesForInvalidToken, - GetScopesForMostRecentInvalidToken(java_client_stub)); - EXPECT_EQ(kInvalidToken, GetMostRecentInvalidToken(java_client_stub)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/ad_density_intervention_browsertest.cc b/weblayer/browser/android/ad_density_intervention_browsertest.cc deleted file mode 100644 index e56587f..0000000 --- a/weblayer/browser/android/ad_density_intervention_browsertest.cc +++ /dev/null
@@ -1,236 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> - -#include "base/test/scoped_feature_list.h" -#include "components/infobars/content/content_infobar_manager.h" -#include "components/infobars/core/infobar.h" -#include "components/infobars/core/infobar_delegate.h" -#include "components/infobars/core/infobar_manager.h" -#include "components/page_load_metrics/browser/observers/ad_metrics/ad_intervention_browser_test_utils.h" -#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" -#include "components/subresource_filter/core/browser/subresource_filter_features.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "components/subresource_filter/core/common/test_ruleset_utils.h" -#include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" -#include "components/ukm/test_ukm_recorder.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/display/screen_info.h" -#include "ui/gfx/geometry/rect.h" -#include "url/gurl.h" -#include "weblayer/test/subresource_filter_browser_test_harness.h" - -namespace weblayer { - -namespace { - -const char kAdsInterventionRecordedHistogram[] = - "SubresourceFilter.PageLoad.AdsInterventionTriggered"; - -} // namespace - -class AdDensityViolationBrowserTest : public SubresourceFilterBrowserTest { - public: - AdDensityViolationBrowserTest() = default; - - void SetUp() override { - std::vector<base::test::FeatureRef> enabled = { - subresource_filter::kAdTagging, - subresource_filter::kAdsInterventionsEnforced}; - std::vector<base::test::FeatureRef> disabled = {}; - - feature_list_.InitWithFeatures(enabled, disabled); - SubresourceFilterBrowserTest::SetUp(); - } - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")}); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -IN_PROC_BROWSER_TEST_F( - AdDensityViolationBrowserTest, - MobilePageAdDensityByHeightAbove30_AdInterventionTriggered) { - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - - auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( - web_contents()); - const GURL url(embedded_test_server()->GetURL( - "a.com", "/ads_observer/blank_with_adiframe_writer.html")); - - waiter->SetMainFrameIntersectionExpectation(); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - waiter->Wait(); - - int document_height = page_load_metrics::GetDocumentHeight(web_contents()); - - int frame_width = 100; // Ad density by height is independent of frame width. - int frame_height = document_height * 0.45; - - // Create the frame with b.com as origin to not get caught by - // restricted ad tagging. - page_load_metrics::CreateAndWaitForIframeAtRect( - web_contents(), waiter.get(), - embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"), - gfx::Rect(0, 0, frame_width, frame_height)); - - // Delete the page load metrics test waiter instead of reinitializing it - // for the next page load. - waiter.reset(); - - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - // blank_with_adiframe_writer loads a script tagged as an ad, verify it is not - // loaded and the subresource filter UI for ad blocking is shown. - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents()) - ->infobar_count(), - 1u); - EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents()) - ->infobar_at(0) - ->delegate() - ->GetIdentifier(), - infobars::InfoBarDelegate::ADS_BLOCKED_INFOBAR_DELEGATE_ANDROID); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30), - 1); -} - -IN_PROC_BROWSER_TEST_F( - AdDensityViolationBrowserTest, - MobilePageAdDensityByHeightBelow30_AdInterventionNotTriggered) { - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - - auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( - web_contents()); - const GURL url(embedded_test_server()->GetURL( - "a.com", "/ads_observer/blank_with_adiframe_writer.html")); - - waiter->SetMainFrameIntersectionExpectation(); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - waiter->Wait(); - - int document_height = page_load_metrics::GetDocumentHeight(web_contents()); - - int frame_width = 100; // Ad density by height is independent of frame width. - int frame_height = document_height * 0.25; - - // Create the frame with b.com as origin to not get caught by - // restricted ad tagging. - page_load_metrics::CreateAndWaitForIframeAtRect( - web_contents(), waiter.get(), - embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"), - gfx::Rect(0, 0, frame_width, frame_height)); - - // Delete the page load metrics test waiter instead of reinitializing it - // for the next page load. - waiter.reset(); - - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - // blank_with_adiframe_writer loads a script tagged as an ad, verify it is - // loaded as ads are not blocked and the subresource filter UI is not - // shown. - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - - // No ads blocked infobar should be shown as we have not triggered the - // intervention. - EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents()) - ->infobar_count(), - 0u); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); -} - -class AdDensityViolationBrowserTestWithoutEnforcement - : public SubresourceFilterBrowserTest { - public: - AdDensityViolationBrowserTestWithoutEnforcement() = default; - - void SetUp() override { - std::vector<base::test::FeatureRef> enabled = { - subresource_filter::kAdTagging}; - std::vector<base::test::FeatureRef> disabled = { - subresource_filter::kAdsInterventionsEnforced}; - - feature_list_.InitWithFeatures(enabled, disabled); - SubresourceFilterBrowserTest::SetUp(); - } - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")}); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -IN_PROC_BROWSER_TEST_F( - AdDensityViolationBrowserTestWithoutEnforcement, - MobilePageAdDensityByHeightAbove30_NoAdInterventionTriggered) { - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - - auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>( - web_contents()); - const GURL url(embedded_test_server()->GetURL( - "a.com", "/ads_observer/blank_with_adiframe_writer.html")); - - waiter->SetMainFrameIntersectionExpectation(); - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - waiter->Wait(); - - int document_height = page_load_metrics::GetDocumentHeight(web_contents()); - - int frame_width = 100; // Ad density by height is independent of frame width. - int frame_height = document_height * 0.45; - - // Create the frame with b.com as origin to not get caught by - // restricted ad tagging. - page_load_metrics::CreateAndWaitForIframeAtRect( - web_contents(), waiter.get(), - embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"), - gfx::Rect(0, 0, frame_width, frame_height)); - - // Delete the page load metrics test waiter instead of reinitializing it - // for the next page load. - waiter.reset(); - - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - // We are not enforcing ad blocking on ads violations, site should load - // as expected without subresource filter UI. - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - - // No ads blocked infobar should be shown as we have not triggered the - // intervention. - EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents()) - ->infobar_count(), - 0u); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30), - 1); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/application_info_helper.cc b/weblayer/browser/android/application_info_helper.cc deleted file mode 100644 index 1a1dd116..0000000 --- a/weblayer/browser/android/application_info_helper.cc +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/android/application_info_helper.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "weblayer/browser/java/base_module_jni/ApplicationInfoHelper_jni.h" - -namespace weblayer { - -// static -bool GetApplicationMetadataAsBoolean(const std::string& key, - bool default_value) { - auto* env = base::android::AttachCurrentThread(); - return Java_ApplicationInfoHelper_getMetadataAsBoolean( - env, base::android::ConvertUTF8ToJavaString(env, key), default_value); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/application_info_helper.h b/weblayer/browser/android/application_info_helper.h deleted file mode 100644 index c4846eb..0000000 --- a/weblayer/browser/android/application_info_helper.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_APPLICATION_INFO_HELPER_H_ -#define WEBLAYER_BROWSER_ANDROID_APPLICATION_INFO_HELPER_H_ - -#include <string> - -namespace weblayer { - -// Looks for a metadata tag with name |key| in the application's manifest, and -// returns its value if found, or |default_value| otherwise. -bool GetApplicationMetadataAsBoolean(const std::string& key, - bool default_value); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_APPLICATION_INFO_HELPER_H_
diff --git a/weblayer/browser/android/exception_filter.cc b/weblayer/browser/android/exception_filter.cc deleted file mode 100644 index e086ed20..0000000 --- a/weblayer/browser/android/exception_filter.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/android/exception_filter.h" - -#include "weblayer/browser/java/jni/WebLayerExceptionFilter_jni.h" - -namespace weblayer { - -bool WebLayerJavaExceptionFilter( - const base::android::JavaRef<jthrowable>& throwable) { - return Java_WebLayerExceptionFilter_stackTraceContainsWebLayerCode( - base::android::AttachCurrentThread(), throwable); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/exception_filter.h b/weblayer/browser/android/exception_filter.h deleted file mode 100644 index bc8a8cd..0000000 --- a/weblayer/browser/android/exception_filter.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_EXCEPTION_FILTER_H_ -#define WEBLAYER_BROWSER_ANDROID_EXCEPTION_FILTER_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" - -namespace weblayer { - -// Called when an uncaught exception is detected. A return value of true -// indicates the exception is likely relevant to WebLayer. -bool WebLayerJavaExceptionFilter( - const base::android::JavaRef<jthrowable>& throwable); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_EXCEPTION_FILTER_H_
diff --git a/weblayer/browser/android/javatests/AndroidManifest.xml b/weblayer/browser/android/javatests/AndroidManifest.xml deleted file mode 100644 index 4d930b68..0000000 --- a/weblayer/browser/android/javatests/AndroidManifest.xml +++ /dev/null
@@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2019 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chromium.webengine.tests"> - <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - <!-- We add an application tag here just so that we can indicate that this - package needs to link against the android.test library, which is - needed when building test cases. --> - <application> - <uses-library android:name="android.test.runner" /> - <activity android:name="org.chromium.test.broker.OnDeviceInstrumentationBroker" - android:exported="true"/> - </application> - - <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner" - android:targetPackage="org.chromium.webengine.test.instrumentation_test_apk" - android:label="JUnit4-based tests for org.chromium.webengine.test.instrumentation_test_apk" /> -</manifest>
diff --git a/weblayer/browser/android/javatests/BUILD.gn b/weblayer/browser/android/javatests/BUILD.gn deleted file mode 100644 index f2bf6cf..0000000 --- a/weblayer/browser/android/javatests/BUILD.gn +++ /dev/null
@@ -1,185 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//android_webview/system_webview_apk_tmpl.gni") -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") - -android_library("webengine_java_tests") { - testonly = true - sources = [ - "src/org/chromium/webengine/test/AllowedOriginsTest.java", - "src/org/chromium/webengine/test/CookieManagerTest.java", - "src/org/chromium/webengine/test/ExecuteScriptTest.java", - "src/org/chromium/webengine/test/ExternalIntentsTest.java", - "src/org/chromium/webengine/test/FaviconTest.java", - "src/org/chromium/webengine/test/PostMessageTest.java", - "src/org/chromium/webengine/test/ProfileManagerTest.java", - "src/org/chromium/webengine/test/StatePersistenceTest.java", - "src/org/chromium/webengine/test/TabManagerTest.java", - "src/org/chromium/webengine/test/TabNavigationControllerTest.java", - "src/org/chromium/webengine/test/TabPrerenderTest.java", - "src/org/chromium/webengine/test/WebEngineTest.java", - "src/org/chromium/webengine/test/WebFragmentTest.java", - "src/org/chromium/webengine/test/WebSandboxTest.java", - ] - deps = [ - ":webengine_instrumentation_test_java", - ":webengine_java_test_support", - "//base:base_java", - "//base:base_java_test_support", - "//components/browser_ui/share/android:java", - "//components/safe_browsing/android:safe_browsing_java", - "//content/public/android:content_java", - "//content/public/test/android:content_java_test_support", - "//net/android:net_java_test_support", - "//third_party/android_deps:com_google_guava_listenablefuture_java", - "//third_party/android_deps:guava_android_java", - "//third_party/androidx:androidx_activity_activity_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_test_core_java", - "//third_party/androidx:androidx_test_monitor_java", - "//third_party/androidx:androidx_test_runner_java", - "//third_party/blink/public/common:common_java", - "//third_party/hamcrest:hamcrest_core_java", - "//third_party/junit:junit", - "//weblayer/public/java:webengine_java", - "//weblayer/public/javatests:weblayer_public_javatests", - ] -} - -_webengine_instrumentation_test_strings = - "$target_gen_dir/instrumentation_test_apk/res/values/strings.xml" - -jinja_template("webengine_instrumentation_test_strings") { - input = "instrumentation_test_apk/res_template/values/strings.xml" - output = _webengine_instrumentation_test_strings -} - -android_resources("webengine_instrumentation_resources") { - sources = [ - "instrumentation_test_apk/res/layout/main.xml", - "instrumentation_test_apk/res/values/styles.xml", - _webengine_instrumentation_test_strings, - ] - deps = [ ":webengine_instrumentation_test_strings" ] -} - -android_library("webengine_instrumentation_test_java") { - testonly = true - resources_package = "org.chromium.webengine.test.instrumentation_test_apk" - - sources = [ "instrumentation_test_apk/src/org/chromium/webengine/test/instrumentation_test_apk/InstrumentationActivity.java" ] - - deps = [ - ":webengine_instrumentation_resources", - "//third_party/android_deps:com_google_guava_listenablefuture_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//weblayer/public/java:webengine_java", - ] -} - -_webengine_instrumentation_apk_android_manifest = - "$target_gen_dir/instrumentation_test_apk/AndroidManifest.xml" - -jinja_template("webengine_instrumentation_apk_manifest") { - input = "instrumentation_test_apk/AndroidManifest.xml" - output = _webengine_instrumentation_apk_android_manifest - - variables = [ "browser_process_mode=local" ] -} - -android_apk("webengine_instrumentation_test_apk") { - testonly = true - - apk_name = "WebengineInstrumentationTest" - android_manifest = _webengine_instrumentation_apk_android_manifest - android_manifest_dep = ":webengine_instrumentation_apk_manifest" - - deps = [ - ":webengine_instrumentation_test_java", - "//weblayer/public/java:service_provider_java", - "//weblayer/shell/android:webengine_service_provider_resources", - ] - - # Test runner does not support having "additional apks" that are incremental. - never_incremental = true - - target_sdk_version = 28 -} - -android_library("webengine_java_test_support") { - testonly = true - sources = [ - "src/org/chromium/webengine/test/DigitalAssetLinksServerRule.java", - "src/org/chromium/webengine/test/InstrumentationActivityTestRule.java", - "src/org/chromium/webengine/test/WebEngineActivityTestRule.java", - "src/org/chromium/webengine/test/WebEngineJUnit4ClassRunner.java", - ] - deps = [ - ":webengine_instrumentation_test_java", - "//base:base_java", - "//base:base_java_test_support", - "//content/public/test/android:content_java_test_support", - "//net/android:net_java_test_support", - "//third_party/android_deps:com_google_guava_listenablefuture_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_test_monitor_java", - "//third_party/junit:junit", - "//ui/android:ui_java_test_support", - "//weblayer/public/java:webengine_java", - ] -} - -android_library("external_intents_apk_java") { - sources = [ "external_intents/src/org/chromium/webengine/test/external/intents/ExternalIntentsTestActivity.java" ] -} - -android_apk("external_intents_apk") { - apk_name = "external_intents_apk" - android_manifest = "external_intents/AndroidManifest.xml" - - deps = [ - ":external_intents_apk_java", - "//weblayer/public/java:webengine_java", - ] -} - -template("webengine_instrumentation") { - instrumentation_test_apk(target_name) { - forward_variables_from(invoker, "*") - - android_manifest = "AndroidManifest.xml" - - if (!defined(additional_apks)) { - additional_apks = [] - } - additional_apks += [ "//net/android:net_test_support_apk" ] - data = [ - "//content/test/data/android/authenticator.html", - "//weblayer/test/data/", - ] - - # The instrumentation test should not be obfuscated otherwise the shell cannot be loaded. - proguard_enabled = false - } -} - -# Runs the instrumentation tests loading the implementation from the WebLayer -# support library. -webengine_instrumentation("webengine_support_instrumentation_test_apk") { - apk_name = "WebEngineSupportInstrumentationTest" - apk_under_test = ":webengine_instrumentation_test_apk" - additional_apks = [ - "//weblayer/shell/android:weblayer_support_apk", - ":external_intents_apk", - ] - - deps = [ ":webengine_java_tests" ] -}
diff --git a/weblayer/browser/android/javatests/DEPS b/weblayer/browser/android/javatests/DEPS deleted file mode 100644 index 2e8d009..0000000 --- a/weblayer/browser/android/javatests/DEPS +++ /dev/null
@@ -1,13 +0,0 @@ -include_rules = [ - "-content/public", - "+content/public/test", - - # WebEngineJUnit4ClassRunner should be used for all tests since it has logic to - # make command line flags work in WebLayer. - "-base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java", -] -specific_include_rules = { - "WebEngineJUnit4ClassRunner.java": [ - "+base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java", - ] -}
diff --git a/weblayer/browser/android/javatests/external_intents/AndroidManifest.xml b/weblayer/browser/android/javatests/external_intents/AndroidManifest.xml deleted file mode 100644 index c2be45d..0000000 --- a/weblayer/browser/android/javatests/external_intents/AndroidManifest.xml +++ /dev/null
@@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<!-- External intents need to target a separate application otherwise -chromium the external intents component will not launch an intent. So we need to -test this with a different activity. --> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="org.chromium.webengine.test.external.intents"> - - <application android:label="ExternalIntents test app"> - <activity - android:name="ExternalIntentsTestActivity" - android:launchMode="singleTask" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.BROWSABLE" /> - <data android:scheme="webenginetest" android:host="state.app" /> - </intent-filter> - </activity> - </application> -</manifest> \ No newline at end of file
diff --git a/weblayer/browser/android/javatests/external_intents/src/org/chromium/webengine/test/external/intents/ExternalIntentsTestActivity.java b/weblayer/browser/android/javatests/external_intents/src/org/chromium/webengine/test/external/intents/ExternalIntentsTestActivity.java deleted file mode 100644 index 9811678d..0000000 --- a/weblayer/browser/android/javatests/external_intents/src/org/chromium/webengine/test/external/intents/ExternalIntentsTestActivity.java +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test.external.intents; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Intent; -import android.os.Bundle; - -/** - * Used by the external intents test. The problem is that the external intents - * only be launched for packages outside of the package the tests are being - * run from so this needs to be in a separate application. - * - * This exists to start the activity that called it. - * - * This activity will kill itself to clean up after it has been backgrounded. - */ -public class ExternalIntentsTestActivity extends Activity { - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - String returnTo = getIntent().getData().getQueryParameter("return_to"); - - if (returnTo != null) { - ComponentName componentCaller = ComponentName.unflattenFromString(returnTo); - - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setComponent(componentCaller); - intent.putExtra("LAUNCHED_EXTERNAL", true); - - // We are just returning back because the instrumentation activity is - // set to single task. - startActivity(intent); - } - } - - @Override - protected void onPause() { - // We want to clean up, but only when we're leaving to ensure that it - // starts the previous activity with its intent. - finish(); - } -}
diff --git a/weblayer/browser/android/javatests/instrumentation_test_apk/AndroidManifest.xml b/weblayer/browser/android/javatests/instrumentation_test_apk/AndroidManifest.xml deleted file mode 100644 index f8b5df7..0000000 --- a/weblayer/browser/android/javatests/instrumentation_test_apk/AndroidManifest.xml +++ /dev/null
@@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="org.chromium.webengine.test.instrumentation_test_apk"> - - <application android:label="WE Instrumentation Test APK" - tools:replace="android:label" - android:supportsRtl="true"> - <activity android:name="InstrumentationActivity" - android:launchMode="singleTask" - android:theme="@style/ShellTheme" - android:windowSoftInputMode="adjustResize" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <meta-data android:name="asset_statements" android:resource="@string/asset_statements" /> - - <meta-data android:name="org.chromium.webengine.shell.BrowserProcessMode" - android:value="{{ browser_process_mode }}"/> - </application> -</manifest>
diff --git a/weblayer/browser/android/javatests/instrumentation_test_apk/res/layout/main.xml b/weblayer/browser/android/javatests/instrumentation_test_apk/res/layout/main.xml deleted file mode 100644 index bcff4432..0000000 --- a/weblayer/browser/android/javatests/instrumentation_test_apk/res/layout/main.xml +++ /dev/null
@@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -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" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <androidx.fragment.app.FragmentContainerView - android:id="@+id/fragment_container_view" - android:layout_width="match_parent" - android:layout_height="match_parent" /> -</LinearLayout>
diff --git a/weblayer/browser/android/javatests/instrumentation_test_apk/res/values/styles.xml b/weblayer/browser/android/javatests/instrumentation_test_apk/res/values/styles.xml deleted file mode 100644 index 5396282..0000000 --- a/weblayer/browser/android/javatests/instrumentation_test_apk/res/values/styles.xml +++ /dev/null
@@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2022 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<resources xmlns:tools="http://schemas.android.com/tools"> - <style name="ShellTheme" parent="Theme.AppCompat.DayNight.NoActionBar"/> -</resources> \ No newline at end of file
diff --git a/weblayer/browser/android/javatests/instrumentation_test_apk/res_template/values/strings.xml b/weblayer/browser/android/javatests/instrumentation_test_apk/res_template/values/strings.xml deleted file mode 100644 index 61a1c4d..0000000 --- a/weblayer/browser/android/javatests/instrumentation_test_apk/res_template/values/strings.xml +++ /dev/null
@@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2022 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<resources xmlns:tools="http://schemas.android.com/tools"> - <string name="asset_statements"> - [ - {# - Add all localhost origins with ports in the 8900s range as 1P origins. - This is to avoid flakiness in tests by relying on having a specific port available. - // LINT.IfChange - #} - {% for i in range(8900, 9000) %} - {# - // LINT.ThenChange( - // //weblayer/browser/android/javatests/src/org/chromium/webengine/test/DigitalAssetLinksServerRule.java - // ) - #} - { - \"relation\": [\"delegate_permission/common.handle_all_urls\"], - \"target\": { - \"namespace\": \"web\", - \"site\": \"http://localhost:{{ i }}\" - } - }, - {% endfor %} - { - \"relation\": [\"delegate_permission/common.handle_all_urls\"], - \"target\": { - \"namespace\": \"web\", - \"site\": \"https://example.com\" - } - } - ] - </string> -</resources> \ No newline at end of file
diff --git a/weblayer/browser/android/javatests/instrumentation_test_apk/src/org/chromium/webengine/test/instrumentation_test_apk/InstrumentationActivity.java b/weblayer/browser/android/javatests/instrumentation_test_apk/src/org/chromium/webengine/test/instrumentation_test_apk/InstrumentationActivity.java deleted file mode 100644 index 0f258e46..0000000 --- a/weblayer/browser/android/javatests/instrumentation_test_apk/src/org/chromium/webengine/test/instrumentation_test_apk/InstrumentationActivity.java +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test.instrumentation_test_apk; - -import android.content.Intent; -import android.os.Bundle; -import android.view.View; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.WebFragment; -import org.chromium.webengine.WebSandbox; - -import java.util.List; - -/** - * Activity for running instrumentation tests. - */ -public class InstrumentationActivity extends AppCompatActivity { - private ListenableFuture<WebSandbox> mWebSandboxFuture; - private ListenableFuture<String> mWebSandboxVersionFuture; - private LifeCycleListener mLifeCycleListener; - - /** - * Use this to listen for life cycle events in tests. - */ - public interface LifeCycleListener { - void onNewIntent(Intent intent); - } - - public void setLifeCycleListener(LifeCycleListener lifeCycleListener) { - mLifeCycleListener = lifeCycleListener; - } - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - - mWebSandboxFuture = WebSandbox.create(getApplicationContext()); - } - - public ListenableFuture<WebSandbox> getWebSandboxFuture() { - return mWebSandboxFuture; - } - - public void attachFragment(WebFragment fragment) { - FragmentManager fragmentManager = getSupportFragmentManager(); - fragmentManager.beginTransaction() - .setReorderingAllowed(true) - .add(R.id.fragment_container_view, fragment) - .commitNow(); - } - - public View getFragmentContainerView() { - return findViewById(R.id.fragment_container_view); - } - - public void detachFragment(WebFragment fragment) { - FragmentManager fragmentManager = getSupportFragmentManager(); - fragmentManager.beginTransaction().setReorderingAllowed(true).remove(fragment).commitNow(); - } - - public WebFragment getAttachedFragment() { - FragmentManager fragmentManager = getSupportFragmentManager(); - List<Fragment> fragments = fragmentManager.getFragments(); - - if (fragments.size() != 1) { - throw new IllegalStateException("Expected to have exactly 1 WebFragment."); - } - - return (WebFragment) fragments.get(0); - } - - @Override - protected void onNewIntent(Intent intent) { - if (mLifeCycleListener != null) { - mLifeCycleListener.onNewIntent(intent); - } - super.onNewIntent(intent); - } -}
diff --git a/weblayer/browser/android/javatests/skew/PRESUBMIT.py b/weblayer/browser/android/javatests/skew/PRESUBMIT.py deleted file mode 100644 index fd2af196..0000000 --- a/weblayer/browser/android/javatests/skew/PRESUBMIT.py +++ /dev/null
@@ -1,36 +0,0 @@ -# Copyright 2021 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import inspect -import os -import sys - -EXPECTATIONS_FILE = 'expectations.txt' - - -def _MaybeAddTypToPath(): - src_dir = os.path.join( - os.path.dirname(inspect.getfile(CheckChangeOnUpload)), - os.pardir, os.pardir, os.pardir, os.pardir, os.pardir) - typ_dir = os.path.join(src_dir, 'third_party', 'catapult', - 'third_party', 'typ') - if typ_dir not in sys.path: - sys.path.append(typ_dir) - - -def CheckChangeOnUpload(input_api, output_api): - - results = [] - if any(EXPECTATIONS_FILE in f.LocalPath() - for f in input_api.AffectedFiles() if f.Action() != 'D'): - _MaybeAddTypToPath() - from typ.expectations_parser import TestExpectations - test_expectations = TestExpectations() - with open(EXPECTATIONS_FILE, 'r') as exp: - ret, errors = test_expectations.parse_tagged_list(exp.read()) - - if ret: - results.append(output_api.PresubmitError( - 'Expectations file had the following errors: \n' + errors)) - return results
diff --git a/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py b/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py deleted file mode 100755 index 86c08df..0000000 --- a/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py +++ /dev/null
@@ -1,146 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Script to build a CIPD package for weblayer_instrumentation_test_apk from -# the current Chromium checkout. -# -# This should be run from the src directory of a release branch. This will -# take care of the build, you need not do that yourself. After the package is -# built run two cipd commands (printed at the end of script execution) to -# upload the package to the CIPD server and to update the ref for the -# corresponding milestone. Once the ref is updated, the version skew test will -# pick up the new package in successive runs. - -import argparse -import contextlib -import os -import shutil -import subprocess -import sys -import re -import tempfile -import zipfile - -SRC_DIR = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') - -# Run mb.py out of the current branch for simplicity. -MB_PATH = os.path.join('tools', 'mb', 'mb.py') - -# Get the config specifying the gn args from the location of this script. -MB_CONFIG_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), - 'mb_config.pyl') - -CHROMIUM_VERSION_REGEX = r'\d+\.\d+\.\d+\.\d+$' - -# CIPD package path. -# https://chrome-infra-packages.appspot.com/p/chromium/testing/weblayer-x86/+/ -CIPD_PKG_PATH='chromium/testing/weblayer-x86' - - -@contextlib.contextmanager -def temporarily_chdir_to_src(local_paths=None): - """Change directories to chromium/src when entering with block and - then change back to current directory after exiting with block. - - Args: - local_paths: List of paths to change into relative paths. - - Returns: - List of paths relative to chromium/src. - """ - curr_dir = os.getcwd() - paths_rel_to_src = [ - os.path.relpath(p, SRC_DIR) for p in local_paths or []] - try: - os.chdir(SRC_DIR) - yield paths_rel_to_src - finally: - os.chdir(curr_dir) - - -def zip_test_target(zip_filename): - """Create zip of all deps for weblayer_instrumentation_test_apk. - - Args: - zip_filename: destination zip filename. - """ - cmd = [MB_PATH, - 'zip', - '--master=dummy.master', - '--builder=dummy.builder', - '--config-file=%s' % MB_CONFIG_PATH, - os.path.join('out', 'Release'), - 'weblayer_instrumentation_test_apk', - zip_filename] - print(' '.join(cmd)) - subprocess.check_call(cmd) - - -def build_cipd_pkg(input_path, cipd_filename): - """Create a CIPD package file from the given input path. - - Args: - input_path: input directory from which to build the package. - cipd_filename: output filename for resulting cipd archive. - """ - cmd = ['cipd', - 'pkg-build', - '--in=%s' % input_path, - '--install-mode=copy', - '--name=%s' % CIPD_PKG_PATH, - '--out=%s' % cipd_filename] - print(' '.join(cmd)) - subprocess.check_call(cmd) - - -def get_chromium_version(): - with open(os.path.join(SRC_DIR, 'chrome', 'VERSION')) as f: - version = '.'.join(line[line.index('=') + 1:] - for line in f.read().splitlines()) - if not re.match(CHROMIUM_VERSION_REGEX, version): - raise ValueError("Chromium version, '%s', is not in proper format" % - version) - return version - - -def main(): - parser = argparse.ArgumentParser( - description='Package weblayer instrumentation tests for CIPD.') - parser.add_argument( - '--cipd_out', - required=True, - help="Output filename for resulting .cipd file.") - - args = parser.parse_args() - chromium_version = get_chromium_version() - with tempfile.TemporaryDirectory() as tmp_dir, \ - temporarily_chdir_to_src([args.cipd_out]) as cipd_out_src_rel_paths: - # Create zip archive of test target. - zip_filename = os.path.join(tmp_dir, 'file.zip') - zip_test_target(zip_filename) - - # Extract zip archive. - extracted = os.path.join(tmp_dir, 'extracted') - os.mkdir(extracted) - with zipfile.ZipFile(zip_filename) as zip_file: - zip_file.extractall(path=extracted) - - # Create CIPD archive. - tmp_cipd_filename = os.path.join(tmp_dir, 'file.cipd') - build_cipd_pkg(extracted, tmp_cipd_filename) - shutil.move(tmp_cipd_filename, cipd_out_src_rel_paths[0]) - - print(('Use "cipd pkg-register %s -verbose -tag \'version:%s\'" ' + - 'to upload package to the cipd server.') % - (args.cipd_out, chromium_version)) - print('Use "cipd set-ref chromium/testing/weblayer-x86 --version ' + - '<CIPD instance version> -ref m<milestone>" to update the ref.') - print('The CIPD instance version can be found on the "Instance" line ' + - 'after "chromium/testing/weblayer-x86:".') - - -if __name__ == '__main__': - sys.exit(main())
diff --git a/weblayer/browser/android/javatests/skew/expectations.txt b/weblayer/browser/android/javatests/skew/expectations.txt deleted file mode 100644 index 5c69edd9..0000000 --- a/weblayer/browser/android/javatests/skew/expectations.txt +++ /dev/null
@@ -1,120 +0,0 @@ -# Test expectations for skew tests between the WebLayer client and -# implementation at combinations of trunk and previous release milestones. -# -# Lines tagged with "impl_lte_$VERSION" will be active when testing trunk client -# with versions less than or equal to $VERSION of the implementation. -# -# These lines are not comments! They define the set of known tags and other information. -# tags: [ client_lte_91 client_lte_94 client_lte_95 impl_lte_95 client_lte_98 impl_lte_98 client_lte_103 ] -# 'all' disables the test from any skew test. -# tags: [ all ] -# results: [ Skip ] -# conflicts_allowed: True - -# Test is flaky, with the particular flake signaled in the bug below but the underlying cause likely -# being crbug.com/1277901. -crbug.com/1329813 [ all ] org.chromium.weblayer.test.ExternalNavigationTest#testNonHandledExternalIntentWithFallbackUrlThatLaunchesIntentAfterRedirectBlocksFallbackIntent [ Skip ] - -# No real changes to weblayer APIs, changes should only affect chrome-internal behavior around -# navigation which the test depends on. -crbug.com/1196803 [ client_lte_91 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoBlockedWhenBackgroundLaunchesAllowedAndUserForbids [ Skip ] - -crbug.com/1239002 [ all ] org.chromium.weblayer.test.FullscreenSizeTest#testOsk [ Skip ] - -# In 96 we changed the implementation to have navigations fail rather than -# complete in this case. Unfortunately there is no way to skip tests based on -# the impl being >= a given version. -crbug.com/1253395 [ all ] org.chromium.weblayer.test.NavigationTest#testGetPageInOnNavigationCompletedForIncompleteNavigation [ Skip ] - -# These tests were flaky, the fix was in the associated html files which landed -# in 94. -crbug.com/1222694 [ client_lte_94 ] org.chromium.weblayer.test.FullscreenCallbackTest* [ Skip ] -crbug.com/1191751 [ client_lte_94 ] org.chromium.weblayer.test.NewTabCallbackTest#testDestroyTabInOnNewTab [ Skip ] -crbug.com/1239032 [ client_lte_94 ] org.chromium.weblayer.test.NewTabCallbackTest#testNewTabHasFocus [ Skip ] -crbug.com/1239032 [ client_lte_94 ] org.chromium.weblayer.test.NewTabCallbackTest#testNewBrowser [ Skip ] -crbug.com/1239032 [ client_lte_94 ] org.chromium.weblayer.test.TabListCallbackTest#testCallbackInvokedWhenTabClosedViaWebContents [ Skip ] -crbug.com/1191751 [ client_lte_94 ] org.chromium.weblayer.test.TabListCallbackTest#testMoveToDifferentFragment [ Skip ] -crbug.com/1191751 [ client_lte_94 ] org.chromium.weblayer.test.TabListCallbackTest#testDestroyTab [ Skip ] -crbug.com/1191751 [ client_lte_94 ] org.chromium.weblayer.test.TabListCallbackTest#testActiveTabChanged [ Skip ] -crbug.com/1239034 [ client_lte_94 ] org.chromium.weblayer.test.TabCallbackTest#testTabModalOverlay [ Skip ] -crbug.com/1239026 [ client_lte_94 ] org.chromium.weblayer.test.TabCallbackTest#testDismissTransientUi [ Skip ] -crbug.com/1191751 [ client_lte_94 ] org.chromium.weblayer.test.NavigationTest#testRepostConfirmation [ Skip ] -crbug.com/1225662 [ client_lte_94 ] org.chromium.weblayer.test.NavigationTest#testDestroyTabWithModalDialog [ Skip ] -crbug.com/1239028 [ client_lte_94 ] org.chromium.weblayer.test.MediaSessionTest#basic [ Skip ] - -crbug.com/1248183 [ all ] org.chromium.weblayer.test.TabTest#testRotationDoesntChangeVisibility [ Skip ] -crbug.com/1248187 [ all ] org.chromium.weblayer.test.FindInPageTest#testHideOnNewTab [ Skip ] - -# Chrome changes broke some test infrastructure, so tests are only artificially -# broken - the behavior under test has not changed. -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentAfterRedirectInBackgroundTabLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentAfterRedirectLaunched [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentInNewTabLaunchedOnLinkClick [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentInSameTabLaunchedOnLinkClick [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentNavigationParamSetOnIntentLaunchViaLinkClick [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentNavigationParamSetOnNavigationsToIntents [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentViaOnLoadLaunched [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithFallbackUrlAfterRedirectLaunched [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBackgroundTabLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoBlockedWhenBackgroundLaunchesAllowedAndUserForbids [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoLaunchedWhenBackgroundLaunchesAllowedAndUserConsents [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoWithEmbedderPresentingWarningDialogBlockedWhenBackgroundLaunchesAllowedAndUserForbids [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoWithEmbedderPresentingWarningDialogLaunchedWhenBackgroundLaunchesAllowedAndUserConsents [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectLaunched [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testUserClicksLinkToPageWithExternalIntentLaunchedViaOnLoad [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testUserDecidingExternalIntentNavigationParamSetOnNavigationsToIntentsInIncognito [ Skip ] -crbug.com/1249962 [ client_lte_95 ] org.chromium.weblayer.test.NavigationTest#testIsKnownProtocol [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentAfterRedirectInBackgroundTabLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentAfterRedirectLaunched [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentInNewTabLaunchedOnLinkClick [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentInSameTabLaunchedOnLinkClick [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentNavigationParamSetOnIntentLaunchViaLinkClick [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentNavigationParamSetOnNavigationsToIntents [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentViaOnLoadLaunched [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithFallbackUrlAfterRedirectLaunched [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBackgroundTabLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoBlockedWhenBackgroundLaunchesAllowedAndUserForbids [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoLaunchedWhenBackgroundLaunchesAllowedAndUserConsents [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoWithEmbedderPresentingWarningDialogBlockedWhenBackgroundLaunchesAllowedAndUserForbids [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoWithEmbedderPresentingWarningDialogLaunchedWhenBackgroundLaunchesAllowedAndUserConsents [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectLaunched [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testUserClicksLinkToPageWithExternalIntentLaunchedViaOnLoad [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.ExternalNavigationTest#testUserDecidingExternalIntentNavigationParamSetOnNavigationsToIntentsInIncognito [ Skip ] -crbug.com/1249962 [ impl_lte_95 ] org.chromium.weblayer.test.NavigationTest#testIsKnownProtocol [ Skip ] - -# Bulk disable to get bot green. -crbug.com/1191751 [ all ] org.chromium.weblayer.test.InputTypesTest* [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.TabCallbackTest#testScrollNotificationDirectionChange [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.TabTest#testBeforeUnload [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.DownloadCallbackTest#testBasic [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.TabCallbackTest#testTabModalOverlayOnBackgroundTab [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.CookieManagerTest#testCookieChanged [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.NavigationTest#testIsFormSubmission [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.TabCallbackTest#testOnRenderProcessGone [ Skip ] -crbug.com/1191751 [ all ] org.chromium.weblayer.test.ScrollOffsetCallbackTest#testBasic [ Skip ] - -# In 98 we changed the implementation to have navigations succeed rather than -# fail in this case. Unfortunately there is no way to skip tests based on -# the impl being >= a given version. -crbug.com/1233480 [ all ] org.chromium.weblayer.test.NavigationTest#testInitialRendererInitiatedNavigationToAboutBlankFails [ Skip ] - -# In 99 we added logic to avoid the disambiguation dialog and a test for it. -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentAfterRedirectInBackgroundTabLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentAfterRedirectLaunched [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentInNewTabLaunchedOnLinkClick [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentInSameTabLaunchedOnLinkClick [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentNavigationParamSetOnIntentLaunchViaLinkClick [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentNavigationParamSetOnNavigationsToIntents [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentViaOnLoadLaunched [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithFallbackUrlAfterRedirectLaunched [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBackgroundTabLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupLaunchedWhenBackgroundLaunchesAllowed [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectLaunched [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testUserClicksLinkToPageWithExternalIntentLaunchedViaOnLoad [ Skip ] -crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testAvoidDisambiguationDialog [ Skip ] -crbug.com/1278017 [ impl_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testAvoidDisambiguationDialog [ Skip ] - -# In 104 we started to cap maximum cookie expiration date -crbug.com/1264458 [ client_lte_103 ] org.chromium.weblayer.test.CookieManagerTest#testGetResponseCookiesAllAttributes [ Skip ]
diff --git a/weblayer/browser/android/javatests/skew/mb_config.pyl b/weblayer/browser/android/javatests/skew/mb_config.pyl deleted file mode 100644 index d9da63f..0000000 --- a/weblayer/browser/android/javatests/skew/mb_config.pyl +++ /dev/null
@@ -1,109 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# This is a .pyl, or "Python Literal", file. You can treat it just like a -# .json file, with the following exceptions: -# * all keys must be quoted (use single quotes, please); -# * comments are allowed, using '#' syntax; and -# * trailing commas are allowed. - -# This is a trimmed version of tools/mb/mb_config.pyl with a dummy master and -# builder to be used with mb.py for creating a zip archive of the WebLayer -# instrumentation tests. -{ - 'builder_groups': { - 'dummy.group': { - 'dummy.builder.google_webview_pkg_name': 'android_weblayer_with_google_webview_pkg_name', - 'dummy.builder.aosp_webview_pkg_name': 'android_weblayer_with_aosp_webview_pkg_name', - } - }, - - 'configs': { - 'android_weblayer_with_aosp_webview_pkg_name': [ - 'android_release_bot_minimal_symbols_x86' - ], - - 'android_weblayer_with_google_webview_pkg_name': [ - 'android_release_bot_minimal_symbols_x86_webview_google' - ], - }, - - # This is a dict mapping a given 'mixin' name to a dict of settings that - # mb should use. See //tools/mb/docs/user_guide.md for more information. - 'mixins': { - # We build Android with codecs on most bots to ensure maximum test - # coverage, but use 'android_without_codecs' on bots responsible for - # building publicly advertised non-Official Android builds -- - # which are not allowed to have proprietary codecs enabled. - 'android': { - 'mixins': ['android_without_codecs', 'chrome_with_codecs'], - }, - - # Default webview package name is com.android.webview which - # is necessary for skew tests to work on Android M and Anroid 10 - # x86 builders. - 'android_release_bot_minimal_symbols_x86': { - 'mixins': ['android', 'release_bot', 'minimal_symbols', 'x86', - 'strip_debug_info', 'improved_debugging'], - }, - - 'android_release_bot_minimal_symbols_x86_webview_google': { - 'mixins': ['android_release_bot_minimal_symbols_x86', 'webview_google'], - }, - - 'android_without_codecs': { - 'gn_args': 'target_os="android"', - }, - - 'chrome_with_codecs': { - 'mixins': ['ffmpeg_branding_chrome', 'proprietary_codecs'], - }, - - 'ffmpeg_branding_chrome': { - 'gn_args': 'ffmpeg_branding="Chrome"', - }, - - 'goma': { - 'gn_args': 'use_goma=true', - }, - - 'minimal_symbols': { - 'gn_args': 'symbol_level=1', - }, - - # Note: This is probably not what you want to use. Instead use one of the - # chrome_with_codecs or chromeos_with_codecs mixins. - 'proprietary_codecs': { - 'gn_args': 'proprietary_codecs=true', - }, - - 'release': { - 'gn_args': 'is_debug=false', - }, - - 'release_bot': { - 'mixins': ['release', 'static', 'goma'], - }, - - 'static': { - 'gn_args': 'is_component_build=false', - }, - - 'strip_debug_info': { - 'gn_args': 'strip_debug_info=true', - }, - - 'webview_google': { - 'gn_args': 'system_webview_package_name="com.google.android.webview"', - }, - - 'x86': { - 'gn_args': 'target_cpu="x86"', - }, - - 'improved_debugging': { - 'gn_args': 'is_java_debug=true dcheck_always_on=true', - }, - }, -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/AllowedOriginsTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/AllowedOriginsTest.java deleted file mode 100644 index cfb2621..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/AllowedOriginsTest.java +++ /dev/null
@@ -1,151 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Navigation; -import org.chromium.webengine.Tab; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebEngineParams; -import org.chromium.webengine.WebSandbox; - -import java.util.ArrayList; - -/** - * Tests allowed origins. This can be provided as a WebEngine parameter. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class AllowedOriginsTest { - private static final int PORT = 3000; - - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - - WebSandbox mSandbox; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - // The origin needs to specify the port so instead of auto-assigning one, we need to choose - // an explicit port in our tests. - mTestServerRule.setServerPort(PORT); - mServer = mTestServerRule.getServer(); - mSandbox = mActivityTestRule.getWebSandbox(); - } - - @After - public void shutdown() throws Exception { - if (mSandbox != null) { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - } - mActivityTestRule.finish(); - } - - @Test - @SmallTest - public void testLoadsUrls_whenAllowlistNotProvided() throws Exception { - tryNavigateUrls(null); - } - - @Test - @SmallTest - public void testLoadsUrls_whenOriginsAllowlisted() throws Exception { - ArrayList<String> allowList = new ArrayList<>(); - allowList.add("http://localhost:" + PORT); - allowList.add("http://127.0.0.1:" + PORT); - - tryNavigateUrls(allowList); - } - - @Test() - @SmallTest - public void testDoNotLoadUrl_whenOriginNotAllowlisted() throws Exception { - ArrayList<String> allowList = new ArrayList<>(); - allowList.add("http://localhost:" + PORT); - // Not allowing 127.0.0.1 - - try { - tryNavigateUrls(allowList); - Assert.fail("Should have thrown exception"); - } catch (InstrumentationActivityTestRule.NavigationFailureException e) { - Navigation failedNavigation = e.getNavigation(); - // Status code is 0 when a navigation hasn't completed - Assert.assertEquals(failedNavigation.getStatusCode(), 0); - // We can verify this failed for 127.0.0.1 - Assert.assertEquals(failedNavigation.getUri().toString(), - getTestDataURL("127.0.0.1", "simple_page.html")); - } - } - - @Test(expected = InstrumentationActivityTestRule.NavigationFailureException.class) - @SmallTest() - public void testDoNotLoadUrl_whenPortNotAllowlisted() throws Exception { - ArrayList<String> allowList = new ArrayList<>(); - allowList.add("http://localhost:" + PORT); - // This will fail because this is using a port that wasn't allowlisted - allowList.add("http://127.0.0.1:" + (PORT + 1)); - - tryNavigateUrls(allowList); - } - - @Test(expected = InstrumentationActivityTestRule.NavigationFailureException.class) - @SmallTest() - public void testDoNotLoadUrl_whenSchemeNotAllowlisted() throws Exception { - ArrayList<String> allowList = new ArrayList<>(); - allowList.add("http://localhost:" + PORT); - // Our test server uses http so this will fail. - allowList.add("https://127.0.0.1:" + PORT); - - tryNavigateUrls(allowList); - } - - private void tryNavigateUrls(ArrayList<String> allowList) throws Exception { - WebEngine webEngine = createWebEngine(allowList); - - String url1 = getTestDataURL("localhost", "simple_page.html"); - String url2 = getTestDataURL("127.0.0.1", "simple_page.html"); - - Tab activeTab = webEngine.getTabManager().getActiveTab(); - mActivityTestRule.navigateAndWait(activeTab, url1); - mActivityTestRule.navigateAndWait(activeTab, url2); - } - - private WebEngine createWebEngine(ArrayList<String> allowList) throws Exception { - WebEngineParams.Builder builder = - (new WebEngineParams.Builder()).setProfileName("DefaultProfile"); - - if (allowList != null) { - builder.setAllowedOrigins(allowList); - } - - WebEngineParams params = builder.build(); - - return runOnUiThreadBlocking(() -> mSandbox.createWebEngine(params)).get(); - } - - private String getTestDataURL(String host, String path) { - return mServer.getURLWithHostName(host, "/weblayer/test/data/" + path); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/CookieManagerTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/CookieManagerTest.java deleted file mode 100644 index 886bb17..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/CookieManagerTest.java +++ /dev/null
@@ -1,134 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.core.content.ContextCompat; -import androidx.test.filters.SmallTest; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.util.TestWebServer; -import org.chromium.webengine.CookieManager; -import org.chromium.webengine.RestrictedAPIException; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabManager; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.concurrent.CountDownLatch; - -/** - * Tests the CookieManager API. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class CookieManagerTest { - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - @Rule - public DigitalAssetLinksServerRule mDALServerRule = new DigitalAssetLinksServerRule(); - - private TestWebServer mServer; - private CookieManager mCookieManager; - private TabManager mTabManager; - - private WebSandbox mSandbox; - - @Before - public void setUp() throws Exception { - mServer = mDALServerRule.getServer(); - mActivityTestRule.launchShell(); - - mSandbox = mActivityTestRule.getWebSandbox(); - WebEngine webEngine = runOnUiThreadBlocking(() -> mSandbox.createWebEngine()).get(); - runOnUiThreadBlocking(() -> mActivityTestRule.attachFragment(webEngine.getFragment())); - mCookieManager = webEngine.getCookieManager(); - mTabManager = webEngine.getTabManager(); - } - - @After - public void tearDown() { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - mActivityTestRule.finish(); - } - - @Test - @SmallTest - public void accessFailsWithoutVerification() throws Exception { - ListenableFuture<String> future = - runOnUiThreadBlocking(() -> mCookieManager.getCookie(mServer.getBaseUrl())); - - CountDownLatch executeLatch = new CountDownLatch(1); - Futures.addCallback(future, new FutureCallback<String>() { - @Override - public void onSuccess(String result) { - Assert.fail("future resolved unexpectedly."); - } - - @Override - public void onFailure(Throwable thrown) { - if (!(thrown instanceof RestrictedAPIException)) { - Assert.fail( - "expected future to fail due to RestrictedAPIException, instead got: " - + thrown.getClass().getName()); - } - executeLatch.countDown(); - } - }, ContextCompat.getMainExecutor(mActivityTestRule.getContext())); - - executeLatch.await(); - } - - @Test - @SmallTest - public void setAndGetCookies() throws Exception { - mDALServerRule.setUpDigitalAssetLinks(); - String cookie = - runOnUiThreadBlocking(() -> mCookieManager.getCookie(mServer.getBaseUrl())).get(); - Assert.assertEquals(cookie, ""); - runOnUiThreadBlocking(() -> mCookieManager.setCookie(mServer.getBaseUrl(), "foo=bar")); - String setCookie = - runOnUiThreadBlocking(() -> mCookieManager.getCookie(mServer.getBaseUrl())).get(); - Assert.assertEquals(setCookie, "foo=bar"); - } - - @Test - @SmallTest - public void getCookieCreatedByPage() throws Exception { - mDALServerRule.setUpDigitalAssetLinks(); - - String url = mDALServerRule.getServer().setResponse("/page.html", - "<html><script>document.cookie='foo=bar42'</script><body>contents!</body></html>", - null); - - String cookie = - runOnUiThreadBlocking(() -> mCookieManager.getCookie(mServer.getBaseUrl())).get(); - Assert.assertEquals(cookie, ""); - Tab tab = mTabManager.getActiveTab(); - - mActivityTestRule.navigateAndWait(tab, url); - - // Run JS to make sure the script had time to run before we actually check via the cookie - // manager. - Assert.assertEquals("\"foo=bar42\"", - runOnUiThreadBlocking(() -> tab.executeScript("document.cookie", false)).get()); - - String updatedCookie = runOnUiThreadBlocking(() -> mCookieManager.getCookie(url)).get(); - Assert.assertEquals(updatedCookie, "foo=bar42"); - } -} \ No newline at end of file
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/DigitalAssetLinksServerRule.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/DigitalAssetLinksServerRule.java deleted file mode 100644 index 430e8fd..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/DigitalAssetLinksServerRule.java +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Assert; -import org.junit.rules.TestWatcher; -import org.junit.runner.Description; - -import org.chromium.base.ContextUtils; -import org.chromium.base.PackageUtils; -import org.chromium.net.test.util.TestWebServer; - -import java.util.List; - -/** - * Gives an option to make DAL verification pass for the tests. - * Also exposes the TestWebServer instance for more customization. - */ -public class DigitalAssetLinksServerRule extends TestWatcher { - private static final String ASSETLINKS_PATH = "/.well-known/assetlinks.json"; - - private TestWebServer mServer; - - @Override - protected void starting(Description desc) { - super.starting(desc); - - // Try to start a server on any of the ports in the 8900s range. - // The 1P port ranges are defined in - // //weblayer/shell/android/webengine_shell_apk/res_template/values/strings.xml. - for (int port = 8900; port < 9000; port++) { - try { - mServer = TestWebServer.start(port); - } catch (Exception e) { - } - } - if (mServer == null) { - Assert.fail("Failed to start a TestWebServer."); - } - // By default, the asset links are not set up. - mServer.setResponseWithNotFoundStatus(ASSETLINKS_PATH, null); - } - - @Override - protected void finished(Description desc) { - super.finished(desc); - mServer.shutdown(); - } - - // Returns the TestServer in case you want to add additional handlers. - public TestWebServer getServer() { - return mServer; - } - - // Makes the DAL verification succeed. - public void setUpDigitalAssetLinks() { - String packageName = ContextUtils.getApplicationContext().getPackageName(); - List<String> signatureFingerprints = - PackageUtils.getCertificateSHA256FingerprintForPackage(packageName); - mServer.setResponse( - ASSETLINKS_PATH, makeAssetFile(packageName, signatureFingerprints.get(0)), null); - } - - private static String makeAssetFile(String packageName, String fingerprint) { - try { - return (new JSONArray().put( - new JSONObject() - .put("relation", - new JSONArray().put( - "delegate_permission/common.handle_all_urls")) - .put("target", - new JSONObject() - .put("namespace", "android_app") - .put("package_name", packageName) - .put("sha256_cert_fingerprints", - new JSONArray().put(fingerprint))))) - .toString(); - } catch (JSONException e) { - } - return ""; - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ExecuteScriptTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ExecuteScriptTest.java deleted file mode 100644 index 7c3be67a..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ExecuteScriptTest.java +++ /dev/null
@@ -1,173 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import android.util.Pair; - -import androidx.core.content.ContextCompat; -import androidx.test.filters.SmallTest; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.util.TestWebServer; -import org.chromium.webengine.RestrictedAPIException; -import org.chromium.webengine.Tab; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; - -/** - * Tests executing JavaScript in a Tab. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class ExecuteScriptTest { - private static final String sRequestPath = "/page.html"; - private static final String sResponseString = - "<html><head></head><body>contents!</body><script>window.foo = 42;</script></html>"; - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - @Rule - public DigitalAssetLinksServerRule mDALServerRule = new DigitalAssetLinksServerRule(); - - private Tab mTab; - private String mDefaultUrl; - private TestWebServer mServer; - - @Before - public void setUp() throws Exception { - mServer = mDALServerRule.getServer(); - mActivityTestRule.launchShell(); - - List<Pair<String, String>> embedderAncestorHeader = new ArrayList(); - embedderAncestorHeader.add(new Pair("X-embedder-ancestors", "none")); - mDefaultUrl = mServer.setResponse(sRequestPath, sResponseString, embedderAncestorHeader); - } - - @After - public void tearDown() { - mActivityTestRule.finish(); - } - - private Tab navigate() throws Exception { - mActivityTestRule.createWebEngineAttachThenNavigateAndWait(mDefaultUrl); - return mActivityTestRule.getFragment().getWebEngine().getTabManager().getActiveTab(); - } - - @Test - @SmallTest - public void executeScriptFailsWithoutVerification() throws Exception { - Tab activeTab = navigate(); - - CountDownLatch executeLatch = new CountDownLatch(1); - - ListenableFuture<String> future = - runOnUiThreadBlocking(() -> activeTab.executeScript("1+1", true)); - - Futures.addCallback(future, new FutureCallback<String>() { - @Override - public void onSuccess(String result) { - Assert.fail("future resolved unexpectedly."); - } - - @Override - public void onFailure(Throwable thrown) { - if (!(thrown instanceof RestrictedAPIException)) { - Assert.fail( - "expected future to fail due to RestrictedAPIException, instead got: " - + thrown.getClass().getName()); - } - executeLatch.countDown(); - } - }, ContextCompat.getMainExecutor(mActivityTestRule.getContext())); - - executeLatch.await(); - } - - @Test - @SmallTest - public void executeScriptSucceedsWithDALVerification() throws Exception { - mDALServerRule.setUpDigitalAssetLinks(); - Tab activeTab = navigate(); - - ListenableFuture<String> future = - runOnUiThreadBlocking(() -> activeTab.executeScript("1+1", true)); - Assert.assertEquals(future.get(), "2"); - } - - @Test - @SmallTest - public void executeScriptSucceedsWithHeaderVerification() throws Exception { - List<Pair<String, String>> embedderAncestorHeader = new ArrayList(); - embedderAncestorHeader.add( - new Pair("X-embedder-ancestors", mActivityTestRule.getPackageName())); - mDefaultUrl = mServer.setResponse(sRequestPath, sResponseString, embedderAncestorHeader); - Tab activeTab = navigate(); - - ListenableFuture<String> future = - runOnUiThreadBlocking(() -> activeTab.executeScript("1+1", true)); - Assert.assertEquals(future.get(), "2"); - } - - @Test - @SmallTest - public void executeScriptSucceedsWithoutHeader() throws Exception { - mDefaultUrl = mServer.setResponse(sRequestPath, sResponseString, null); - Tab activeTab = navigate(); - - ListenableFuture<String> future = - runOnUiThreadBlocking(() -> activeTab.executeScript("1+1", true)); - Assert.assertEquals(future.get(), "2"); - } - - @Test - @SmallTest - public void useSeparateIsolate() throws Exception { - mDALServerRule.setUpDigitalAssetLinks(); - Tab activeTab = navigate(); - - ListenableFuture<String> futureIsolated = - runOnUiThreadBlocking(() -> activeTab.executeScript("window.foo", true)); - Assert.assertEquals(futureIsolated.get(), "null"); - - ListenableFuture<String> futureUnisolated = - runOnUiThreadBlocking(() -> activeTab.executeScript("window.foo", false)); - Assert.assertEquals(futureUnisolated.get(), "42"); - } - - @Test - @SmallTest - public void modifyDOMSucceeds() throws Exception { - mDALServerRule.setUpDigitalAssetLinks(); - Tab activeTab = navigate(); - - ListenableFuture<String> future1 = runOnUiThreadBlocking( - () -> activeTab.executeScript("document.body.innerText", false)); - Assert.assertEquals(future1.get(), "\"contents!\""); - - runOnUiThreadBlocking( - () -> activeTab.executeScript("document.body.innerText = 'foo'", false)) - .get(); - - ListenableFuture<String> future2 = runOnUiThreadBlocking( - () -> activeTab.executeScript("document.body.innerText", false)); - Assert.assertEquals(future2.get(), "\"foo\""); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ExternalIntentsTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ExternalIntentsTest.java deleted file mode 100644 index e1eeeef..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ExternalIntentsTest.java +++ /dev/null
@@ -1,158 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import android.app.Instrumentation; -import android.content.Intent; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.LargeTest; - -import com.google.common.util.concurrent.SettableFuture; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.content_public.browser.test.util.ClickUtils; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Tab; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebEngineParams; -import org.chromium.webengine.WebSandbox; -import org.chromium.webengine.test.instrumentation_test_apk.InstrumentationActivity; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Tests for launching external intents from deep links. - */ -@DoNotBatch(reason = "Tests are testing behaviour between activities that are single task") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class ExternalIntentsTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - // We need plenty time to load up a page, launch a new activity, and return. - // We need to be confident that those events also did not happen in the disabled - // case if this times out. - // The is quite a slow set of tests because we need this to be a large value to avoid flaking. - private static final int TEST_TIMEOUT_MS = 20_000; - - private EmbeddedTestServer mServer; - private WebSandbox mSandbox; - private Instrumentation mInstrumentation; - private String mUrl; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - - mServer = mTestServerRule.getServer(); - mUrl = getTestDataURL("external_intents.html#" - + mActivityTestRule.getShellComponentName().flattenToString()); - - mSandbox = mActivityTestRule.getWebSandbox(); - } - - @After - public void shutdown() { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - mActivityTestRule.finish(); - } - - @Test - @LargeTest - @DisabledTest(message = "Flaky because this relies on waiting for an activity to launch") - public void testOpensExternalIntents_shouldLaunch() throws Exception { - // Awful hack heads up: - // The problem is that the application is a separate application from the - // activity running the tests so we can't use an ActivityMonitor. - // Chromium thinks that if you are opening a deeplink to the same package, - // it should act as a "tab" navigation and not send an external intent. - // We can't override apis like startActivity for the instrumentation activity - // because the component is starting the activity from the web engine context. - final SettableFuture<Boolean> launchedExternal = SettableFuture.create(); - mActivityTestRule.getActivity().setLifeCycleListener( - new InstrumentationActivity.LifeCycleListener() { - @Override - public void onNewIntent(Intent intent) { - launchedExternal.set(intent.hasExtra("LAUNCHED_EXTERNAL")); - } - }); - Tab currentTab = createWebEngineAndLoadPage(/* isExternalIntentsEnabled= */ true); - - ClickUtils.mouseSingleClickView(InstrumentationRegistry.getInstrumentation(), - mActivityTestRule.getFragmentContainerView(), 1, 1); - - try { - Assert.assertTrue(launchedExternal.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (TimeoutException e) { - Assert.fail("Shouldn't have timed out"); - } - } - - @Test - @LargeTest - public void testDisableExternalIntents_shouldNotLaunch() throws Exception { - final SettableFuture<Boolean> launchedExternal = SettableFuture.create(); - mActivityTestRule.getActivity().setLifeCycleListener( - new InstrumentationActivity.LifeCycleListener() { - @Override - public void onNewIntent(Intent intent) { - launchedExternal.set(intent.hasExtra("LAUNCHED_EXTERNAL")); - } - }); - Tab currentTab = createWebEngineAndLoadPage(/* isExternalIntentsEnabled= */ false); - - ClickUtils.mouseSingleClickView(InstrumentationRegistry.getInstrumentation(), - mActivityTestRule.getFragmentContainerView(), 1, 1); - - try { - Assert.assertFalse(launchedExternal.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)); - // If we get here it means the test resumed from the other activity - Assert.fail("The activity shouldn't have been resumed"); - } catch (TimeoutException e) { - // Yay it was meant to timeout - } - } - - /** - * Creates a new web engine and loads the test page. - * - * Will configure if we can launch external intents or not. - */ - private Tab createWebEngineAndLoadPage(boolean isExternalIntentsEnabled) throws Exception { - WebEngineParams params = new WebEngineParams.Builder() - .setProfileName("Default") - .setIsExternalIntentsEnabled(isExternalIntentsEnabled) - .build(); - - WebEngine webEngine = runOnUiThreadBlocking(() -> mSandbox.createWebEngine(params)).get(); - runOnUiThreadBlocking(() -> mActivityTestRule.attachFragment(webEngine.getFragment())); - - Tab activeTab = webEngine.getTabManager().getActiveTab(); - mActivityTestRule.navigateAndWait(activeTab, mUrl); - - return activeTab; - } - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/FaviconTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/FaviconTest.java deleted file mode 100644 index dd65becd9..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/FaviconTest.java +++ /dev/null
@@ -1,163 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import android.graphics.Bitmap; -import android.graphics.Color; - -import androidx.test.filters.MediumTest; -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabObserver; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Tests that a tab's favicon is returned. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class FaviconTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - private Tab mTab; - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - mServer = mTestServerRule.getServer(); - WebSandbox sandbox = mActivityTestRule.getWebSandbox(); - WebEngine webEngine = runOnUiThreadBlocking(() -> sandbox.createWebEngine()).get(); - - mTab = webEngine.getTabManager().getActiveTab(); - } - - @After - public void tearDown() { - mActivityTestRule.finish(); - } - - private static final class ResultHolder { - public Bitmap mResult; - } - - private Bitmap waitForFaviconChange() throws Exception { - final ResultHolder holder = new ResultHolder(); - CountDownLatch faviconLatch = new CountDownLatch(1); - TabObserver observer = new TabObserver() { - @Override - public void onFaviconChanged(Tab tab, Bitmap favicon) { - holder.mResult = favicon; - faviconLatch.countDown(); - } - }; - runOnUiThreadBlocking(() -> mTab.registerTabObserver(observer)); - - faviconLatch.await(10, TimeUnit.SECONDS); - - runOnUiThreadBlocking(() -> mTab.unregisterTabObserver(observer)); - return holder.mResult; - } - - private void verifyFavicon(Bitmap favicon) { - Assert.assertNotNull(favicon); - Assert.assertEquals(favicon.getHeight(), 16); - Assert.assertEquals(favicon.getWidth(), 16); - Assert.assertEquals(favicon.getPixel(0, 0), Color.rgb(0, 72, 255)); - } - - @Test - @SmallTest - public void checkFaviconIsExposed() throws Exception { - runOnUiThreadBlocking(() - -> mTab.getNavigationController().navigate( - getTestDataURL("simple_page_with_favicon.html"))); - Bitmap favicon = waitForFaviconChange(); - verifyFavicon(favicon); - } - - @Test - @SmallTest - public void checkDelayedFaviconsAreDelivered() throws Exception { - runOnUiThreadBlocking(() - -> mTab.getNavigationController().navigate(getTestDataURL( - "simple_page_with_delayed_favicon.html"))); - - Bitmap favicon = waitForFaviconChange(); - Assert.assertNull(favicon); - - // The page dynamically creates a favicon after receiving a post message. - runOnUiThreadBlocking(() -> mTab.postMessage("message", "*")); - favicon = waitForFaviconChange(); - verifyFavicon(favicon); - } - - @Test - @MediumTest - public void checkFaviconsCanBeDeleted() throws Exception { - runOnUiThreadBlocking(() - -> mTab.getNavigationController().navigate(getTestDataURL( - "simple_page_with_deleted_favicon.html"))); - - Bitmap favicon = waitForFaviconChange(); - verifyFavicon(favicon); - - // Favicon eventually gets deleted. - favicon = waitForFaviconChange(); - Assert.assertNull(favicon); - } - - @Test - @SmallTest - public void pageWithNoFaviconDeliversEvent() throws Exception { - runOnUiThreadBlocking( - () -> mTab.getNavigationController().navigate(getTestDataURL("simple_page.html"))); - - Bitmap favicon = waitForFaviconChange(); - Assert.assertNull(favicon); - } - - @Test - @SmallTest - public void multipleNavigationsDelieverEvents() throws Exception { - runOnUiThreadBlocking(() - -> mTab.getNavigationController().navigate( - getTestDataURL("simple_page_with_favicon.html"))); - - Bitmap favicon = waitForFaviconChange(); - verifyFavicon(favicon); - - runOnUiThreadBlocking( - () -> mTab.getNavigationController().navigate(getTestDataURL("simple_page.html"))); - favicon = waitForFaviconChange(); - Assert.assertNull(favicon); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/InstrumentationActivityTestRule.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/InstrumentationActivityTestRule.java deleted file mode 100644 index f4158c0..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/InstrumentationActivityTestRule.java +++ /dev/null
@@ -1,181 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.view.View; - -import androidx.annotation.Nullable; -import androidx.test.InstrumentationRegistry; - -import org.junit.Assert; - -import org.chromium.webengine.Navigation; -import org.chromium.webengine.NavigationObserver; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabListObserver; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebFragment; -import org.chromium.webengine.WebSandbox; -import org.chromium.webengine.test.instrumentation_test_apk.InstrumentationActivity; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; - -/** - * ActivityTestRule for InstrumentationActivity. - * - * Test can use this ActivityTestRule to launch or get InstrumentationActivity. - */ -public class InstrumentationActivityTestRule - extends WebEngineActivityTestRule<InstrumentationActivity> { - @Nullable - private WebFragment mFragment; - - public InstrumentationActivityTestRule() { - super(InstrumentationActivity.class); - } - - /** - * Starts the WebEngine Instrumentation activity. - */ - public void launchShell() { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setComponent(getShellComponentName()); - launchActivity(intent); - } - - public ComponentName getShellComponentName() { - return new ComponentName(InstrumentationRegistry.getInstrumentation().getTargetContext(), - InstrumentationActivity.class); - } - - public void finish() { - Assert.assertNotNull(getActivity()); - getActivity().finish(); - } - - public WebSandbox getWebSandbox() throws Exception { - return getActivity().getWebSandboxFuture().get(); - } - - /** - * Attaches a fragment to the container in the activity. If a fragment is already present, it - * will detach it first. - */ - public void attachFragment(WebFragment fragment) { - if (mFragment != null) { - detachFragment(mFragment); - } - - getActivity().attachFragment(fragment); - mFragment = fragment; - } - - /** - * Return the current fragment attached to the fragment container in the activity. - */ - public WebFragment getFragment() { - Assert.assertNotNull(mFragment); - return mFragment; - } - - public void detachFragment(WebFragment fragment) { - getActivity().detachFragment(fragment); - } - - public Tab getActiveTab() throws Exception { - return getFragment().getWebEngine().getTabManager().getActiveTab(); - } - - public View getFragmentContainerView() { - return getActivity().getFragmentContainerView(); - } - - /** - * Creates a new WebEngine and attaches its Fragment before navigating. - */ - public WebEngine createWebEngineAttachThenNavigateAndWait(String path) throws Exception { - WebSandbox sandbox = getWebSandbox(); - WebEngine webEngine = runOnUiThreadBlocking(() -> sandbox.createWebEngine()).get(); - - runOnUiThreadBlocking(() -> attachFragment(webEngine.getFragment())); - - Tab activeTab = webEngine.getTabManager().getActiveTab(); - - navigateAndWait(activeTab, path); - return webEngine; - } - - /** - * Navigates Tab to new path and waits for navigation to complete. - */ - public void navigateAndWait(Tab tab, String url) throws Exception { - CountDownLatch navigationCompleteLatch = new CountDownLatch(1); - AtomicReference<Navigation> navigationFailure = new AtomicReference(); - runOnUiThreadBlocking(() -> { - tab.getNavigationController().registerNavigationObserver(new NavigationObserver() { - @Override - public void onNavigationCompleted(Tab tab, Navigation navigation) { - navigationCompleteLatch.countDown(); - } - @Override - public void onNavigationFailed(Tab tab, Navigation navigation) { - navigationFailure.set(navigation); - navigationCompleteLatch.countDown(); - } - }); - tab.getNavigationController().navigate(url); - }); - navigationCompleteLatch.await(); - - if (navigationFailure.get() != null) { - throw new NavigationFailureException(navigationFailure.get()); - } - } - - public void setTabActiveAndWait(WebEngine webEngine, Tab tab) throws Exception { - CountDownLatch setActiveLatch = new CountDownLatch(1); - runOnUiThreadBlocking(() -> { - webEngine.getTabManager().registerTabListObserver(new TabListObserver() { - @Override - public void onActiveTabChanged(WebEngine webEngine, Tab activeTab) { - setActiveLatch.countDown(); - } - }); - tab.setActive(); - }); - setActiveLatch.await(); - } - - public Context getContext() { - return getActivity(); - } - - public String getPackageName() { - return getActivity().getPackageName(); - } - - /** - * Thrown by navigateAndWait if the navigation failed. - */ - public class NavigationFailureException extends RuntimeException { - private final Navigation mNavigation; - NavigationFailureException(Navigation navigation) { - super("Navigation failed."); - mNavigation = navigation; - } - - public Navigation getNavigation() { - return mNavigation; - } - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/PostMessageTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/PostMessageTest.java deleted file mode 100644 index 0d76721..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/PostMessageTest.java +++ /dev/null
@@ -1,230 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.test.filters.MediumTest; -import androidx.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.MessageEventListener; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabObserver; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Tests the postMessage functionality. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class PostMessageTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - private Tab mTab; - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - mServer = mTestServerRule.getServer(); - - WebSandbox sandbox = mActivityTestRule.getWebSandbox(); - WebEngine webEngine = runOnUiThreadBlocking(() -> sandbox.createWebEngine()).get(); - - mTab = webEngine.getTabManager().getActiveTab(); - - // First title is the domain, second title is the one in the html title tag. - CountDownLatch titleUpdateLatch = new CountDownLatch(2); - TabObserver observer = new TabObserver() { - @Override - public void onTitleUpdated(Tab tab, String title) { - titleUpdateLatch.countDown(); - } - }; - runOnUiThreadBlocking(() -> mTab.registerTabObserver(observer)); - - mActivityTestRule.navigateAndWait(mTab, getTestDataURL("postmessage.html")); - titleUpdateLatch.await(10, TimeUnit.SECONDS); - - runOnUiThreadBlocking(() -> mTab.unregisterTabObserver(observer)); - } - - private static final class ResultHolder { - public String mResult; - } - - private String waitForTitleChange() throws Exception { - final ResultHolder holder = new ResultHolder(); - CountDownLatch postMessageLatch = new CountDownLatch(1); - TabObserver observer = new TabObserver() { - @Override - public void onTitleUpdated(Tab tab, String title) { - holder.mResult = title; - postMessageLatch.countDown(); - } - }; - runOnUiThreadBlocking(() -> mTab.registerTabObserver(observer)); - - postMessageLatch.await(10, TimeUnit.SECONDS); - - runOnUiThreadBlocking(() -> mTab.unregisterTabObserver(observer)); - - if (holder.mResult == null) { - throw new RuntimeException("Title was not updated"); - } - return holder.mResult; - } - - private String waitForPostMessage() throws Exception { - return waitForPostMessage(Arrays.asList("*")); - } - - private String waitForPostMessage(List<String> allowedOrigins) throws Exception { - final ResultHolder holder = new ResultHolder(); - CountDownLatch postMessageLatch = new CountDownLatch(1); - MessageEventListener listener = new MessageEventListener() { - @Override - public void onMessage(Tab source, String message) { - Assert.assertEquals(source, mTab); - holder.mResult = message; - postMessageLatch.countDown(); - } - }; - - runOnUiThreadBlocking(() -> mTab.addMessageEventListener(listener, allowedOrigins)); - - postMessageLatch.await(10, TimeUnit.SECONDS); - runOnUiThreadBlocking(() -> mTab.removeMessageEventListener(listener)); - - if (holder.mResult == null) { - throw new RuntimeException("postMessage was not received"); - } - return holder.mResult; - } - - @Test - @SmallTest - public void pageReceivesPostMessage() throws Exception { - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - Assert.assertEquals("postMessage: 1", waitForTitleChange()); - } - - @Test - @SmallTest - public void pageCanPostMessageBack() throws Exception { - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - Assert.assertEquals("message: hello, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - } - - @Test - @MediumTest - @DisabledTest(message = "https://crbug.com/1457935") - public void postMessageTargetOriginIsRespected() throws Exception { - runOnUiThreadBlocking(() -> mTab.postMessage("hello", mTestServerRule.getOrigin())); - Assert.assertEquals("postMessage: 1", waitForTitleChange()); - - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "https://example.com/")); - try { - waitForPostMessage(); - Assert.fail("postMessage was delivered to the wrong origin"); - } catch (Exception e) { - } - } - - @Test - @SmallTest - public void canPostToPageMultipleTimes() throws Exception { - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - Assert.assertEquals("message: hello, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - Assert.assertEquals("message: hello, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - Assert.assertEquals("postMessage: 3", waitForTitleChange()); - } - - @Test - @MediumTest - public void onlyTargetedTabReceivesPostMessage() throws Exception { - WebSandbox sandbox = mActivityTestRule.getWebSandbox(); - WebEngine webEngine = runOnUiThreadBlocking(() -> sandbox.createWebEngine()).get(); - - Tab tab2 = runOnUiThreadBlocking(() -> webEngine.getTabManager().createTab()).get(); - mActivityTestRule.navigateAndWait(tab2, getTestDataURL("postmessage.html")); - - runOnUiThreadBlocking(() -> tab2.postMessage("hello", "*")); - try { - waitForPostMessage(); - Assert.fail("postMessage was delivered to the wrong origin"); - } catch (Exception e) { - } - } - - @Test - @MediumTest - public void postMessageFromTabRespectsAllowedOrigin() throws Exception { - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - Assert.assertEquals("message: hello, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - try { - waitForPostMessage(Arrays.asList("https://different.example.com")); - Assert.fail("postMessage was received from the wrong origin"); - } catch (Exception e) { - } - } - - @Test - @MediumTest - public void receivePostMessageFromSavedPort() throws Exception { - runOnUiThreadBlocking(() -> mTab.postMessage("hello - delayed", "*")); - Assert.assertEquals("message: hello - delayed, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - Assert.assertEquals("message: hello - delayed2, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - Assert.assertEquals("message: hello - delayed3, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - - runOnUiThreadBlocking(() -> mTab.postMessage("hello", "*")); - Assert.assertEquals("message: hello, " - + "source: app://org.chromium.webengine.test.instrumentation_test_apk", - waitForPostMessage()); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ProfileManagerTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ProfileManagerTest.java deleted file mode 100644 index 1263ce026..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/ProfileManagerTest.java +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.webengine.ProfileManager; -import org.chromium.webengine.WebEngineParams; -import org.chromium.webengine.WebSandbox; - -import java.util.List; - -/** - * Tests functions called on the ProfileManager object. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class ProfileManagerTest { - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - WebSandbox mSandbox; - ProfileManager mProfileManager; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - - mSandbox = mActivityTestRule.getWebSandbox(); - mProfileManager = mSandbox.getProfileManager(); - } - - @After - public void shutdown() throws Exception { - if (mSandbox != null) { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - } - mActivityTestRule.finish(); - } - - @Test - @SmallTest - public void profileManagerIsAvailable() { - Assert.assertNotNull(mProfileManager); - } - - @Test - @SmallTest - public void getAllProfileNamesReturnsNames() throws Exception { - String name1 = "TestProfile1"; - WebEngineParams params1 = new WebEngineParams.Builder().setProfileName(name1).build(); - runOnUiThreadBlocking(() -> mSandbox.createWebEngine(params1)); - - List<String> initialNames = - runOnUiThreadBlocking(() -> mProfileManager.getAllProfileNames()).get(); - Assert.assertEquals(1, initialNames.size()); - Assert.assertTrue(initialNames.contains(name1)); - - String profileName2 = "TestProfile2"; - WebEngineParams params2 = - new WebEngineParams.Builder().setProfileName(profileName2).build(); - runOnUiThreadBlocking(() -> mSandbox.createWebEngine(params2)); - - List<String> newNames = - runOnUiThreadBlocking(() -> mProfileManager.getAllProfileNames()).get(); - Assert.assertEquals(2, newNames.size()); - Assert.assertTrue(newNames.contains(profileName2)); - } - - @Test - @SmallTest - public void createProfileWithIdenticalName() throws Exception { - String profileName = "TestProfile"; - WebEngineParams params = new WebEngineParams.Builder().setProfileName(profileName).build(); - runOnUiThreadBlocking(() -> mSandbox.createWebEngine(params, "tag-1")); - runOnUiThreadBlocking(() -> mSandbox.createWebEngine(params, "tag-2")); - - List<String> names = - runOnUiThreadBlocking(() -> mProfileManager.getAllProfileNames()).get(); - - Assert.assertEquals(1, names.size()); - Assert.assertTrue(names.contains(profileName)); - } - - @Test - @SmallTest - public void noProfilesOnWebSandboxStartup() throws Exception { - List<String> names = - runOnUiThreadBlocking(() -> mProfileManager.getAllProfileNames()).get(); - - Assert.assertEquals(0, names.size()); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/StatePersistenceTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/StatePersistenceTest.java deleted file mode 100644 index e9bdad2..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/StatePersistenceTest.java +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import android.net.Uri; - -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.ContextUtils; -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Tab; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebEngineParams; -import org.chromium.webengine.WebSandbox; - -import java.util.Set; - -/** - * Tests the persistence state of WebEngine. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class StatePersistenceTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - - WebSandbox mSandbox; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - mServer = mTestServerRule.getServer(); - - mSandbox = mActivityTestRule.getWebSandbox(); - } - - @After - public void shutdown() throws Exception { - if (mSandbox != null) { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - } - mActivityTestRule.finish(); - } - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } - - @Test - @SmallTest - public void tabsPersistAcrossSessions() throws Exception { - WebEngineParams params = (new WebEngineParams.Builder()) - .setPersistenceId("pid1234") - .setProfileName("pn12345") - .build(); - WebEngine webEngine = runOnUiThreadBlocking( - () -> mActivityTestRule.getWebSandbox().createWebEngine(params)) - .get(); - Tab activeTab = webEngine.getTabManager().getActiveTab(); - String url = getTestDataURL("simple_page.html"); - mActivityTestRule.navigateAndWait(activeTab, url); - // Shutdown the sandbox. - runOnUiThreadBlocking(() -> { - try { - mActivityTestRule.getWebSandbox().shutdown(); - } catch (Exception e) { - Assert.fail("Failed to shutdown sandbox"); - } - }); - - WebSandbox sandbox = - runOnUiThreadBlocking(() -> WebSandbox.create(ContextUtils.getApplicationContext())) - .get(); - // Recreate a WebEngine with the same params. - WebEngine webEngine2 = runOnUiThreadBlocking(() -> sandbox.createWebEngine(params)).get(); - Tab newActiveTab = webEngine2.getTabManager().getActiveTab(); - - Assert.assertEquals(url, newActiveTab.getDisplayUri().toString()); - Assert.assertEquals(newActiveTab.getGuid(), activeTab.getGuid()); - - Set<Tab> allTabs = webEngine2.getTabManager().getAllTabs(); - Assert.assertEquals(1, allTabs.size()); - Assert.assertEquals(newActiveTab, allTabs.iterator().next()); - } - - @Test - @SmallTest - public void incognitoModeNotInterferingWithPerisitenceState() throws Exception { - String perisistenceId = "pid1234"; - String profileName = "pn12345"; - WebEngineParams params = (new WebEngineParams.Builder()) - .setPersistenceId(perisistenceId) - .setProfileName(profileName) - .build(); - // Create an initial WebEngine state and associate it with a persistence ID. - WebEngine webEngine = runOnUiThreadBlocking( - () -> mActivityTestRule.getWebSandbox().createWebEngine(params)) - .get(); - String url = getTestDataURL("simple_page.html"); - Tab activeTab = webEngine.getTabManager().getActiveTab(); - mActivityTestRule.navigateAndWait(activeTab, url); - runOnUiThreadBlocking(() -> webEngine.close()); - - // Recreate a WebEngine in incognito mode. - WebEngineParams paramsIncognito = (new WebEngineParams.Builder()) - .setPersistenceId(perisistenceId) - .setProfileName(profileName) - .setIsIncognito(true) - .build(); - WebEngine webEngineIncognito = runOnUiThreadBlocking( - () -> mActivityTestRule.getWebSandbox().createWebEngine(paramsIncognito)) - .get(); - // Test that WebEngine did not recreate based on persistence ID. - Tab incognitoTab = webEngineIncognito.getTabManager().getActiveTab(); - Assert.assertNotEquals(activeTab.getGuid(), incognitoTab.getGuid()); - Assert.assertEquals(Uri.EMPTY, incognitoTab.getDisplayUri()); - Assert.assertEquals(1, webEngineIncognito.getTabManager().getAllTabs().size()); - - runOnUiThreadBlocking(() -> webEngineIncognito.close()); - - // Recreate WebEngine with perisistence ID, and verify that state was not changed. - WebEngine webEngine2 = runOnUiThreadBlocking( - () -> mActivityTestRule.getWebSandbox().createWebEngine(params)) - .get(); - Assert.assertEquals( - url, webEngine2.getTabManager().getActiveTab().getDisplayUri().toString()); - Assert.assertEquals(1, webEngine2.getTabManager().getAllTabs().size()); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabManagerTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabManagerTest.java deleted file mode 100644 index bdcaba7..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabManagerTest.java +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; - -import static org.hamcrest.CoreMatchers.is; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import android.content.pm.ActivityInfo; - -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.Criteria; -import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabListObserver; -import org.chromium.webengine.TabManager; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.Set; -import java.util.concurrent.CountDownLatch; - -/** - * Tests various aspects of interacting with Tabs. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class TabManagerTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - - WebSandbox mSandbox; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - mServer = mTestServerRule.getServer(); - - mSandbox = mActivityTestRule.getWebSandbox(); - } - - @After - public void shutdown() throws Exception { - if (mSandbox != null) { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - } - mActivityTestRule.finish(); - } - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } - - @Test - @SmallTest - public void tabGetsAddedAndActivatedOnStartup() throws Exception { - WebEngine webEngine = runOnUiThreadBlocking(() -> mSandbox.createWebEngine()).get(); - - Tab activeTab = webEngine.getTabManager().getActiveTab(); - Assert.assertNotNull(activeTab); - - Set<Tab> allTabs = webEngine.getTabManager().getAllTabs(); - Assert.assertEquals(1, allTabs.size()); - - Assert.assertTrue(allTabs.contains(activeTab)); - } - - @Test - @SmallTest - public void tabsGetAddedToRegistry() throws Exception { - WebEngine webEngine = runOnUiThreadBlocking(() -> mSandbox.createWebEngine()).get(); - - Set<Tab> initialTabs = webEngine.getTabManager().getAllTabs(); - Assert.assertEquals(1, initialTabs.size()); - - Tab addedTab = runOnUiThreadBlocking(() -> webEngine.getTabManager().createTab()).get(); - Set<Tab> twoTabs = webEngine.getTabManager().getAllTabs(); - Assert.assertEquals(2, twoTabs.size()); - Assert.assertTrue(twoTabs.contains(addedTab)); - } - - @Test - @SmallTest - @DisabledTest(message = "Flaky") - public void tabsPersistAcrossRotations() throws Exception { - String url = getTestDataURL("simple_page.html"); - WebEngine webEngine = mActivityTestRule.createWebEngineAttachThenNavigateAndWait(url); - - // Rotate device. - mActivityTestRule.getActivity().setRequestedOrientation( - ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - CriteriaHelper.pollUiThread(() -> { - Criteria.checkThat( - mActivityTestRule.getActivity().getResources().getConfiguration().orientation, - is(ORIENTATION_LANDSCAPE)); - }); - Tab activeTab = webEngine.getTabManager().getActiveTab(); - Assert.assertEquals(url, activeTab.getDisplayUri().toString()); - } - - private static final class TabHolder { - private Tab mAddedTab; - private Tab mActiveTab; - private Tab mRemovedTab; - } - - @Test - @SmallTest - public void newTabCanBeActivatedAndRemoved() throws Exception { - // One count for the initial tab created and one for the tab we programmatically create. - CountDownLatch activeLatch = new CountDownLatch(1); - CountDownLatch removeLatch = new CountDownLatch(1); - - final TabHolder holder = new TabHolder(); - WebEngine webEngine = runOnUiThreadBlocking(() -> mSandbox.createWebEngine()).get(); - runOnUiThreadBlocking( - () -> webEngine.getTabManager().registerTabListObserver(new TabListObserver() { - @Override - public void onTabAdded(WebEngine webEngine, Tab tab) { - holder.mAddedTab = tab; - } - - @Override - public void onActiveTabChanged(WebEngine webEngine, Tab tab) { - holder.mActiveTab = tab; - activeLatch.countDown(); - } - - @Override - public void onTabRemoved(WebEngine webEngine, Tab tab) { - holder.mRemovedTab = tab; - removeLatch.countDown(); - } - })); - runOnUiThreadBlocking(() -> mActivityTestRule.attachFragment(webEngine.getFragment())); - TabManager tabManager = webEngine.getTabManager(); - Tab newTab = runOnUiThreadBlocking(() -> tabManager.createTab()).get(); - Assert.assertEquals(newTab, holder.mAddedTab); - - runOnUiThreadBlocking(() -> newTab.setActive()); - activeLatch.await(); - Assert.assertEquals(newTab, holder.mActiveTab); - - runOnUiThreadBlocking(() -> newTab.close()); - removeLatch.await(); - Assert.assertEquals(newTab, holder.mRemovedTab); - - Assert.assertNull(tabManager.getActiveTab()); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabNavigationControllerTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabNavigationControllerTest.java deleted file mode 100644 index a581d908e..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabNavigationControllerTest.java +++ /dev/null
@@ -1,213 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.annotation.NonNull; -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Navigation; -import org.chromium.webengine.NavigationObserver; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabNavigationController; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.concurrent.CountDownLatch; - -/** - * Tests various aspects of Navigations and NavigationObservers. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class TabNavigationControllerTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - - private WebSandbox mSandbox; - - private TabNavigationController mNavigationController; - private Tab mActiveTab; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - mServer = mTestServerRule.getServer(); - - mSandbox = mActivityTestRule.getWebSandbox(); - WebEngine webEngine = runOnUiThreadBlocking(() -> mSandbox.createWebEngine()).get(); - - mActiveTab = webEngine.getTabManager().getActiveTab(); - mNavigationController = mActiveTab.getNavigationController(); - } - - @After - public void shutdown() throws Exception { - if (mSandbox != null) { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - } - mActivityTestRule.finish(); - } - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } - - private void navigateSync(String url) throws InterruptedException { - CountDownLatch navigationCompleted = new CountDownLatch(1); - - runOnUiThreadBlocking(() -> { - mNavigationController.registerNavigationObserver(new NavigationObserver() { - @Override - public void onNavigationCompleted( - @NonNull Tab tab, @NonNull Navigation navigation) { - navigationCompleted.countDown(); - } - }); - mNavigationController.navigate(url); - }); - navigationCompleted.await(); - } - - @Test - @SmallTest - public void cannotGoBackOnFirstLoadedUrl() throws Exception { - Assert.assertFalse((runOnUiThreadBlocking(() -> mNavigationController.canGoBack())).get()); - navigateSync(getTestDataURL("simple_page.html")); - Assert.assertFalse((runOnUiThreadBlocking(() -> mNavigationController.canGoBack())).get()); - } - - @Test - @SmallTest - public void canGoBackOnSecondLoadedUrl() throws Exception { - navigateSync(getTestDataURL("simple_page.html")); - navigateSync(getTestDataURL("simple_page2.html")); - Assert.assertTrue((runOnUiThreadBlocking(() -> mNavigationController.canGoBack())).get()); - } - - @Test - @SmallTest - public void cannotGoForwardWhenNotNavigatedBackBefore() throws Exception { - navigateSync(getTestDataURL("simple_page.html")); - Assert.assertFalse( - (runOnUiThreadBlocking(() -> mNavigationController.canGoForward())).get()); - } - - @Test - @SmallTest - public void backNavigationToFirstPage() throws Exception { - navigateSync(getTestDataURL("simple_page.html")); - navigateSync(getTestDataURL("simple_page2.html")); - - // Synchronously go back. - CountDownLatch navigationCompleted = new CountDownLatch(1); - runOnUiThreadBlocking(() -> { - mNavigationController.registerNavigationObserver(new NavigationObserver() { - @Override - public void onNavigationCompleted( - @NonNull Tab tab, @NonNull Navigation navigation) { - navigationCompleted.countDown(); - } - }); - mNavigationController.goBack(); - }); - navigationCompleted.await(); - - Assert.assertEquals( - getTestDataURL("simple_page.html"), mActiveTab.getDisplayUri().toString()); - Assert.assertFalse((runOnUiThreadBlocking(() -> mNavigationController.canGoBack())).get()); - Assert.assertTrue( - (runOnUiThreadBlocking(() -> mNavigationController.canGoForward())).get()); - } - - @Test - @SmallTest - public void forwardNavigationAfterBackNavigation() throws Exception { - navigateSync(getTestDataURL("simple_page.html")); - navigateSync(getTestDataURL("simple_page2.html")); - - // Synchronously go back. - CountDownLatch backNavigationCompleted = new CountDownLatch(1); - runOnUiThreadBlocking(() -> { - mNavigationController.registerNavigationObserver(new NavigationObserver() { - @Override - public void onNavigationCompleted( - @NonNull Tab tab, @NonNull Navigation navigation) { - backNavigationCompleted.countDown(); - } - }); - mNavigationController.goBack(); - }); - backNavigationCompleted.await(); - Assert.assertEquals( - getTestDataURL("simple_page.html"), mActiveTab.getDisplayUri().toString()); - - // Synchronously go forward - CountDownLatch forwardNavigationCompleted = new CountDownLatch(1); - runOnUiThreadBlocking(() -> { - mNavigationController.registerNavigationObserver(new NavigationObserver() { - @Override - public void onNavigationCompleted( - @NonNull Tab tab, @NonNull Navigation navigation) { - forwardNavigationCompleted.countDown(); - } - }); - mNavigationController.goForward(); - }); - forwardNavigationCompleted.await(); - Assert.assertEquals( - getTestDataURL("simple_page2.html"), mActiveTab.getDisplayUri().toString()); - } - - @Test - @SmallTest - public void testAllNavigationEventsAreReceivedOnNavigate() throws Exception { - CountDownLatch navigationCompleted = new CountDownLatch(1); - CountDownLatch navigationStarted = new CountDownLatch(1); - CountDownLatch finishedLoadProgress = new CountDownLatch(1); - - runOnUiThreadBlocking(() -> { - mNavigationController.registerNavigationObserver(new NavigationObserver() { - @Override - public void onNavigationStarted(@NonNull Tab tab, @NonNull Navigation navigation) { - navigationStarted.countDown(); - } - @Override - public void onNavigationCompleted( - @NonNull Tab tab, @NonNull Navigation navigation) { - navigationCompleted.countDown(); - } - @Override - public void onLoadProgressChanged(@NonNull Tab tab, double progress) { - if (progress == 1.0) { - finishedLoadProgress.countDown(); - } - } - }); - - mNavigationController.navigate(getTestDataURL("simple_page.html")); - }); - navigationStarted.await(); - navigationCompleted.await(); - finishedLoadProgress.await(); - } -} \ No newline at end of file
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabPrerenderTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabPrerenderTest.java deleted file mode 100644 index d24ec27..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/TabPrerenderTest.java +++ /dev/null
@@ -1,155 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.hamcrest.CoreMatchers.is; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.test.filters.MediumTest; -import androidx.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.Criteria; -import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.webengine.Navigation; -import org.chromium.webengine.NavigationObserver; -import org.chromium.webengine.Tab; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.concurrent.CountDownLatch; - -/** - * Tests prerendering when tab navigations happen before the UI is shown. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class TabPrerenderTest { - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - @Rule - public DigitalAssetLinksServerRule mDALServerRule = new DigitalAssetLinksServerRule(); - - private Tab mTab; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - - mDALServerRule.setUpDigitalAssetLinks(); - - WebSandbox sandbox = mActivityTestRule.getWebSandbox(); - WebEngine webEngine = runOnUiThreadBlocking(() -> sandbox.createWebEngine()).get(); - mTab = runOnUiThreadBlocking(() -> webEngine.getTabManager().createTab()).get(); - - String scriptContents = "const div = document.createElement('div');" - + "div.id = 'id1';" - + "div.innerText = 'Div1';" - + "document.body.appendChild(div);"; - mDALServerRule.getServer().setResponse("/script.js", scriptContents, null); - } - - private void navigateToPage(String pageContents) throws Exception { - String url = mDALServerRule.getServer().setResponse("/page.html", pageContents, null); - - CountDownLatch navigationCompletedLatch = new CountDownLatch(1); - runOnUiThreadBlocking(() - -> mTab.getNavigationController().registerNavigationObserver( - new NavigationObserver() { - @Override - public void onNavigationCompleted( - Tab tab, Navigation navigation) { - navigationCompletedLatch.countDown(); - } - })); - - runOnUiThreadBlocking(() -> mTab.getNavigationController().navigate(url)); - navigationCompletedLatch.await(); - } - - private String executeScript(String scriptContents) { - try { - return runOnUiThreadBlocking(() -> mTab.executeScript(scriptContents, false)).get(); - } catch (Exception e) { - Assert.fail("Unexpected exception executing script: " + e.getMessage()); - return null; - } - } - - @SmallTest - @Test - public void pageContentsAreAvailable() throws Exception { - navigateToPage("<html><head></head><body><div id=\"id1\">Div1</div></body>"); - CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat( - executeScript("document.querySelector('#id1').innerText"), is("\"Div1\"")); - }); - } - - @SmallTest - @Test - public void blockingScriptChangesAreAvailable() throws Exception { - navigateToPage("<html><head></head><body><script src=\"/script.js\"></script></body>"); - - CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat( - executeScript("document.getElementsByTagName('script').length"), is("1")); - Criteria.checkThat( - executeScript("document.querySelector('#id1').innerText"), is("\"Div1\"")); - }); - } - - @SmallTest - @Test - public void asyncScriptChangesAreAvailable() throws Exception { - navigateToPage( - "<html><head></head><body><script async src=\"/script.js\"></script></body>"); - - CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat( - executeScript("document.getElementsByTagName('script').length"), is("1")); - Criteria.checkThat( - executeScript("document.querySelector('#id1').innerText"), is("\"Div1\"")); - }); - } - - @SmallTest - @Test - public void deferredScriptChangesAreAvailable() throws Exception { - navigateToPage( - "<html><head></head><body><script defer src=\"/script.js\"></script></body>"); - CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat( - executeScript("document.getElementsByTagName('script').length"), is("1")); - Criteria.checkThat( - executeScript("document.querySelector('#id1').innerText"), is("\"Div1\"")); - }); - } - - @MediumTest - @Test - public void asyncTasksInScriptsExecute() throws Exception { - navigateToPage( - "<html><head></head><body><script>setTimeout(() => document.body.appendChild(document.createElement('div')), 2000);</script></body>"); - - CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat( - executeScript("document.getElementsByTagName('div').length"), is("0")); - }); - Thread.sleep(5000); - CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat( - executeScript("document.getElementsByTagName('div').length"), is("1")); - }); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineActivityTestRule.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineActivityTestRule.java deleted file mode 100644 index c98dcb6..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineActivityTestRule.java +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import android.app.Activity; -import android.content.Context; -import android.text.TextUtils; - -import androidx.test.InstrumentationRegistry; - -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import org.chromium.base.CommandLine; -import org.chromium.base.test.BaseActivityTestRule; - -import java.io.File; -import java.io.OutputStreamWriter; -import java.io.Writer; - -/** - * Base ActivityTestRule for WebEngine instrumentation tests. - * - * This rule contains some common setup needed to deal with WebEngine's multiple classloaders. - */ -abstract class WebEngineActivityTestRule<T extends Activity> extends BaseActivityTestRule<T> { - private static final String COMMAND_LINE_FILE = "weblayer-command-line"; - - public WebEngineActivityTestRule(Class<T> clazz) { - super(clazz); - } - - /** - * Writes the command line file. This can be useful if a test needs to dynamically add command - * line arguments before WebLayer has been loaded. - */ - public void writeCommandLineFile() throws Exception { - // The CommandLine instance we have here will not be picked up in the - // implementation since they use different class loaders, so we need to write - // all the switches to the WebLayer command line file. - try (Writer writer = new OutputStreamWriter( - InstrumentationRegistry.getInstrumentation().getTargetContext().openFileOutput( - COMMAND_LINE_FILE, Context.MODE_PRIVATE), - "UTF-8")) { - writer.write(TextUtils.join(" ", CommandLine.getJavaSwitchesOrNull())); - } - } - - @Override - public Statement apply(final Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - try { - writeCommandLineFile(); - base.evaluate(); - } finally { - new File(InstrumentationRegistry.getInstrumentation() - .getTargetContext() - .getFilesDir(), - COMMAND_LINE_FILE) - .delete(); - } - } - }; - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineJUnit4ClassRunner.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineJUnit4ClassRunner.java deleted file mode 100644 index 0d8f8dbd..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineJUnit4ClassRunner.java +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import org.junit.runners.model.InitializationError; - -import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.util.SkipCheck; - -import java.util.List; - -/** - * A custom runner for //weblayer JUnit4 tests. - */ -public class WebEngineJUnit4ClassRunner extends BaseJUnit4ClassRunner { - /** - * Create a WebEngineJUnit4ClassRunner to run {@code klass} and initialize values. - * - * @throws InitializationError if the test class malformed - */ - public WebEngineJUnit4ClassRunner(final Class<?> klass) throws InitializationError { - super(klass); - } - - @Override - protected List<SkipCheck> getSkipChecks() { - // TODO(rayankans): Add SkipChecks. - return super.getSkipChecks(); - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineTest.java deleted file mode 100644 index 16e0fae..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebEngineTest.java +++ /dev/null
@@ -1,216 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.annotation.NonNull; -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Navigation; -import org.chromium.webengine.NavigationObserver; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabListObserver; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; - -/** - * Tests functions called on the WebEngine object. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class WebEngineTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - - WebSandbox mSandbox; - WebEngine mWebEngine; - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - mServer = mTestServerRule.getServer(); - - mSandbox = mActivityTestRule.getWebSandbox(); - mWebEngine = runOnUiThreadBlocking(() -> mSandbox.createWebEngine()).get(); - } - - @After - public void shutdown() throws Exception { - if (mSandbox != null) { - runOnUiThreadBlocking(() -> mSandbox.shutdown()); - } - mActivityTestRule.finish(); - } - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } - - @Test - @SmallTest - public void tabManagerIsAvailable() throws Exception { - Assert.assertNotNull(mWebEngine.getTabManager()); - } - - @Test - @SmallTest - public void tabCookieIsAvailable() throws Exception { - Assert.assertNotNull(mWebEngine.getCookieManager()); - } - - @Test - @SmallTest - public void navigateBackEngineOnInitialStateReturnsFalse() throws Exception { - boolean handledBackNav = runOnUiThreadBlocking(() -> mWebEngine.tryNavigateBack()).get(); - Assert.assertFalse(handledBackNav); - } - - @Test - @SmallTest - public void navigateBackEngineHandlesBackNavInTab() throws Exception { - String url1 = getTestDataURL("simple_page.html"); - String url2 = getTestDataURL("simple_page2.html"); - Tab activeTab = mWebEngine.getTabManager().getActiveTab(); - mActivityTestRule.navigateAndWait(activeTab, url1); - mActivityTestRule.navigateAndWait(activeTab, url2); - - // Go back and wait until navigation completed. - CountDownLatch navigationCompletedLatch = new CountDownLatch(1); - runOnUiThreadBlocking(() -> { - activeTab.getNavigationController().registerNavigationObserver( - new NavigationObserver() { - @Override - public void onNavigationCompleted(Tab tab, @NonNull Navigation navigation) { - navigationCompletedLatch.countDown(); - } - }); - }); - boolean handledBackNav = runOnUiThreadBlocking(() -> mWebEngine.tryNavigateBack()).get(); - navigationCompletedLatch.await(); - - Assert.assertTrue(handledBackNav); - Assert.assertEquals(1, mWebEngine.getTabManager().getAllTabs().size()); - Assert.assertEquals( - url1, mWebEngine.getTabManager().getActiveTab().getDisplayUri().toString()); - } - - @Test - @SmallTest - public void navigateBackEngineClosesTabAndSetsPreviousTabActive() throws Exception { - Tab firstTab = mWebEngine.getTabManager().getActiveTab(); - String url1 = getTestDataURL("simple_page.html"); - mActivityTestRule.navigateAndWait(firstTab, url1); - - Tab secondTab = runOnUiThreadBlocking(() -> mWebEngine.getTabManager().createTab()).get(); - Assert.assertEquals(2, mWebEngine.getTabManager().getAllTabs().size()); - - // Synchronously Set second Tab to active. - CountDownLatch secondTabActiveLatch = new CountDownLatch(1); - runOnUiThreadBlocking(() -> { - mWebEngine.getTabManager().registerTabListObserver(new TabListObserver() { - @Override - public void onActiveTabChanged( - @NonNull WebEngine webEngine, @NonNull Tab activeTab) { - secondTabActiveLatch.countDown(); - } - }); - secondTab.setActive(); - }); - secondTabActiveLatch.await(); - Assert.assertEquals(secondTab, mWebEngine.getTabManager().getActiveTab()); - - String url2 = getTestDataURL("simple_page2.html"); - mActivityTestRule.navigateAndWait(secondTab, url2); - - // // Go back and wait until active tab changed and second tab was removed. - CountDownLatch activeTabChangedLatch = new CountDownLatch(1); - CountDownLatch prevTabRemovedLatch = new CountDownLatch(1); - runOnUiThreadBlocking(() -> { - mWebEngine.getTabManager().registerTabListObserver(new TabListObserver() { - @Override - public void onActiveTabChanged( - @NonNull WebEngine webEngine, @NonNull Tab activeTab) { - activeTabChangedLatch.countDown(); - } - @Override - public void onTabRemoved(@NonNull WebEngine webEngine, @NonNull Tab activeTab) { - prevTabRemovedLatch.countDown(); - } - }); - }); - boolean handledBackNav = runOnUiThreadBlocking(() -> mWebEngine.tryNavigateBack()).get(); - activeTabChangedLatch.await(); - prevTabRemovedLatch.await(); - - Assert.assertTrue(handledBackNav); - Assert.assertEquals(1, mWebEngine.getTabManager().getAllTabs().size()); - Assert.assertEquals(firstTab, mWebEngine.getTabManager().getActiveTab()); - Assert.assertEquals( - url1, mWebEngine.getTabManager().getActiveTab().getDisplayUri().toString()); - } - - @Test - @SmallTest - public void closingWebEngineRemovesItFromSandbox() throws Exception { - int numWebEngines = runOnUiThreadBlocking(() -> { - mWebEngine.close(); - return mSandbox.getWebEngines().size(); - }); - Assert.assertEquals(0, numWebEngines); - } - - @Test - @SmallTest - public void createWebEngineWithTag() throws Exception { - String tag = "web-engine-tag"; - WebEngine webEngineWithTag = - runOnUiThreadBlocking(() -> mSandbox.createWebEngine(tag)).get(); - - Assert.assertEquals(webEngineWithTag, mSandbox.getWebEngine(tag)); - Assert.assertEquals(tag, webEngineWithTag.getTag()); - } - - @Test - @SmallTest - public void createWebEngineWithoutTag() throws Exception { - WebEngine webEngineWithoutGivenTag = - runOnUiThreadBlocking(() -> mSandbox.createWebEngine()).get(); - - Assert.assertTrue(mSandbox.getWebEngines().contains(webEngineWithoutGivenTag)); - // Check that a tag was given to the web-engine - Assert.assertEquals("webengine_1", webEngineWithoutGivenTag.getTag()); - } - - @Test - @SmallTest - public void cannotCreateWebEngineWithIdenticalTags() throws Exception { - String tag = "web-engine-tag"; - WebEngine webEngineWithTag = - runOnUiThreadBlocking(() -> mSandbox.createWebEngine(tag)).get(); - - Assert.assertThrows(ExecutionException.class, - () -> runOnUiThreadBlocking(() -> mSandbox.createWebEngine(tag))); - } -} \ No newline at end of file
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebFragmentTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebFragmentTest.java deleted file mode 100644 index a9c60b4..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebFragmentTest.java +++ /dev/null
@@ -1,125 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import android.net.Uri; - -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.Batch; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; -import org.chromium.webengine.Tab; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -/** - * Tests that basic fragment operations work as intended. - */ -@Batch(Batch.PER_CLASS) -@RunWith(WebEngineJUnit4ClassRunner.class) -public class WebFragmentTest { - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - private EmbeddedTestServer mServer; - private WebSandbox mWebSandbox; - - @Before - public void setUp() throws Throwable { - mServer = mTestServerRule.getServer(); - mActivityTestRule.launchShell(); - mWebSandbox = mActivityTestRule.getWebSandbox(); - } - - @After - public void tearDown() { - mActivityTestRule.finish(); - runOnUiThreadBlocking(() -> mWebSandbox.shutdown()); - } - - private String getTestDataURL(String path) { - return mServer.getURL("/weblayer/test/data/" + path); - } - - @Test - @SmallTest - public void loadsPage() throws Exception { - WebEngine webEngine = runOnUiThreadBlocking(() -> mWebSandbox.createWebEngine()).get(); - runOnUiThreadBlocking(() -> mActivityTestRule.attachFragment(webEngine.getFragment())); - - Tab activeTab = webEngine.getTabManager().getActiveTab(); - - Assert.assertEquals(activeTab.getDisplayUri(), Uri.EMPTY); - - String url = getTestDataURL("simple_page.html"); - mActivityTestRule.navigateAndWait(activeTab, url); - - Assert.assertEquals(runOnUiThreadBlocking(() -> activeTab.getDisplayUri()), Uri.parse(url)); - } - - /** - * This test is similar to the previous one and just ensures that these unit tests can be - * batched. - */ - @Test - @SmallTest - public void successfullyLoadDifferentPage() throws Exception { - mActivityTestRule.createWebEngineAttachThenNavigateAndWait( - getTestDataURL("simple_page2.html")); - } - - @Test - @SmallTest - public void fragmentTabCanLoadMultiplePages() throws Exception { - mActivityTestRule.createWebEngineAttachThenNavigateAndWait( - getTestDataURL("simple_page.html")); - - Tab tab = mActivityTestRule.getActiveTab(); - mActivityTestRule.navigateAndWait(tab, getTestDataURL("simple_page2.html")); - - Assert.assertTrue(tab.getDisplayUri().toString().endsWith("simple_page2.html")); - } - - @Test - @SmallTest - public void fragmentsCanBeReplaced() throws Exception { - mActivityTestRule.createWebEngineAttachThenNavigateAndWait( - getTestDataURL("simple_page.html")); - // New fragment - mActivityTestRule.createWebEngineAttachThenNavigateAndWait( - getTestDataURL("simple_page2.html")); - - Tab tab = mActivityTestRule.getActiveTab(); - Assert.assertTrue(tab.getDisplayUri().toString().endsWith("simple_page2.html")); - } - - @Test - @SmallTest - public void navigationFailure() { - try { - mActivityTestRule.createWebEngineAttachThenNavigateAndWait( - getTestDataURL("missingpage.html")); - Assert.fail("exception not thrown"); - } catch (RuntimeException e) { - Assert.assertEquals(e.getMessage(), "Navigation failed."); - } catch (Exception e) { - Assert.fail("RuntimeException not thrown, instead got: " + e); - } - } -}
diff --git a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebSandboxTest.java b/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebSandboxTest.java deleted file mode 100644 index b64680a..0000000 --- a/weblayer/browser/android/javatests/src/org/chromium/webengine/test/WebSandboxTest.java +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.test; - -import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; - -import androidx.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.DoNotBatch; -import org.chromium.webengine.WebSandbox; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Tests the WebSandbox API. - */ -@DoNotBatch(reason = "Tests need separate Activities and WebFragments") -@RunWith(WebEngineJUnit4ClassRunner.class) -public class WebSandboxTest { - @Rule - public InstrumentationActivityTestRule mActivityTestRule = - new InstrumentationActivityTestRule(); - - @Before - public void setUp() throws Exception { - mActivityTestRule.launchShell(); - } - - @After - public void shutdown() throws Exception { - mActivityTestRule.finish(); - } - - @Test - @SmallTest - public void canStartSandbox() throws Exception { - Assert.assertNotNull(mActivityTestRule.getWebSandbox()); - } - - @Test - @SmallTest - public void onlyOneSandboxIsCreated() throws Exception { - WebSandbox sandbox1 = mActivityTestRule.getWebSandbox(); - WebSandbox sandbox2 = - runOnUiThreadBlocking(() -> WebSandbox.create(mActivityTestRule.getContext())) - .get(); - - Assert.assertEquals(sandbox1, sandbox2); - } - - @Test - @SmallTest - public void returnsVersion() throws Exception { - String returnedVersion = - runOnUiThreadBlocking(() -> WebSandbox.getVersion(mActivityTestRule.getContext())) - .get(); - Assert.assertNotNull(returnedVersion); - - Pattern expectedVersionPattern = - Pattern.compile("[0-9]*[.][0-9]*[.][0-9]*", Pattern.CASE_INSENSITIVE); - Matcher returnedVersionMatcher = expectedVersionPattern.matcher(returnedVersion); - Assert.assertTrue(returnedVersionMatcher.find()); - } - - @Test - @SmallTest - public void returnsIfIsAvailable() throws Exception { - boolean isAvailable = - runOnUiThreadBlocking(() -> WebSandbox.isAvailable(mActivityTestRule.getContext())) - .get(); - Assert.assertTrue(isAvailable); - } - - @Test - @SmallTest - public void returnsProviderPackageName() throws Exception { - String providerPackageName = runOnUiThreadBlocking( - () -> WebSandbox.getProviderPackageName(mActivityTestRule.getContext())) - .get(); - Assert.assertEquals("org.chromium.weblayer.support", providerPackageName); - } -} \ No newline at end of file
diff --git a/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py b/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py deleted file mode 100755 index cad5ac8..0000000 --- a/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py +++ /dev/null
@@ -1,223 +0,0 @@ -#!/usr/bin/env vpython3 -# -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Runs WebLayer instrumentation tests against arbitrary versions of tests, the -# client, and the implementation. -# -# Example usage, testing M80 tests and client against master implementation: -# autoninja -C out/Release weblayer_instrumentation_test_versions_apk -# cipd install --root /tmp/M80 chromium/testing/weblayer-x86 m80 -# out/Release/bin/run_weblayer_instrumentation_test_versions_apk \ -# --test-runner-outdir out/Release -# --client-outdir /tmp/M80/out/Release -# --implementation-outdir out/Release - -import argparse -import logging -import operator -import os -import re -import subprocess -import sys - -CUR_DIR = os.path.dirname(os.path.realpath(__file__)) - -# Find src root starting from either the release bin directory or original path. -if os.path.basename(CUR_DIR) == 'bin': - SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(CUR_DIR))) -else: - SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname( - CUR_DIR)))) - -TYP_DIR = os.path.join( - SRC_DIR, 'third_party', 'catapult', 'third_party', 'typ') - -if TYP_DIR not in sys.path: - sys.path.insert(0, TYP_DIR) - -import typ - - -# Mapping of operator string in the expectation file tags to actual operator. -OP_MAP = {'gte': operator.ge, 'lte': operator.le} - - -def tag_matches(tag, impl_version='trunk', client_version='trunk'): - """Test if specified versions match the tag. - - Args: - tag: skew test expectation tag, e.g. 'impl_lte_5' or 'client_lte_2'. - impl_version: WebLayer implementation version number or 'trunk'. - client_version: WebLayer implementation version number or 'trunk'. - - Returns: - True if the specified versions match the tag. - - Raises: - AssertionError if the tag is invalid. - """ - # 'All' is special cased to match anything. - if tag == 'all': - return True - # Extract the three components from the tag. - match = re.match(r'(client|impl)_([gl]te)_([0-9]+)', tag) - assert match is not None, ( - 'tag must be of the form "{client,impl}_{gte,lte}_$version", found %r' % - tag) - target_str, op_str, tag_version_str = match.groups() - - # If a version is specified see if the tag refers to the same target or - # return False otherwise. - if impl_version != 'trunk' and target_str != 'impl': - return False - if client_version != 'trunk' and target_str != 'client': - return False - - - version = impl_version if impl_version != 'trunk' else client_version - assert type(version) == int, 'Specified version must be an integer.' - - tag_version = int(tag_version_str) - op = OP_MAP[op_str] - return op(version, tag_version) - - -def tests_to_skip(expectation_contents, impl_version='trunk', - client_version='trunk'): - """Get list of tests to skip for the given version. - - Args: - expectation_contents: String containing expectation file contents. - impl_version: WebLayer implementation version number or 'trunk'. - client_version: WebLayer implementation version number or 'trunk'. - - Returns: - List of test names to skip. - - Raises: - AssertionError if both versions are 'trunk'. - """ - assert impl_version != 'trunk' or client_version != 'trunk' - - parser = typ.expectations_parser.TaggedTestListParser(expectation_contents) - - tests = [] - for expectation in parser.expectations: - assert len(expectation.tags) == 1, ( - 'Only one tag is allowed per expectation.') - assert len(expectation.results) == 1 and ( - typ.json_results.ResultType.Skip in expectation.results), ( - 'Only "Skip" is supported in the skew test expectations.') - - # Iterate over the first (and only) item since can't index over a frozenset. - tag = next(iter(expectation.tags)) - if tag_matches(tag, impl_version, client_version): - tests.append(expectation.test) - return tests - - -def main(): - """Wrapper to call weblayer instrumentation tests with different versions.""" - - parser = argparse.ArgumentParser( - description='Run weblayer instrumentation tests at different versions.') - parser.add_argument( - '--test-runner-outdir', - required=True, - help='Local build output directory for finding the test runner.') - parser.add_argument( - '--client-outdir', - required=True, - help='Build output directory for WebLayer client.') - parser.add_argument( - '--implementation-outdir', - required=True, - help='Build output directory for WebLayer implementation.') - parser.add_argument( - '--test-expectations', - required=False, - default='', - help=('Test expectations file describing which tests are failing at ' - 'different versions.')) - - # There are two Webview apks that are available for WebLayer skew tests. - # crbug.com/1163652. - parser.add_argument( - '--webview-apk-path', - required=True, - help=('Relative path for the WebLayer implementation library apk. ' - 'The path is relative to the WebLayer implementation ' - 'output directory.')) - - version_group = parser.add_mutually_exclusive_group(required=True) - version_group.add_argument( - '--client-version', - default='trunk', - help=('Version of the client being used if not trunk. Only set one of ' - '--client-version and --impl-version.')) - version_group.add_argument( - '--impl-version', - default='trunk', - help=('Version of the implementation being used if not trunk. Only set ' - 'one of --client-version and --impl-version.')) - args, remaining_args = parser.parse_known_args() - - logging.basicConfig(level=logging.INFO) - - # The command line is derived from the resulting command line from - # run_weblayer_instrumentation_test_apk but with parameterized client and - # implementation. - test_runner_srcdir = os.path.normpath( - os.path.join(args.test_runner_outdir, '..', '..')) - executable_path = os.path.join(test_runner_srcdir, - 'build/android/test_runner.py') - executable_args = [ - 'instrumentation', - '--output-directory', - args.client_outdir, - '--runtime-deps-path', - os.path.join(args.client_outdir, - ('gen.runtime/weblayer/browser/android/javatests/' + - 'weblayer_instrumentation_test_apk.runtime_deps')), - '--test-apk', - os.path.join(args.client_outdir, - 'apks/WebLayerInstrumentationTest.apk'), - '--apk-under-test', - os.path.join(args.client_outdir, 'apks/WebLayerShellSystemWebView.apk'), - '--use-webview-provider', - os.path.join(args.implementation_outdir, args.webview_apk_path), - '--additional-apk', - os.path.join(args.client_outdir, 'apks/ChromiumNetTestSupport.apk')] - - cmd = [sys.executable, executable_path] + executable_args + remaining_args - - # Pass along the implementation version if it's set so that tests can - # be filtered through the @MinWebLayerVersion annotation. - # Note: The Chrome Android command line library requires the flag be passed - # with "=" rather than as two arguments. - if args.impl_version != 'trunk': - cmd.append('--impl-version=%s' % args.impl_version) - - tests = [] - if args.test_expectations: - if args.impl_version != 'trunk': - args.impl_version = int(args.impl_version) - if args.client_version != 'trunk': - args.client_version = int(args.client_version) - with open(args.test_expectations) as expectations_file: - contents = expectations_file.read() - tests = tests_to_skip(contents, impl_version=args.impl_version, - client_version=args.client_version) - if tests: - logging.info('Filtering known failing tests: %s', tests) - cmd.append('--test-filter=-%s' % ':'.join(tests)) - - logging.info(' '.join(cmd)) - return subprocess.call(cmd) - - -if __name__ == '__main__': - sys.exit(main())
diff --git a/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions_test.py b/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions_test.py deleted file mode 100755 index 002313e..0000000 --- a/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions_test.py +++ /dev/null
@@ -1,82 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Test helper functions in skew test wrapper. - -import textwrap -import unittest - -import weblayer_instrumentation_test_versions - - -class ExpectationsTest(unittest.TestCase): - - def testMatchesImpl(self): - tag_matches = weblayer_instrumentation_test_versions.tag_matches - - self.assertTrue(tag_matches('impl_lte_84', impl_version=83)) - self.assertTrue(tag_matches('impl_lte_83', impl_version=83)) - self.assertFalse(tag_matches('impl_lte_82', impl_version=83)) - - def testMatchesClient(self): - tag_matches = weblayer_instrumentation_test_versions.tag_matches - - self.assertTrue(tag_matches('client_lte_84', client_version=83)) - self.assertTrue(tag_matches('client_lte_83', client_version=83)) - self.assertFalse(tag_matches('client_lte_82', client_version=83)) - - def testMismatchedTargets(self): - tag_matches = weblayer_instrumentation_test_versions.tag_matches - - self.assertFalse(tag_matches('client_lte_80', impl_version=80)) - self.assertFalse(tag_matches('impl_lte_80', client_version=80)) - - def testMatchesGreater(self): - tag_matches = weblayer_instrumentation_test_versions.tag_matches - - self.assertFalse(tag_matches('client_gte_84', client_version=83)) - self.assertTrue(tag_matches('client_gte_83', client_version=83)) - self.assertTrue(tag_matches('client_gte_82', client_version=83)) - - def testMatchesInvalid(self): - tag_matches = weblayer_instrumentation_test_versions.tag_matches - - self.assertRaises(AssertionError, tag_matches, 'impl_lte_82') - self.assertRaises(AssertionError, tag_matches, 'impl_x_82', - client_version=83) - self.assertRaises(AssertionError, tag_matches, 'client_lte_82', - client_version='83') - - def testTestsToSkip(self): - expectation_contents = textwrap.dedent(""" - # tags: [ impl_lte_83 client_lte_80 ] - # results: [ Skip ] - - [ impl_lte_83 ] weblayer.NavigationTest#testIntent [ Skip ] - [ client_lte_80 ] weblayer.ExternalTest#testUser [ Skip ] - """) - tests_to_skip = weblayer_instrumentation_test_versions.tests_to_skip - - self.assertEquals( - tests_to_skip(expectation_contents, impl_version=80), - ['weblayer.NavigationTest#testIntent']) - self.assertEquals( - tests_to_skip(expectation_contents, impl_version=83), - ['weblayer.NavigationTest#testIntent']) - self.assertEquals(tests_to_skip(expectation_contents, impl_version=84), []) - - self.assertEquals( - tests_to_skip(expectation_contents, client_version=79), - ['weblayer.ExternalTest#testUser']) - self.assertEquals( - tests_to_skip(expectation_contents, client_version=80), - ['weblayer.ExternalTest#testUser']) - self.assertEquals( - tests_to_skip(expectation_contents, client_version=81), []) - - -if __name__ == '__main__': - unittest.main()
diff --git a/weblayer/browser/android/metrics/DEPS b/weblayer/browser/android/metrics/DEPS deleted file mode 100644 index 3a3f231..0000000 --- a/weblayer/browser/android/metrics/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - "+components/metrics", - "+google_apis/google_api_keys.h", - "+third_party/metrics_proto" -]
diff --git a/weblayer/browser/android/metrics/metrics_browsertest.cc b/weblayer/browser/android/metrics/metrics_browsertest.cc deleted file mode 100644 index 7c20a13..0000000 --- a/weblayer/browser/android/metrics/metrics_browsertest.cc +++ /dev/null
@@ -1,235 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <deque> - -#include "base/metrics/metrics_hashes.h" -#include "base/metrics/statistics_recorder.h" -#include "base/test/bind.h" -#include "components/metrics/log_decoder.h" -#include "components/metrics/metrics_log_uploader.h" -#include "components/metrics/metrics_service.h" -#include "components/metrics/metrics_switches.h" -#include "components/metrics/stability_metrics_helper.h" -#include "content/public/test/browser_test_utils.h" -#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" -#include "weblayer/browser/android/metrics/metrics_test_helper.h" -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" -#include "weblayer/browser/browser_fragment_list.h" -#include "weblayer/browser/browser_list.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/profile.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -bool HasHistogramWithHash(const metrics::ChromeUserMetricsExtension& uma_log, - uint64_t hash) { - for (int i = 0; i < uma_log.histogram_event_size(); ++i) { - if (uma_log.histogram_event(i).name_hash() == hash) { - return true; - } - } - return false; -} - -} // namespace - -class MetricsBrowserTest : public WebLayerBrowserTest { - public: - void SetUp() override { - metrics::ForceEnableMetricsReportingForTesting(); - - InstallTestGmsBridge(GetConsentType(), - base::BindRepeating(&MetricsBrowserTest::OnLogMetrics, - base::Unretained(this))); - WebLayerMetricsServiceClient::GetInstance()->SetFastStartupForTesting(true); - WebLayerMetricsServiceClient::GetInstance()->SetUploadIntervalForTesting( - base::Milliseconds(10)); - WebLayerBrowserTest::SetUp(); - } - - void TearDown() override { - RemoveTestGmsBridge(); - WebLayerBrowserTest::TearDown(); - } - - void OnLogMetrics(metrics::ChromeUserMetricsExtension metric) { - metrics_logs_.push_back(metric); - if (on_new_log_) - std::move(on_new_log_).Run(); - } - - metrics::ChromeUserMetricsExtension WaitForNextMetricsLog() { - if (metrics_logs_.empty()) { - base::RunLoop run_loop; - on_new_log_ = run_loop.QuitClosure(); - run_loop.Run(); - DCHECK(!metrics_logs_.empty()); - } - metrics::ChromeUserMetricsExtension tmp = std::move(metrics_logs_.front()); - metrics_logs_.pop_front(); - return tmp; - } - - size_t GetNumLogs() const { return metrics_logs_.size(); } - - virtual ConsentType GetConsentType() { return ConsentType::kConsent; } - - private: - std::unique_ptr<Profile> profile_; - std::deque<metrics::ChromeUserMetricsExtension> metrics_logs_; - base::OnceClosure on_new_log_; -}; - -IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, ProtoHasExpectedFields) { - metrics::ChromeUserMetricsExtension log = WaitForNextMetricsLog(); - EXPECT_EQ(metrics::ChromeUserMetricsExtension::ANDROID_WEBLAYER, - log.product()); - EXPECT_TRUE(log.has_client_id()); - EXPECT_TRUE(log.has_session_id()); - - const metrics::SystemProfileProto& system_profile = log.system_profile(); - EXPECT_TRUE(system_profile.has_build_timestamp()); - EXPECT_TRUE(system_profile.has_app_version()); - EXPECT_TRUE(system_profile.has_channel()); - EXPECT_TRUE(system_profile.has_install_date()); - EXPECT_TRUE(system_profile.has_application_locale()); - EXPECT_TRUE(system_profile.has_low_entropy_source()); - EXPECT_TRUE(system_profile.has_old_low_entropy_source()); - EXPECT_EQ("Android", system_profile.os().name()); - EXPECT_TRUE(system_profile.os().has_version()); - EXPECT_TRUE(system_profile.hardware().has_system_ram_mb()); - EXPECT_TRUE(system_profile.hardware().has_hardware_class()); - EXPECT_TRUE(system_profile.hardware().has_screen_count()); - EXPECT_TRUE(system_profile.hardware().has_primary_screen_width()); - EXPECT_TRUE(system_profile.hardware().has_primary_screen_height()); - EXPECT_TRUE(system_profile.hardware().has_primary_screen_scale_factor()); - EXPECT_TRUE(system_profile.hardware().has_cpu_architecture()); - EXPECT_TRUE(system_profile.hardware().cpu().has_vendor_name()); - EXPECT_TRUE(system_profile.hardware().cpu().has_signature()); - EXPECT_TRUE(system_profile.hardware().cpu().has_num_cores()); - EXPECT_TRUE(system_profile.hardware().cpu().has_is_hypervisor()); - EXPECT_TRUE(system_profile.hardware().gpu().has_driver_version()); - EXPECT_TRUE(system_profile.hardware().gpu().has_gl_vendor()); - EXPECT_TRUE(system_profile.hardware().gpu().has_gl_renderer()); -} - -IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, PageLoadsEnableMultipleUploads) { - WaitForNextMetricsLog(); - - // At this point, the MetricsService should be asleep, and should not have - // created any more metrics logs. - ASSERT_EQ(0u, GetNumLogs()); - - // The start of a page load should be enough to indicate to the MetricsService - // that the app is "in use" and it's OK to upload the next record. No need to - // wait for onPageFinished, since this behavior should be gated on - // NOTIFICATION_LOAD_START. - shell()->tab()->GetNavigationController()->Navigate(GURL("about:blank")); - - // This may take slightly longer than UPLOAD_INTERVAL_MS, due to the time - // spent processing the metrics log, but should be well within the timeout - // (unless something is broken). - WaitForNextMetricsLog(); - - // If we get here, we got a second metrics log (and the test may pass). If - // there was no second metrics log, then the above call will check fail with a - // timeout. We should not assert the logs are empty however, because it's - // possible we got a metrics log between onPageStarted & onPageFinished, in - // which case onPageFinished would *also* wake up the metrics service, and we - // might potentially have a third metrics log in the queue. -} - -IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, NavigationIncrementsPageLoadCount) { - base::HistogramTester histogram_tester; - ASSERT_TRUE(embedded_test_server()->Start()); - metrics::ChromeUserMetricsExtension log = WaitForNextMetricsLog(); - // The initial log should not have a page load count (because nothing was - // loaded). - { - const metrics::SystemProfileProto& system_profile = log.system_profile(); - ASSERT_TRUE(system_profile.has_stability()); - EXPECT_EQ(0, system_profile.stability().page_load_count()); - histogram_tester.ExpectBucketCount( - "Stability.Counts2", metrics::StabilityEventType::kPageLoad, 0); - } - - // Loading a page should increment the page load count. - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page.html"), shell()); - log = WaitForNextMetricsLog(); - { - const metrics::SystemProfileProto& system_profile = log.system_profile(); - ASSERT_TRUE(system_profile.has_stability()); - EXPECT_EQ(1, system_profile.stability().page_load_count()); - histogram_tester.ExpectBucketCount( - "Stability.Counts2", metrics::StabilityEventType::kPageLoad, 1); - } -} - -IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, RendererHistograms) { - base::HistogramTester histogram_tester; - ASSERT_TRUE(embedded_test_server()->Start()); - - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page.html"), shell()); - - uint64_t hash = base::HashMetricName("Android.SeccompStatus.RendererSandbox"); - - bool collect_final_metrics_for_log_called = false; - - WebLayerMetricsServiceClient::GetInstance() - ->SetCollectFinalMetricsForLogClosureForTesting( - base::BindLambdaForTesting( - [&]() { collect_final_metrics_for_log_called = true; })); - - // Not every WaitForNextMetricsLog call will end up calling - // MetricsServiceClient::CollectFinalMetricsForLog since there may already be - // staged logs to send (see ReportingService::SendNextLog). Since we need to - // wait for CollectFinalMetricsForLog to be run after the navigate call above, - // keep calling WaitForNextMetricsLog until CollectFinalMetricsForLog is - // called. - metrics::ChromeUserMetricsExtension uma_log; - while (!collect_final_metrics_for_log_called) - uma_log = WaitForNextMetricsLog(); - - ASSERT_TRUE(HasHistogramWithHash(uma_log, hash)); -} - -class MetricsBrowserTestWithUserOptOut : public MetricsBrowserTest { - ConsentType GetConsentType() override { return ConsentType::kNoConsent; } -}; - -IN_PROC_BROWSER_TEST_F(MetricsBrowserTestWithUserOptOut, MetricsNotRecorded) { - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(0u, GetNumLogs()); -} - -class MetricsBrowserTestWithConfigurableConsent : public MetricsBrowserTest { - ConsentType GetConsentType() override { return ConsentType::kDelayConsent; } -}; - -IN_PROC_BROWSER_TEST_F(MetricsBrowserTestWithConfigurableConsent, - IsInForegroundWhenConsentGiven) { - // There should be at least one browser which is resumed. This is the trigger - // for whether the MetricsService is considered in the foreground. - EXPECT_TRUE( - BrowserFragmentList::GetInstance()->HasAtLeastOneResumedBrowser()); - RunConsentCallback(true); - // RunConsentCallback() should trigger the MetricsService to start. - EXPECT_TRUE(WebLayerMetricsServiceClient::GetInstance() - ->GetMetricsServiceIfStarted()); - EXPECT_TRUE(WebLayerMetricsServiceClient::GetInstance() - ->GetMetricsService() - ->IsInForegroundForTesting()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/metrics/metrics_test_helper.cc b/weblayer/browser/android/metrics/metrics_test_helper.cc deleted file mode 100644 index 724c82c..0000000 --- a/weblayer/browser/android/metrics/metrics_test_helper.cc +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/android/metrics/metrics_test_helper.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/no_destructor.h" -#include "content/public/test/test_utils.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/test/weblayer_browsertests_jni/MetricsTestHelper_jni.h" - -namespace weblayer { - -namespace { - -OnLogsMetricsCallback& GetOnLogMetricsCallback() { - static base::NoDestructor<OnLogsMetricsCallback> s_callback; - return *s_callback; -} - -ProfileImpl* GetProfileByName(const std::string& name) { - for (auto* profile : ProfileImpl::GetAllProfiles()) { - if (profile->name() == name) - return profile; - } - - return nullptr; -} - -} // namespace - -void InstallTestGmsBridge(ConsentType consent_type, - const OnLogsMetricsCallback on_log_metrics) { - GetOnLogMetricsCallback() = on_log_metrics; - Java_MetricsTestHelper_installTestGmsBridge( - base::android::AttachCurrentThread(), static_cast<int>(consent_type)); -} - -void RemoveTestGmsBridge() { - Java_MetricsTestHelper_removeTestGmsBridge( - base::android::AttachCurrentThread()); - GetOnLogMetricsCallback().Reset(); -} - -void RunConsentCallback(bool has_consent) { - Java_MetricsTestHelper_runConsentCallback( - base::android::AttachCurrentThread(), has_consent); -} - -ProfileImpl* CreateProfile(const std::string& name, bool incognito) { - DCHECK(!GetProfileByName(name)); - JNIEnv* env = base::android::AttachCurrentThread(); - Java_MetricsTestHelper_createProfile( - env, base::android::ConvertUTF8ToJavaString(env, name), incognito); - ProfileImpl* profile = GetProfileByName(name); - // Creating a profile may involve storage partition initialization. Wait for - // the initialization to be completed. - content::RunAllTasksUntilIdle(); - return profile; -} - -void DestroyProfile(const std::string& name, bool incognito) { - DCHECK(GetProfileByName(name)); - JNIEnv* env = base::android::AttachCurrentThread(); - Java_MetricsTestHelper_destroyProfile( - env, base::android::ConvertUTF8ToJavaString(env, name), incognito); -} - -void JNI_MetricsTestHelper_OnLogMetrics( - JNIEnv* env, - const base::android::JavaParamRef<jbyteArray>& data) { - auto& callback = GetOnLogMetricsCallback(); - if (!callback) - return; - - metrics::ChromeUserMetricsExtension proto; - jbyte* src_bytes = env->GetByteArrayElements(data, nullptr); - proto.ParseFromArray(src_bytes, env->GetArrayLength(data.obj())); - env->ReleaseByteArrayElements(data, src_bytes, JNI_ABORT); - callback.Run(proto); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/metrics/metrics_test_helper.h b/weblayer/browser/android/metrics/metrics_test_helper.h deleted file mode 100644 index 47a7c89..0000000 --- a/weblayer/browser/android/metrics/metrics_test_helper.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_METRICS_METRICS_TEST_HELPER_H_ -#define WEBLAYER_BROWSER_ANDROID_METRICS_METRICS_TEST_HELPER_H_ - -#include <string> - -#include "base/functional/callback.h" -#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" - -namespace weblayer { -class ProfileImpl; - -// Various utilities to bridge to Java code for metrics related tests. - -using OnLogsMetricsCallback = - base::RepeatingCallback<void(metrics::ChromeUserMetricsExtension)>; - -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private -// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ConsentType -enum class ConsentType { - kConsent, - kNoConsent, - // If this is supplied to InstallTestGmsBridge(), the callback used to - // determine if consent is given is not automatically called. Use - // RunConsentCallback() to apply consent. - kDelayConsent, -}; - -// Call this in the SetUp() test harness method to install the test -// GmsBridge and to set the metrics user consent state. -void InstallTestGmsBridge( - ConsentType consent_type, - const OnLogsMetricsCallback on_log_metrics = OnLogsMetricsCallback()); - -// Call this in the TearDown() test harness method to remove the GmsBridge. -void RemoveTestGmsBridge(); - -// See comment for kDelayConsent. -void RunConsentCallback(bool has_consent); - -ProfileImpl* CreateProfile(const std::string& name, bool incognito = false); - -void DestroyProfile(const std::string& name, bool incognito = false); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_METRICS_METRICS_TEST_HELPER_H_
diff --git a/weblayer/browser/android/metrics/ukm_browsertest.cc b/weblayer/browser/android/metrics/ukm_browsertest.cc deleted file mode 100644 index 30b7dc14..0000000 --- a/weblayer/browser/android/metrics/ukm_browsertest.cc +++ /dev/null
@@ -1,150 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/test/bind.h" -#include "components/ukm/ukm_test_helper.h" -#include "weblayer/browser/android/metrics/metrics_test_helper.h" -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" - -namespace weblayer { - -class UkmBrowserTest : public WebLayerBrowserTest { - public: - void SetUp() override { - InstallTestGmsBridge(user_consent_ ? ConsentType::kConsent - : ConsentType::kNoConsent); - - WebLayerBrowserTest::SetUp(); - } - - void TearDown() override { - RemoveTestGmsBridge(); - WebLayerBrowserTest::TearDown(); - } - - ukm::UkmService* GetUkmService() { - return WebLayerMetricsServiceClient::GetInstance()->GetUkmService(); - } - - void disable_user_consent() { user_consent_ = false; } - - private: - bool user_consent_ = true; -}; - -// Even if there's user consent for UMA, need to explicitly enable UKM. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, UserConsentButNotEnabled) { - ukm::UkmTestHelper ukm_test_helper(GetUkmService()); - - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); -} - -// UKMs are only enabled when there's user consent and it's explicitly enabled. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, DISABLED_Enabled) { - ukm::UkmTestHelper ukm_test_helper(GetUkmService()); - - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); - EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled()); -} - -// If UKMs are disabled it's reflected accordingly. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, DISABLED_EnabledThenDisable) { - ukm::UkmTestHelper ukm_test_helper(GetUkmService()); - - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); - EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled()); - uint64_t original_client_id = ukm_test_helper.GetClientId(); - EXPECT_NE(0U, original_client_id); - - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, false); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - // Client ID should have been reset. - EXPECT_NE(original_client_id, ukm_test_helper.GetClientId()); -} - -// Make sure that UKM is disabled while an incognito profile is alive. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, DISABLED_RegularPlusIncognitoCheck) { - ukm::UkmTestHelper ukm_test_helper(GetUkmService()); - - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); - EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled()); - uint64_t original_client_id = ukm_test_helper.GetClientId(); - EXPECT_NE(0U, original_client_id); - - CreateProfile(std::string(), true); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - - // Creating another regular profile mustn't enable UKM. - auto* profile = CreateProfile("foo"); - profile->SetBooleanSetting(SettingType::UKM_ENABLED, true); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - - // Opening and closing another Incognito browser mustn't enable UKM. - CreateProfile("bar", true); - DestroyProfile("bar", true); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - - DestroyProfile("foo"); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - - DestroyProfile(std::string(), true); - EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled()); - // Client ID should not have been reset. - EXPECT_EQ(original_client_id, ukm_test_helper.GetClientId()); -} - -// Make sure creating a real profile after Incognito doesn't enable UKM. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, DISABLED_IncognitoPlusRegularCheck) { - ukm::UkmTestHelper ukm_test_helper(GetUkmService()); - - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); - - CreateProfile(std::string(), true); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - - auto* profile = CreateProfile("foo"); - profile->SetBooleanSetting(SettingType::UKM_ENABLED, true); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - - DestroyProfile(std::string(), true); - EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled()); -} - -class UkmDisabledBrowserTest : public UkmBrowserTest { - public: - UkmDisabledBrowserTest() { disable_user_consent(); } -}; - -// If there's no user consent UKMs are disabled. -IN_PROC_BROWSER_TEST_F(UkmDisabledBrowserTest, Disabled) { - ukm::UkmTestHelper ukm_test_helper(GetUkmService()); - - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); - - // Ensure enabling UKMs still doesn't enable it. - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); -} - -class UkmIncognitoBrowserTest : public UkmBrowserTest { - public: - UkmIncognitoBrowserTest() { SetShellStartsInIncognitoMode(); } -}; - -// Starting with one incognito window should disable UKM. -IN_PROC_BROWSER_TEST_F(UkmIncognitoBrowserTest, Disabled) { - ukm::UkmTestHelper ukm_test_helper(GetUkmService()); - - // Enabling UKMs doesn't enable it because of the incognito window. - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); - - EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/metrics/uma_utils.cc b/weblayer/browser/android/metrics/uma_utils.cc deleted file mode 100644 index cedfd89..0000000 --- a/weblayer/browser/android/metrics/uma_utils.cc +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/android/metrics/uma_utils.h" - -#include <stdint.h> - -#include "components/metrics/metrics_reporting_default_state.h" -#include "weblayer/browser/java/jni/UmaUtils_jni.h" - -using base::android::JavaParamRef; - -class PrefService; - -namespace weblayer { - -base::TimeTicks GetApplicationStartTime() { - JNIEnv* env = base::android::AttachCurrentThread(); - return base::TimeTicks::FromUptimeMillis( - Java_UmaUtils_getApplicationStartTime(env)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/metrics/uma_utils.h b/weblayer/browser/android/metrics/uma_utils.h deleted file mode 100644 index 59d4da9..0000000 --- a/weblayer/browser/android/metrics/uma_utils.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_METRICS_UMA_UTILS_H_ -#define WEBLAYER_BROWSER_ANDROID_METRICS_UMA_UTILS_H_ - -#include "base/time/time.h" - -namespace weblayer { - -base::TimeTicks GetApplicationStartTime(); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_METRICS_UMA_UTILS_H_
diff --git a/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc b/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc deleted file mode 100644 index f21298a8..0000000 --- a/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc +++ /dev/null
@@ -1,244 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" - -#include <jni.h> -#include <cstdint> -#include <memory> - -#include "base/base64.h" -#include "base/no_destructor.h" -#include "components/metrics/metrics_provider.h" -#include "components/metrics/metrics_service.h" -#include "components/page_load_metrics/browser/metrics_web_contents_observer.h" -#include "components/prefs/pref_service.h" -#include "components/ukm/ukm_service.h" -#include "components/variations/variations_ids_provider.h" -#include "components/version_info/android/channel_getter.h" -#include "content/public/browser/browser_context.h" -#include "google_apis/google_api_keys.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_fragment_list.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/java/jni/MetricsServiceClient_jni.h" -#include "weblayer/browser/system_network_context_manager.h" -#include "weblayer/browser/tab_impl.h" - -namespace weblayer { -namespace { - -// IMPORTANT: DO NOT CHANGE sample rates without first ensuring the Chrome -// Metrics team has the appropriate backend bandwidth and storage. - -// Sample at 10%, which is the same as chrome. -const int kStableSampledInRatePerMille = 100; - -// Sample non-stable channels at 99%, to boost volume for pre-stable -// experiments. We choose 99% instead of 100% for consistency with Chrome and to -// exercise the out-of-sample code path. -const int kBetaDevCanarySampledInRatePerMille = 990; - -// As a mitigation to preserve user privacy, the privacy team has asked that we -// upload package name with no more than 10% of UMA records. This is to mitigate -// fingerprinting for users on low-usage applications (if an app only has a -// a small handful of users, there's a very good chance many of them won't be -// uploading UMA records due to sampling). Do not change this constant without -// consulting with the privacy team. -const int kPackageNameLimitRatePerMille = 100; - -// MetricsProvider that interfaces with page_load_metrics. -class PageLoadMetricsProvider : public metrics::MetricsProvider { - public: - PageLoadMetricsProvider() = default; - - PageLoadMetricsProvider(const PageLoadMetricsProvider&) = delete; - PageLoadMetricsProvider& operator=(const PageLoadMetricsProvider&) = delete; - - ~PageLoadMetricsProvider() override = default; - - // metrics:MetricsProvider implementation: - void OnAppEnterBackground() override { - auto tabs = TabImpl::GetAllTabImpl(); - for (auto* tab : tabs) { - page_load_metrics::MetricsWebContentsObserver* observer = - page_load_metrics::MetricsWebContentsObserver::FromWebContents( - tab->web_contents()); - if (observer) - observer->FlushMetricsOnAppEnterBackground(); - } - } -}; - -} // namespace - -// static -WebLayerMetricsServiceClient* WebLayerMetricsServiceClient::GetInstance() { - static base::NoDestructor<WebLayerMetricsServiceClient> client; - client->EnsureOnValidSequence(); - return client.get(); -} - -WebLayerMetricsServiceClient::WebLayerMetricsServiceClient() { - ProfileImpl::AddProfileObserver(this); - BrowserFragmentList::GetInstance()->AddObserver(this); -} - -WebLayerMetricsServiceClient::~WebLayerMetricsServiceClient() { - BrowserFragmentList::GetInstance()->RemoveObserver(this); - ProfileImpl::RemoveProfileObserver(this); -} - -void WebLayerMetricsServiceClient::RegisterExternalExperiments( - const std::vector<int>& experiment_ids) { - if (!GetMetricsService()) { - if (!IsConsentDetermined()) { - post_start_tasks_.push_back(base::BindOnce( - &WebLayerMetricsServiceClient::RegisterExternalExperiments, - base::Unretained(this), experiment_ids)); - } - return; - } - - GetMetricsService()->GetSyntheticTrialRegistry()->RegisterExternalExperiments( - "WebLayerExperiments", experiment_ids, - variations::SyntheticTrialRegistry::kOverrideExistingIds); -} - -int32_t WebLayerMetricsServiceClient::GetProduct() { - return metrics::ChromeUserMetricsExtension::ANDROID_WEBLAYER; -} - -bool WebLayerMetricsServiceClient::IsExternalExperimentAllowlistEnabled() { - // RegisterExternalExperiments() is actually used to register experiment ids - // coming from the app embedding WebLayer itself, rather than externally. So - // the allowlist shouldn't be applied. - return false; -} - -bool WebLayerMetricsServiceClient::IsUkmAllowedForAllProfiles() { - for (auto* profile : ProfileImpl::GetAllProfiles()) { - if (!profile->GetBooleanSetting(SettingType::UKM_ENABLED)) - return false; - } - return true; -} - -std::string WebLayerMetricsServiceClient::GetUploadSigningKey() { - std::string decoded_key; - base::Base64Decode(google_apis::GetMetricsKey(), &decoded_key); - return decoded_key; -} - -const network_time::NetworkTimeTracker* -WebLayerMetricsServiceClient::GetNetworkTimeTracker() { - return BrowserProcess::GetInstance()->GetNetworkTimeTracker(); -} - -int WebLayerMetricsServiceClient::GetSampleRatePerMille() const { - version_info::Channel channel = version_info::android::GetChannel(); - if (channel == version_info::Channel::STABLE || - channel == version_info::Channel::UNKNOWN) { - return kStableSampledInRatePerMille; - } - return kBetaDevCanarySampledInRatePerMille; -} - -void WebLayerMetricsServiceClient::OnMetricsStart() { - for (auto& task : post_start_tasks_) { - std::move(task).Run(); - } - post_start_tasks_.clear(); -} - -void WebLayerMetricsServiceClient::OnMetricsNotStarted() { - post_start_tasks_.clear(); -} - -int WebLayerMetricsServiceClient::GetPackageNameLimitRatePerMille() { - return kPackageNameLimitRatePerMille; -} - -void WebLayerMetricsServiceClient::RegisterAdditionalMetricsProviders( - metrics::MetricsService* service) { - service->RegisterMetricsProvider(std::make_unique<PageLoadMetricsProvider>()); -} - -bool WebLayerMetricsServiceClient::IsOffTheRecordSessionActive() { - for (auto* profile : ProfileImpl::GetAllProfiles()) { - if (profile->GetBrowserContext()->IsOffTheRecord()) - return true; - } - - return false; -} - -scoped_refptr<network::SharedURLLoaderFactory> -WebLayerMetricsServiceClient::GetURLLoaderFactory() { - return SystemNetworkContextManager::GetInstance() - ->GetSharedURLLoaderFactory(); -} - -void WebLayerMetricsServiceClient::ApplyConsent(bool user_consent, - bool app_consent) { - // TODO(https://crbug.com/1155163): update this once consent can be - // dynamically changed. - // It is expected this function is called only once, and that prior to this - // function the metrics service has not been started. The reason the metric - // service should not have been started prior to this function is that the - // metrics service is only started if consent is given, and this function is - // responsible for setting consent. - DCHECK(!GetMetricsServiceIfStarted()); - // UkmService is only created if consent is given. - DCHECK(!GetUkmService()); - - SetHaveMetricsConsent(user_consent, app_consent); - ApplyForegroundStateToServices(); -} - -void WebLayerMetricsServiceClient::ApplyForegroundStateToServices() { - const bool is_in_foreground = - BrowserFragmentList::GetInstance()->HasAtLeastOneResumedBrowser(); - if (auto* metrics_service = WebLayerMetricsServiceClient::GetInstance() - ->GetMetricsServiceIfStarted()) { - if (is_in_foreground) - metrics_service->OnAppEnterForeground(); - else - metrics_service->OnAppEnterBackground(); - } - - if (auto* ukm_service = GetUkmService()) { - if (is_in_foreground) - ukm_service->OnAppEnterForeground(); - else - ukm_service->OnAppEnterBackground(); - } -} - -void WebLayerMetricsServiceClient::ProfileCreated(ProfileImpl* profile) { - UpdateUkmService(); -} - -void WebLayerMetricsServiceClient::ProfileDestroyed(ProfileImpl* profile) { - UpdateUkmService(); -} - -void WebLayerMetricsServiceClient:: - OnHasAtLeastOneResumedBrowserFragmentStateChanged(bool new_value) { - ApplyForegroundStateToServices(); -} - -void JNI_ApplyConsentHelper(bool user_consent, bool app_consent) { - WebLayerMetricsServiceClient::GetInstance()->ApplyConsent(user_consent, - app_consent); -} - -// static -void JNI_MetricsServiceClient_SetHaveMetricsConsent(JNIEnv* env, - jboolean user_consent, - jboolean app_consent) { - JNI_ApplyConsentHelper(user_consent, app_consent); -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/metrics/weblayer_metrics_service_client.h b/weblayer/browser/android/metrics/weblayer_metrics_service_client.h deleted file mode 100644 index da8469b..0000000 --- a/weblayer/browser/android/metrics/weblayer_metrics_service_client.h +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_METRICS_WEBLAYER_METRICS_SERVICE_CLIENT_H_ -#define WEBLAYER_BROWSER_ANDROID_METRICS_WEBLAYER_METRICS_SERVICE_CLIENT_H_ - -#include <memory> -#include <string> - -#include "base/metrics/field_trial.h" -#include "base/no_destructor.h" -#include "base/sequence_checker.h" -#include "components/embedder_support/android/metrics/android_metrics_service_client.h" -#include "components/metrics/metrics_log_uploader.h" -#include "components/metrics/metrics_service_client.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "weblayer/browser/browser_fragment_list_observer.h" -#include "weblayer/browser/profile_impl.h" - -namespace weblayer { - -class WebLayerMetricsServiceClient - : public ::metrics::AndroidMetricsServiceClient, - public ProfileImpl::ProfileObserver, - public BrowserFragmentListObserver { - friend class base::NoDestructor<WebLayerMetricsServiceClient>; - - public: - static WebLayerMetricsServiceClient* GetInstance(); - - WebLayerMetricsServiceClient(); - - WebLayerMetricsServiceClient(const WebLayerMetricsServiceClient&) = delete; - WebLayerMetricsServiceClient& operator=(const WebLayerMetricsServiceClient&) = - delete; - - ~WebLayerMetricsServiceClient() override; - - void RegisterExternalExperiments(const std::vector<int>& experiment_ids); - - // metrics::MetricsServiceClient - int32_t GetProduct() override; - bool IsExternalExperimentAllowlistEnabled() override; - bool IsUkmAllowedForAllProfiles() override; - std::string GetUploadSigningKey() override; - - // metrics::AndroidMetricsServiceClient: - const network_time::NetworkTimeTracker* GetNetworkTimeTracker() override; - int GetSampleRatePerMille() const override; - void OnMetricsStart() override; - void OnMetricsNotStarted() override; - int GetPackageNameLimitRatePerMille() override; - void RegisterAdditionalMetricsProviders( - metrics::MetricsService* service) override; - bool IsOffTheRecordSessionActive() override; - scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; - - private: - friend void JNI_ApplyConsentHelper(bool user_consent, bool app_consent); - - // Called once when consent has been determined. - void ApplyConsent(bool user_consent, bool app_consent); - - // Updates the services based on the foreground state. - void ApplyForegroundStateToServices(); - - // ProfileImpl::ProfileObserver: - void ProfileCreated(ProfileImpl* profile) override; - void ProfileDestroyed(ProfileImpl* profile) override; - - // BrowserListObserver: - void OnHasAtLeastOneResumedBrowserFragmentStateChanged( - bool new_value) override; - - std::vector<base::OnceClosure> post_start_tasks_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_METRICS_WEBLAYER_METRICS_SERVICE_CLIENT_H_
diff --git a/weblayer/browser/android/permission_request_utils.cc b/weblayer/browser/android/permission_request_utils.cc deleted file mode 100644 index e3f1865..0000000 --- a/weblayer/browser/android/permission_request_utils.cc +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/android/permission_request_utils.h" - -#include <algorithm> - -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "content/public/browser/web_contents.h" -#include "ui/android/window_android.h" -#include "weblayer/browser/java/jni/PermissionRequestUtils_jni.h" - -namespace weblayer { - -void RequestAndroidPermissions( - content::WebContents* web_contents, - const std::vector<ContentSettingsType>& content_settings_types, - PermissionsUpdatedCallback callback) { - if (!web_contents) { - std::move(callback).Run(false); - return; - } - - auto* window = web_contents->GetTopLevelNativeWindow(); - if (!window) { - std::move(callback).Run(false); - return; - } - - std::vector<int> content_settings_ints; - for (auto type : content_settings_types) - content_settings_ints.push_back(static_cast<int>(type)); - - // The callback allocated here will be deleted in the call to OnResult, which - // is guaranteed to be called. - Java_PermissionRequestUtils_requestPermission( - base::android::AttachCurrentThread(), window->GetJavaObject(), - reinterpret_cast<jlong>( - new PermissionsUpdatedCallback(std::move(callback))), - base::android::ToJavaIntArray(base::android::AttachCurrentThread(), - content_settings_ints)); -} - -void JNI_PermissionRequestUtils_OnResult(JNIEnv* env, - jlong callback_ptr, - jboolean result) { - auto* callback = reinterpret_cast<PermissionsUpdatedCallback*>(callback_ptr); - std::move(*callback).Run(result); - delete callback; -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/permission_request_utils.h b/weblayer/browser/android/permission_request_utils.h deleted file mode 100644 index ed65c8f18..0000000 --- a/weblayer/browser/android/permission_request_utils.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_PERMISSION_REQUEST_UTILS_H_ -#define WEBLAYER_BROWSER_ANDROID_PERMISSION_REQUEST_UTILS_H_ - -#include <vector> - -#include "base/functional/callback_forward.h" -#include "components/content_settings/core/common/content_settings_types.h" - -namespace content { -class WebContents; -} - -namespace weblayer { - -using PermissionsUpdatedCallback = base::OnceCallback<void(bool)>; - -// Requests all necessary Android permissions related to -// |content_settings_types|, and calls |callback|. |callback| will be called -// with true if all permissions were successfully granted, and false otherwise. -void RequestAndroidPermissions( - content::WebContents* web_contents, - const std::vector<ContentSettingsType>& content_settings_type, - PermissionsUpdatedCallback callback); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_PERMISSION_REQUEST_UTILS_H_
diff --git a/weblayer/browser/android/resource_mapper.cc b/weblayer/browser/android/resource_mapper.cc deleted file mode 100644 index d4a9f323..0000000 --- a/weblayer/browser/android/resource_mapper.cc +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/android/resource_mapper.h" - -#include <map> - -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/check_op.h" -#include "base/no_destructor.h" -#include "base/notreached.h" -#include "components/resources/android/theme_resources.h" -#include "weblayer/browser/java/jni/ResourceMapper_jni.h" - -namespace weblayer { -namespace { -using ResourceMap = std::map<int, int>; - -ResourceMap* GetIdMap() { - static base::NoDestructor<ResourceMap> id_map; - return id_map.get(); -} - -// Create the mapping. IDs start at 0 to correspond to the array that gets -// built in the corresponding ResourceID Java class. -void ConstructMap() { - DCHECK(GetIdMap()->empty()); - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jintArray> java_id_array = - Java_ResourceMapper_getResourceIdList(env); - std::vector<int> resource_id_list; - base::android::JavaIntArrayToIntVector(env, java_id_array, &resource_id_list); - size_t next_id = 0; - -#define LINK_RESOURCE_ID(c_id, java_id) \ - (*GetIdMap())[c_id] = resource_id_list[next_id++]; -#define DECLARE_RESOURCE_ID(c_id, java_id) \ - (*GetIdMap())[c_id] = resource_id_list[next_id++]; -#include "components/resources/android/blocked_content_resource_id.h" -#include "components/resources/android/page_info_resource_id.h" -#include "components/resources/android/permissions_resource_id.h" -#include "components/resources/android/sms_resource_id.h" -#include "components/resources/android/webxr_resource_id.h" -#undef LINK_RESOURCE_ID -#undef DECLARE_RESOURCE_ID - // Make sure ID list sizes match up. - DCHECK_EQ(next_id, resource_id_list.size()); -} - -} // namespace - -int MapToJavaDrawableId(int resource_id) { - if (GetIdMap()->empty()) { - ConstructMap(); - } - - ResourceMap::iterator iterator = GetIdMap()->find(resource_id); - if (iterator != GetIdMap()->end()) { - return iterator->second; - } - - // The resource couldn't be found. - // If you've landed here, please ensure that the header that declares the - // mapping of your native resource to Java resource is listed both in - // ResourceId.tempalate and in this file, next to other *resource_id.h - // headers. - NOTREACHED(); - return 0; -} - -} // namespace weblayer
diff --git a/weblayer/browser/android/resource_mapper.h b/weblayer/browser/android/resource_mapper.h deleted file mode 100644 index 24cd3e8a..0000000 --- a/weblayer/browser/android/resource_mapper.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_RESOURCE_MAPPER_H_ -#define WEBLAYER_BROWSER_ANDROID_RESOURCE_MAPPER_H_ - -namespace weblayer { - -// Converts the given chromium |resource_id| (e.g. IDR_INFOBAR_TRANSLATE) to -// an Android drawable resource ID. Returns 0 if a mapping wasn't found. -int MapToJavaDrawableId(int resource_id); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_RESOURCE_MAPPER_H_
diff --git a/weblayer/browser/android_descriptors.h b/weblayer/browser/android_descriptors.h deleted file mode 100644 index 48a03c17..0000000 --- a/weblayer/browser/android_descriptors.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ANDROID_DESCRIPTORS_H_ -#define WEBLAYER_BROWSER_ANDROID_DESCRIPTORS_H_ - -#include "content/public/common/content_descriptors.h" - -namespace weblayer { - -// This is a list of global descriptor keys to be used with the -// base::GlobalDescriptors object (see base/posix/global_descriptors.h) -enum { - kWebLayerLocalePakDescriptor = kContentIPCDescriptorMax + 1, - kWebLayerMainPakDescriptor, - kWebLayer100PercentPakDescriptor, - kWebLayerSecondaryLocalePakDescriptor, -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ANDROID_DESCRIPTORS_H_
diff --git a/weblayer/browser/autocomplete_scheme_classifier_impl.cc b/weblayer/browser/autocomplete_scheme_classifier_impl.cc deleted file mode 100644 index 3098046..0000000 --- a/weblayer/browser/autocomplete_scheme_classifier_impl.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/autocomplete_scheme_classifier_impl.h" - -#include "base/strings/string_util.h" -#include "build/build_config.h" -#include "content/public/common/url_constants.h" -#include "third_party/metrics_proto/omnibox_input_type.pb.h" -#include "url/url_constants.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/java/jni/AutocompleteSchemeClassifierImpl_jni.h" -#endif - -namespace weblayer { - -#if BUILDFLAG(IS_ANDROID) -static jlong JNI_AutocompleteSchemeClassifierImpl_CreateAutocompleteClassifier( - JNIEnv* env) { - return reinterpret_cast<intptr_t>(new AutocompleteSchemeClassifierImpl()); -} - -static void JNI_AutocompleteSchemeClassifierImpl_DeleteAutocompleteClassifier( - JNIEnv* env, - jlong autocomplete_scheme_classifier_impl) { - delete reinterpret_cast<AutocompleteSchemeClassifierImpl*>( - autocomplete_scheme_classifier_impl); -} -#endif - -metrics::OmniboxInputType -AutocompleteSchemeClassifierImpl::GetInputTypeForScheme( - const std::string& scheme) const { - DCHECK_EQ(scheme, base::ToLowerASCII(scheme)); - - // Check against an allowlist of schemes. - const char* kKnownURLSchemes[] = { - url::kHttpScheme, url::kHttpsScheme, - url::kWsScheme, url::kWssScheme, - url::kFileScheme, url::kAboutScheme, - url::kFtpScheme, url::kBlobScheme, - url::kFileSystemScheme, content::kViewSourceScheme, - url::kJavaScriptScheme}; - - for (const char* known_scheme : kKnownURLSchemes) { - if (scheme == known_scheme) - return metrics::OmniboxInputType::URL; - } - - return metrics::OmniboxInputType::EMPTY; -} - -} // namespace weblayer \ No newline at end of file
diff --git a/weblayer/browser/autocomplete_scheme_classifier_impl.h b/weblayer/browser/autocomplete_scheme_classifier_impl.h deleted file mode 100644 index 2f5c0ec..0000000 --- a/weblayer/browser/autocomplete_scheme_classifier_impl.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_ -#define WEBLAYER_BROWSER_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_ - -#include "components/omnibox/browser/autocomplete_scheme_classifier.h" - -namespace weblayer { -class AutocompleteSchemeClassifierImpl : public AutocompleteSchemeClassifier { - public: - AutocompleteSchemeClassifierImpl() = default; - // AutocompleteInputSchemeChecker: - metrics::OmniboxInputType GetInputTypeForScheme( - const std::string& scheme) const override; - ~AutocompleteSchemeClassifierImpl() override = default; - AutocompleteSchemeClassifierImpl(const AutocompleteSchemeClassifierImpl&) = - delete; - AutocompleteSchemeClassifierImpl& operator=( - const AutocompleteSchemeClassifierImpl&) = delete; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_ \ No newline at end of file
diff --git a/weblayer/browser/autofill_browsertest.cc b/weblayer/browser/autofill_browsertest.cc deleted file mode 100644 index 684d739..0000000 --- a/weblayer/browser/autofill_browsertest.cc +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "components/autofill/core/common/form_data.h" -#include "components/autofill/core/common/form_field_data.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -// Method that is passed to the autofill system to be invoked on detection of -// autofill forms. -// NOTE: This method can currently be invoked only once within the context of -// a given test. If that restriction ever needs to be relaxed, it could be -// done by changing |quit_closure| to a global that could be reset between -// expected invocations of the method. -void OnReceivedFormDataFromRenderer(base::OnceClosure quit_closure, - autofill::FormData* output, - const autofill::FormData& form) { - ASSERT_TRUE(quit_closure); - - *output = form; - std::move(quit_closure).Run(); -} - -} // namespace - -// Cross-platform tests of autofill parsing in the renderer and communication -// to the browser. Does not test integration with any platform's underlying -// system autofill mechanisms. -class AutofillBrowserTest : public WebLayerBrowserTest { - public: - AutofillBrowserTest() = default; - - AutofillBrowserTest(const AutofillBrowserTest&) = delete; - AutofillBrowserTest& operator=(const AutofillBrowserTest&) = delete; - - ~AutofillBrowserTest() override = default; - - void SetUp() override { -#if BUILDFLAG(IS_ANDROID) - TabImpl::DisableAutofillSystemIntegrationForTesting(); -#endif - - WebLayerBrowserTest::SetUp(); - } -}; - -// Tests that the renderer detects a password form and passes the appropriate -// data to the browser. -IN_PROC_BROWSER_TEST_F(AutofillBrowserTest, TestPasswordFormDetection) { - ASSERT_TRUE(embedded_test_server()->Start()); - - base::RunLoop run_loop; - autofill::FormData observed_form; - - InitializeAutofillWithEventForwarding( - shell(), base::BindRepeating(&OnReceivedFormDataFromRenderer, - run_loop.QuitClosure(), &observed_form)); - - GURL password_form_url = - embedded_test_server()->GetURL("/simple_password_form.html"); - NavigateAndWaitForCompletion(password_form_url, shell()); - - // Focus the username field (note that a user gesture is necessary for - // autofill to trigger) ... - ExecuteScriptWithUserGesture( - shell(), "document.getElementById('username_field').focus();"); - - // ... and wait for the parsed data to be passed to the browser. - run_loop.Run(); - - // Verify that that the form data matches that of the document. - EXPECT_EQ(u"testform", observed_form.name); - EXPECT_EQ(password_form_url.spec(), observed_form.url); - - auto fields = observed_form.fields; - EXPECT_EQ(2u, fields.size()); - autofill::FormFieldData username_field = fields[0]; - EXPECT_EQ(u"username_field", username_field.name); - autofill::FormFieldData password_field = fields[1]; - EXPECT_EQ(u"password_field", password_field.name); -} - -} // namespace weblayer
diff --git a/weblayer/browser/autofill_client_impl.cc b/weblayer/browser/autofill_client_impl.cc deleted file mode 100644 index decc720..0000000 --- a/weblayer/browser/autofill_client_impl.cc +++ /dev/null
@@ -1,417 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/autofill_client_impl.h" - -#include <utility> - -#include "build/build_config.h" -#include "components/autofill/core/browser/autofill_download_manager.h" -#include "components/autofill/core/browser/data_model/autofill_profile.h" -#include "components/autofill/core/browser/ui/popup_item_ids.h" -#include "components/autofill/core/browser/ui/suggestion.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/ssl_status.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_contents.h" -#include "services/metrics/public/cpp/ukm_recorder.h" -#include "weblayer/browser/translate_client_impl.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/android_autofill/browser/android_autofill_manager.h" -#else -#include "weblayer/browser/i18n_util.h" -#endif - -namespace weblayer { - -AutofillClientImpl::~AutofillClientImpl() = default; - -bool AutofillClientImpl::IsOffTheRecord() { - return web_contents()->GetBrowserContext()->IsOffTheRecord(); -} - -scoped_refptr<network::SharedURLLoaderFactory> -AutofillClientImpl::GetURLLoaderFactory() { - return web_contents() - ->GetBrowserContext() - ->GetDefaultStoragePartition() - ->GetURLLoaderFactoryForBrowserProcess(); -} - -autofill::AutofillDownloadManager* AutofillClientImpl::GetDownloadManager() { - if (!download_manager_) { - // Lazy initialization to avoid virtual function calls in the constructor. - download_manager_ = std::make_unique<autofill::AutofillDownloadManager>( - this, GetChannel(), GetLogManager()); - } - return download_manager_.get(); -} - -autofill::PersonalDataManager* AutofillClientImpl::GetPersonalDataManager() { - NOTREACHED(); - return nullptr; -} - -autofill::AutocompleteHistoryManager* -AutofillClientImpl::GetAutocompleteHistoryManager() { - NOTREACHED(); - return nullptr; -} - -PrefService* AutofillClientImpl::GetPrefs() { - return const_cast<PrefService*>(std::as_const(*this).GetPrefs()); -} - -const PrefService* AutofillClientImpl::GetPrefs() const { - NOTREACHED(); - return nullptr; -} - -syncer::SyncService* AutofillClientImpl::GetSyncService() { - NOTREACHED(); - return nullptr; -} - -signin::IdentityManager* AutofillClientImpl::GetIdentityManager() { - NOTREACHED(); - return nullptr; -} - -autofill::FormDataImporter* AutofillClientImpl::GetFormDataImporter() { - NOTREACHED(); - return nullptr; -} - -autofill::payments::PaymentsClient* AutofillClientImpl::GetPaymentsClient() { - NOTREACHED(); - return nullptr; -} - -autofill::StrikeDatabase* AutofillClientImpl::GetStrikeDatabase() { - NOTREACHED(); - return nullptr; -} - -ukm::UkmRecorder* AutofillClientImpl::GetUkmRecorder() { - // TODO(crbug.com/1181141): Enable the autofill UKM. - return nullptr; -} - -ukm::SourceId AutofillClientImpl::GetUkmSourceId() { - // TODO(crbug.com/1181141): Enable the autofill UKM. - return ukm::kInvalidSourceId; -} - -autofill::AddressNormalizer* AutofillClientImpl::GetAddressNormalizer() { - NOTREACHED(); - return nullptr; -} - -const GURL& AutofillClientImpl::GetLastCommittedPrimaryMainFrameURL() const { - NOTREACHED(); - return GURL::EmptyGURL(); -} - -url::Origin AutofillClientImpl::GetLastCommittedPrimaryMainFrameOrigin() const { - NOTREACHED(); - return url::Origin(); -} - -security_state::SecurityLevel -AutofillClientImpl::GetSecurityLevelForUmaHistograms() { - NOTREACHED(); - return security_state::SecurityLevel::SECURITY_LEVEL_COUNT; -} - -const translate::LanguageState* AutofillClientImpl::GetLanguageState() { - return nullptr; -} - -translate::TranslateDriver* AutofillClientImpl::GetTranslateDriver() { - // The TranslateDriver is used by AutofillManager to observe the page language - // and run the type-prediction heuristics with language-dependent regexps. - auto* translate_client = TranslateClientImpl::FromWebContents(web_contents()); - if (translate_client) - return translate_client->translate_driver(); - return nullptr; -} - -void AutofillClientImpl::ShowAutofillSettings(autofill::PopupType popup_type) { - NOTREACHED(); -} - -void AutofillClientImpl::ShowUnmaskPrompt( - const autofill::CreditCard& card, - const autofill::CardUnmaskPromptOptions& card_unmask_prompt_options, - base::WeakPtr<autofill::CardUnmaskDelegate> delegate) { - NOTREACHED(); -} - -void AutofillClientImpl::OnUnmaskVerificationResult(PaymentsRpcResult result) { - NOTREACHED(); -} - -#if !BUILDFLAG(IS_ANDROID) -std::vector<std::string> -AutofillClientImpl::GetAllowedMerchantsForVirtualCards() { - NOTREACHED(); - return std::vector<std::string>(); -} - -std::vector<std::string> -AutofillClientImpl::GetAllowedBinRangesForVirtualCards() { - NOTREACHED(); - return std::vector<std::string>(); -} - -void AutofillClientImpl::ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure) { - NOTREACHED(); -} - -void AutofillClientImpl::ConfirmMigrateLocalCardToCloud( - const autofill::LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<autofill::MigratableCreditCard>& migratable_credit_cards, - LocalCardMigrationCallback start_migrating_cards_callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ShowLocalCardMigrationResults( - const bool has_server_error, - const std::u16string& tip_message, - const std::vector<autofill::MigratableCreditCard>& migratable_credit_cards, - MigrationDeleteCardCallback delete_local_card_callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ConfirmSaveIBANLocally( - const autofill::IBAN& iban, - bool should_show_prompt, - LocalSaveIBANPromptCallback callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ShowWebauthnOfferDialog( - WebauthnDialogCallback offer_dialog_callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ShowWebauthnVerifyPendingDialog( - WebauthnDialogCallback verify_pending_dialog_callback) { - NOTREACHED(); -} - -void AutofillClientImpl::UpdateWebauthnOfferDialogWithError() { - NOTREACHED(); -} - -bool AutofillClientImpl::CloseWebauthnDialog() { - NOTREACHED(); - return false; -} - -void AutofillClientImpl::ConfirmSaveUpiIdLocally( - const std::string& upi_id, - base::OnceCallback<void(bool user_decision)> callback) { - NOTREACHED(); -} - -void AutofillClientImpl::OfferVirtualCardOptions( - const std::vector<autofill::CreditCard*>& candidates, - base::OnceCallback<void(const std::string&)> callback) { - NOTREACHED(); -} - -#else // !BUILDFLAG(IS_ANDROID) -void AutofillClientImpl::ConfirmAccountNameFixFlow( - base::OnceCallback<void(const std::u16string&)> callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ConfirmExpirationDateFixFlow( - const autofill::CreditCard& card, - base::OnceCallback<void(const std::u16string&, const std::u16string&)> - callback) { - NOTREACHED(); -} -#endif - -void AutofillClientImpl::ConfirmSaveCreditCardLocally( - const autofill::CreditCard& card, - SaveCreditCardOptions options, - LocalSaveCardPromptCallback callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ConfirmSaveCreditCardToCloud( - const autofill::CreditCard& card, - const autofill::LegalMessageLines& legal_message_lines, - SaveCreditCardOptions options, - UploadSaveCardPromptCallback callback) { - NOTREACHED(); -} - -void AutofillClientImpl::CreditCardUploadCompleted(bool card_saved) { - NOTREACHED(); -} - -void AutofillClientImpl::ConfirmCreditCardFillAssist( - const autofill::CreditCard& card, - base::OnceClosure callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ConfirmSaveAddressProfile( - const autofill::AutofillProfile& profile, - const autofill::AutofillProfile* original_profile, - SaveAddressProfilePromptOptions options, - AddressProfileSavePromptCallback callback) { - NOTREACHED(); -} - -void AutofillClientImpl::ShowEditAddressProfileDialog( - const AutofillProfile& profile) { - NOTREACHED_NORETURN(); -} - -void AutofillClientImpl::ShowDeleteAddressProfileDialog() { - NOTREACHED_NORETURN(); -} - -bool AutofillClientImpl::HasCreditCardScanFeature() { - NOTREACHED(); - return false; -} - -void AutofillClientImpl::ScanCreditCard(CreditCardScanCallback callback) { - NOTREACHED(); -} - -bool AutofillClientImpl::IsTouchToFillCreditCardSupported() { - return false; -} - -bool AutofillClientImpl::ShowTouchToFillCreditCard( - base::WeakPtr<autofill::TouchToFillDelegate> delegate, - base::span<const autofill::CreditCard> cards_to_suggest) { - NOTREACHED(); - return false; -} - -void AutofillClientImpl::HideTouchToFillCreditCard() { - NOTREACHED(); -} - -void AutofillClientImpl::ShowAutofillPopup( - const autofill::AutofillClient::PopupOpenArgs& open_args, - base::WeakPtr<autofill::AutofillPopupDelegate> delegate) { - NOTREACHED(); -} - -void AutofillClientImpl::UpdateAutofillPopupDataListValues( - const std::vector<std::u16string>& values, - const std::vector<std::u16string>& labels) { - NOTREACHED(); -} - -void AutofillClientImpl::HideAutofillPopup(autofill::PopupHidingReason reason) { - // This is invoked on the user moving away from an autofill context (e.g., a - // navigation finishing or a tab being hidden). As all showing/hiding of - // autofill UI in WebLayer is driven by the system, there is no action to - // take. -} - -std::vector<autofill::Suggestion> AutofillClientImpl::GetPopupSuggestions() - const { - NOTIMPLEMENTED(); - return {}; -} - -void AutofillClientImpl::PinPopupView() { - NOTIMPLEMENTED(); -} - -autofill::AutofillClient::PopupOpenArgs AutofillClientImpl::GetReopenPopupArgs( - autofill::AutofillSuggestionTriggerSource trigger_source) const { - NOTIMPLEMENTED(); - return {}; -} - -void AutofillClientImpl::UpdatePopup( - const std::vector<autofill::Suggestion>& suggestions, - autofill::PopupType popup_type, - autofill::AutofillSuggestionTriggerSource trigger_source) { - NOTREACHED(); -} - -bool AutofillClientImpl::IsAutocompleteEnabled() const { - NOTREACHED(); - return false; -} - -bool AutofillClientImpl::IsPasswordManagerEnabled() { - // This function is currently only used by the BrowserAutofillManager, - // but not by the AndroidAutofillManager. See crbug.com/1293341 for context. - NOTREACHED(); - return false; -} - -void AutofillClientImpl::PropagateAutofillPredictionsDeprecated( - autofill::AutofillDriver* driver, - const std::vector<autofill::FormStructure*>& forms) { - NOTREACHED(); -} - -void AutofillClientImpl::DidFillOrPreviewForm( - autofill::mojom::AutofillActionPersistence action_persistence, - autofill::AutofillTriggerSource trigger_source, - bool is_refill) { - NOTREACHED(); -} - -void AutofillClientImpl::DidFillOrPreviewField( - const std::u16string& autofilled_value, - const std::u16string& profile_full_name) { - NOTREACHED(); -} - -bool AutofillClientImpl::IsContextSecure() const { - NOTREACHED(); - return false; -} - -void AutofillClientImpl::OpenPromoCodeOfferDetailsURL(const GURL& url) { - NOTREACHED(); -} - -autofill::FormInteractionsFlowId -AutofillClientImpl::GetCurrentFormInteractionsFlowId() { - // Currently not in use here. See `ChromeAutofillClient` for a proper - // implementation. - return {}; -} - -void AutofillClientImpl::LoadRiskData( - base::OnceCallback<void(const std::string&)> callback) { - NOTREACHED(); -} - -AutofillClientImpl::AutofillClientImpl(content::WebContents* web_contents) - : autofill::ContentAutofillClient( - web_contents, -#if BUILDFLAG(IS_ANDROID) - base::BindRepeating(&autofill::AndroidDriverInitHook, this) -#else - base::BindRepeating(&autofill::BrowserDriverInitHook, - this, - i18n::GetApplicationLocale()) -#endif - ), - content::WebContentsObserver(web_contents) { -} - -} // namespace weblayer
diff --git a/weblayer/browser/autofill_client_impl.h b/weblayer/browser/autofill_client_impl.h deleted file mode 100644 index ed5c1b0..0000000 --- a/weblayer/browser/autofill_client_impl.h +++ /dev/null
@@ -1,181 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_AUTOFILL_CLIENT_IMPL_H_ -#define WEBLAYER_BROWSER_AUTOFILL_CLIENT_IMPL_H_ - -#include "base/compiler_specific.h" -#include "build/build_config.h" -#include "components/autofill/content/browser/content_autofill_client.h" -#include "components/autofill/core/browser/ui/popup_item_ids.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace weblayer { - -// A minimal implementation of autofill::AutofillClient to satisfy the minor -// touchpoints between the autofill implementation and its client that get -// exercised within the WebLayer autofill flow. -class AutofillClientImpl : public autofill::ContentAutofillClient, - public content::WebContentsObserver { - public: - static AutofillClientImpl* FromWebContents( - content::WebContents* web_contents) { - return static_cast<AutofillClientImpl*>( - ContentAutofillClient::FromWebContents(web_contents)); - } - - static void CreateForWebContents(content::WebContents* contents) { - DCHECK(contents); - if (!ContentAutofillClient::FromWebContents(contents)) { - contents->SetUserData(UserDataKey(), - base::WrapUnique(new AutofillClientImpl(contents))); - } - } - - AutofillClientImpl(const AutofillClientImpl&) = delete; - AutofillClientImpl& operator=(const AutofillClientImpl&) = delete; - - ~AutofillClientImpl() override; - - // AutofillClient: - bool IsOffTheRecord() override; - scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; - autofill::AutofillDownloadManager* GetDownloadManager() override; - autofill::PersonalDataManager* GetPersonalDataManager() override; - autofill::AutocompleteHistoryManager* GetAutocompleteHistoryManager() - override; - PrefService* GetPrefs() override; - const PrefService* GetPrefs() const override; - syncer::SyncService* GetSyncService() override; - signin::IdentityManager* GetIdentityManager() override; - autofill::FormDataImporter* GetFormDataImporter() override; - autofill::payments::PaymentsClient* GetPaymentsClient() override; - autofill::StrikeDatabase* GetStrikeDatabase() override; - ukm::UkmRecorder* GetUkmRecorder() override; - ukm::SourceId GetUkmSourceId() override; - autofill::AddressNormalizer* GetAddressNormalizer() override; - const GURL& GetLastCommittedPrimaryMainFrameURL() const override; - url::Origin GetLastCommittedPrimaryMainFrameOrigin() const override; - security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; - const translate::LanguageState* GetLanguageState() override; - translate::TranslateDriver* GetTranslateDriver() override; - - void ShowAutofillSettings(autofill::PopupType popup_type) override; - void ShowUnmaskPrompt( - const autofill::CreditCard& card, - const autofill::CardUnmaskPromptOptions& card_unmask_prompt_options, - base::WeakPtr<autofill::CardUnmaskDelegate> delegate) override; - void OnUnmaskVerificationResult(PaymentsRpcResult result) override; - -#if !BUILDFLAG(IS_ANDROID) - std::vector<std::string> GetAllowedMerchantsForVirtualCards() override; - std::vector<std::string> GetAllowedBinRangesForVirtualCards() override; - - void ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure) override; - void ConfirmMigrateLocalCardToCloud( - const autofill::LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<autofill::MigratableCreditCard>& - migratable_credit_cards, - LocalCardMigrationCallback start_migrating_cards_callback) override; - void ShowLocalCardMigrationResults( - const bool has_server_error, - const std::u16string& tip_message, - const std::vector<autofill::MigratableCreditCard>& - migratable_credit_cards, - MigrationDeleteCardCallback delete_local_card_callback) override; - void ConfirmSaveIBANLocally(const autofill::IBAN& iban, - bool should_show_prompt, - LocalSaveIBANPromptCallback callback) override; - void ShowWebauthnOfferDialog( - WebauthnDialogCallback offer_dialog_callback) override; - void ShowWebauthnVerifyPendingDialog( - WebauthnDialogCallback verify_pending_dialog_callback) override; - void UpdateWebauthnOfferDialogWithError() override; - bool CloseWebauthnDialog() override; - void ConfirmSaveUpiIdLocally( - const std::string& upi_id, - base::OnceCallback<void(bool user_decision)> callback) override; - void OfferVirtualCardOptions( - const std::vector<autofill::CreditCard*>& candidates, - base::OnceCallback<void(const std::string&)> callback) override; -#else // !BUILDFLAG(IS_ANDROID) - void ConfirmAccountNameFixFlow( - base::OnceCallback<void(const std::u16string&)> callback) override; - void ConfirmExpirationDateFixFlow( - const autofill::CreditCard& card, - base::OnceCallback<void(const std::u16string&, const std::u16string&)> - callback) override; -#endif // !BUILDFLAG(IS_ANDROID) - void ConfirmSaveCreditCardLocally( - const autofill::CreditCard& card, - SaveCreditCardOptions options, - LocalSaveCardPromptCallback callback) override; - void ConfirmSaveCreditCardToCloud( - const autofill::CreditCard& card, - const autofill::LegalMessageLines& legal_message_lines, - SaveCreditCardOptions options, - UploadSaveCardPromptCallback callback) override; - void CreditCardUploadCompleted(bool card_saved) override; - void ConfirmCreditCardFillAssist(const autofill::CreditCard& card, - base::OnceClosure callback) override; - void ConfirmSaveAddressProfile( - const autofill::AutofillProfile& profile, - const autofill::AutofillProfile* original_profile, - SaveAddressProfilePromptOptions options, - AddressProfileSavePromptCallback callback) override; - void ShowEditAddressProfileDialog(const AutofillProfile& profile) override; - void ShowDeleteAddressProfileDialog() override; - bool HasCreditCardScanFeature() override; - void ScanCreditCard(CreditCardScanCallback callback) override; - bool IsTouchToFillCreditCardSupported() override; - bool ShowTouchToFillCreditCard( - base::WeakPtr<autofill::TouchToFillDelegate> delegate, - base::span<const autofill::CreditCard> cards_to_suggest) override; - void HideTouchToFillCreditCard() override; - void ShowAutofillPopup( - const autofill::AutofillClient::PopupOpenArgs& open_args, - base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override; - void UpdateAutofillPopupDataListValues( - const std::vector<std::u16string>& values, - const std::vector<std::u16string>& labels) override; - std::vector<autofill::Suggestion> GetPopupSuggestions() const override; - void PinPopupView() override; - autofill::AutofillClient::PopupOpenArgs GetReopenPopupArgs( - autofill::AutofillSuggestionTriggerSource trigger_source) const override; - void UpdatePopup( - const std::vector<autofill::Suggestion>& suggestions, - autofill::PopupType popup_type, - autofill::AutofillSuggestionTriggerSource trigger_source) override; - void HideAutofillPopup(autofill::PopupHidingReason reason) override; - bool IsAutocompleteEnabled() const override; - bool IsPasswordManagerEnabled() override; - void PropagateAutofillPredictionsDeprecated( - autofill::AutofillDriver* driver, - const std::vector<autofill::FormStructure*>& forms) override; - void DidFillOrPreviewForm( - autofill::mojom::AutofillActionPersistence action_persistence, - autofill::AutofillTriggerSource trigger_source, - bool is_refill) override; - void DidFillOrPreviewField(const std::u16string& autofilled_value, - const std::u16string& profile_full_name) override; - bool IsContextSecure() const override; - void OpenPromoCodeOfferDetailsURL(const GURL& url) override; - autofill::FormInteractionsFlowId GetCurrentFormInteractionsFlowId() override; - - // RiskDataLoader: - void LoadRiskData( - base::OnceCallback<void(const std::string&)> callback) override; - - private: - explicit AutofillClientImpl(content::WebContents* web_contents); - - std::unique_ptr<autofill::AutofillDownloadManager> download_manager_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_AUTOFILL_CLIENT_IMPL_H_
diff --git a/weblayer/browser/background_download_service_factory.cc b/weblayer/browser/background_download_service_factory.cc deleted file mode 100644 index 9c833ac..0000000 --- a/weblayer/browser/background_download_service_factory.cc +++ /dev/null
@@ -1,196 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/background_download_service_factory.h" - -#include "base/files/file_path.h" -#include "base/memory/raw_ptr.h" -#include "base/no_destructor.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/single_thread_task_runner.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" -#include "components/background_fetch/download_client.h" -#include "components/download/content/factory/download_service_factory_helper.h" -#include "components/download/content/factory/navigation_monitor_factory.h" -#include "components/download/public/background_service/background_download_service.h" -#include "components/download/public/background_service/basic_task_scheduler.h" -#include "components/download/public/background_service/blob_context_getter_factory.h" -#include "components/download/public/background_service/clients.h" -#include "components/download/public/common/simple_download_manager_coordinator.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/leveldb_proto/public/proto_database_provider.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/download_manager.h" -#include "content/public/browser/network_service_instance.h" -#include "content/public/browser/storage_partition.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/system_network_context_manager.h" - -namespace weblayer { - -namespace { - -// Like BackgroundDownloadServiceFactory, this is a -// BrowserContextKeyedServiceFactory although the Chrome version is a -// SimpleKeyedServiceFactory. -class SimpleDownloadManagerCoordinatorFactory - : public BrowserContextKeyedServiceFactory { - public: - // Returns singleton instance of SimpleDownloadManagerCoordinatorFactory. - static SimpleDownloadManagerCoordinatorFactory* GetInstance() { - static base::NoDestructor<SimpleDownloadManagerCoordinatorFactory> instance; - return instance.get(); - } - - static download::SimpleDownloadManagerCoordinator* GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<download::SimpleDownloadManagerCoordinator*>( - GetInstance()->GetServiceForBrowserContext(context, true)); - } - - SimpleDownloadManagerCoordinatorFactory( - const SimpleDownloadManagerCoordinatorFactory& other) = delete; - SimpleDownloadManagerCoordinatorFactory& operator=( - const SimpleDownloadManagerCoordinatorFactory& other) = delete; - - private: - friend class base::NoDestructor<SimpleDownloadManagerCoordinatorFactory>; - - SimpleDownloadManagerCoordinatorFactory() - : BrowserContextKeyedServiceFactory( - "SimpleDownloadManagerCoordinator", - BrowserContextDependencyManager::GetInstance()) {} - ~SimpleDownloadManagerCoordinatorFactory() override = default; - - // BrowserContextKeyedService: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override { - auto* service_instance = new download::SimpleDownloadManagerCoordinator({}); - service_instance->SetSimpleDownloadManager(context->GetDownloadManager(), - true); - return service_instance; - } - - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override { - return context; - } -}; - -// An implementation of BlobContextGetterFactory that returns the -// BlobStorageContext without delay (since WebLayer must be in "full browser" -// mode). -class DownloadBlobContextGetterFactory - : public download::BlobContextGetterFactory { - public: - explicit DownloadBlobContextGetterFactory( - content::BrowserContext* browser_context) - : browser_context_(browser_context) {} - DownloadBlobContextGetterFactory(const DownloadBlobContextGetterFactory&) = - delete; - DownloadBlobContextGetterFactory& operator=( - const DownloadBlobContextGetterFactory&) = delete; - ~DownloadBlobContextGetterFactory() override = default; - - private: - // download::BlobContextGetterFactory: - void RetrieveBlobContextGetter( - download::BlobContextGetterCallback callback) override { - std::move(callback).Run(browser_context_->GetBlobStorageContext()); - } - - raw_ptr<content::BrowserContext> browser_context_; -}; - -} // namespace - -// static -download::BackgroundDownloadService* -BackgroundDownloadServiceFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<download::BackgroundDownloadService*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - /*create=*/true)); -} - -// static -BackgroundDownloadServiceFactory* -BackgroundDownloadServiceFactory::GetInstance() { - static base::NoDestructor<BackgroundDownloadServiceFactory> factory; - return factory.get(); -} - -BackgroundDownloadServiceFactory::BackgroundDownloadServiceFactory() - : BrowserContextKeyedServiceFactory( - "BackgroundDownloadServiceFactory", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(SimpleDownloadManagerCoordinatorFactory::GetInstance()); - DependsOn(download::NavigationMonitorFactory::GetInstance()); -} - -std::unique_ptr<KeyedService> -BackgroundDownloadServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - SimpleFactoryKey* key = ProfileImpl::FromBrowserContext(context) - ->GetBrowserContext() - ->simple_factory_key(); - - auto clients = std::make_unique<download::DownloadClientMap>(); - clients->insert(std::make_pair( - download::DownloadClient::BACKGROUND_FETCH, - std::make_unique<background_fetch::DownloadClient>(context))); - - // Build in memory download service for an off the record context. - if (context->IsOffTheRecord()) { - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = - content::GetIOThreadTaskRunner({}); - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory = - SystemNetworkContextManager::GetInstance()->GetSharedURLLoaderFactory(); - - return download::BuildInMemoryDownloadService( - key, std::move(clients), content::GetNetworkConnectionTracker(), - base::FilePath(), - std::make_unique<DownloadBlobContextGetterFactory>(context), - io_task_runner, url_loader_factory); - } - - // Build download service for a regular browsing context. - base::FilePath storage_dir; - if (!context->IsOffTheRecord() && !context->GetPath().empty()) { - const base::FilePath::CharType kDownloadServiceStorageDirname[] = - FILE_PATH_LITERAL("Download Service"); - storage_dir = context->GetPath().Append(kDownloadServiceStorageDirname); - } - scoped_refptr<base::SequencedTaskRunner> background_task_runner = - base::ThreadPool::CreateSequencedTaskRunner( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); - - leveldb_proto::ProtoDatabaseProvider* proto_db_provider = - context->GetDefaultStoragePartition()->GetProtoDatabaseProvider(); - return download::BuildDownloadService( - key, std::move(clients), content::GetNetworkConnectionTracker(), - storage_dir, - SimpleDownloadManagerCoordinatorFactory::GetForBrowserContext( - context), - proto_db_provider, background_task_runner, - std::make_unique<download::BasicTaskScheduler>(base::BindRepeating( - [](content::BrowserContext* context) { - return BackgroundDownloadServiceFactory:: - GetForBrowserContext(context); - }, - context))) - .release(); -} - -content::BrowserContext* -BackgroundDownloadServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/background_download_service_factory.h b/weblayer/browser/background_download_service_factory.h deleted file mode 100644 index 364ce98c..0000000 --- a/weblayer/browser/background_download_service_factory.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BACKGROUND_DOWNLOAD_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_BACKGROUND_DOWNLOAD_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace download { -class BackgroundDownloadService; -} // namespace download - -namespace weblayer { - -// Unlike Chrome, which can operate outside of full browser mode, WebLayer can -// assume the full BrowserContext is available. For that reason this class is a -// BrowserContextKeyedService rather than a SimpleKeyedServiceFactory. -class BackgroundDownloadServiceFactory - : public BrowserContextKeyedServiceFactory { - public: - static BackgroundDownloadServiceFactory* GetInstance(); - - static download::BackgroundDownloadService* GetForBrowserContext( - content::BrowserContext* context); - - BackgroundDownloadServiceFactory( - const BackgroundDownloadServiceFactory& other) = delete; - BackgroundDownloadServiceFactory& operator=( - const BackgroundDownloadServiceFactory& other) = delete; - - private: - friend class base::NoDestructor<BackgroundDownloadServiceFactory>; - - BackgroundDownloadServiceFactory(); - ~BackgroundDownloadServiceFactory() override = default; - - // BrowserContextKeyedService: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BACKGROUND_DOWNLOAD_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/background_fetch/background_fetch_delegate_factory.cc b/weblayer/browser/background_fetch/background_fetch_delegate_factory.cc deleted file mode 100644 index 8895882..0000000 --- a/weblayer/browser/background_fetch/background_fetch_delegate_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/background_fetch/background_fetch_delegate_factory.h" - -#include "base/strings/string_number_conversions.h" -#include "build/build_config.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "content/public/browser/background_fetch_delegate.h" -#include "weblayer/browser/background_download_service_factory.h" -#include "weblayer/browser/background_fetch/background_fetch_delegate_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/android/application_info_helper.h" -#endif - -namespace weblayer { - -// static -BackgroundFetchDelegateImpl* -BackgroundFetchDelegateFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<BackgroundFetchDelegateImpl*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -BackgroundFetchDelegateFactory* BackgroundFetchDelegateFactory::GetInstance() { - return base::Singleton<BackgroundFetchDelegateFactory>::get(); -} - -BackgroundFetchDelegateFactory::BackgroundFetchDelegateFactory() - : BrowserContextKeyedServiceFactory( - "BackgroundFetchService", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(BackgroundDownloadServiceFactory::GetInstance()); - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -BackgroundFetchDelegateFactory::~BackgroundFetchDelegateFactory() = default; - -std::unique_ptr<KeyedService> -BackgroundFetchDelegateFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<BackgroundFetchDelegateImpl>(context); -} - -content::BrowserContext* BackgroundFetchDelegateFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/background_fetch/background_fetch_delegate_factory.h b/weblayer/browser/background_fetch/background_fetch_delegate_factory.h deleted file mode 100644 index 43ad035a..0000000 --- a/weblayer/browser/background_fetch/background_fetch_delegate_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DELEGATE_FACTORY_H_ -#define WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DELEGATE_FACTORY_H_ - -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace weblayer { - -class BackgroundFetchDelegateImpl; - -class BackgroundFetchDelegateFactory - : public BrowserContextKeyedServiceFactory { - public: - static BackgroundFetchDelegateImpl* GetForBrowserContext( - content::BrowserContext* context); - static BackgroundFetchDelegateFactory* GetInstance(); - - BackgroundFetchDelegateFactory(const BackgroundFetchDelegateFactory&) = - delete; - BackgroundFetchDelegateFactory& operator=( - const BackgroundFetchDelegateFactory&) = delete; - - private: - friend struct base::DefaultSingletonTraits<BackgroundFetchDelegateFactory>; - - BackgroundFetchDelegateFactory(); - ~BackgroundFetchDelegateFactory() override; - - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DELEGATE_FACTORY_H_
diff --git a/weblayer/browser/background_fetch/background_fetch_delegate_impl.cc b/weblayer/browser/background_fetch/background_fetch_delegate_impl.cc deleted file mode 100644 index ddc3783..0000000 --- a/weblayer/browser/background_fetch/background_fetch_delegate_impl.cc +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/background_fetch/background_fetch_delegate_impl.h" - -#include <utility> - -#include "base/check_op.h" -#include "base/task/sequenced_task_runner.h" -#include "build/build_config.h" -#include "components/background_fetch/download_client.h" -#include "components/background_fetch/job_details.h" -#include "components/content_settings/core/common/content_settings_types.h" -#include "content/public/browser/background_fetch_description.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/background_download_service_factory.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/system_network_context_manager.h" -#include "weblayer/public/download_delegate.h" - -namespace weblayer { - -BackgroundFetchDelegateImpl::BackgroundFetchDelegateImpl( - content::BrowserContext* context) - : background_fetch::BackgroundFetchDelegateBase(context) {} - -BackgroundFetchDelegateImpl::~BackgroundFetchDelegateImpl() = default; - -void BackgroundFetchDelegateImpl::MarkJobComplete(const std::string& job_id) { - BackgroundFetchDelegateBase::MarkJobComplete(job_id); - -#if BUILDFLAG(IS_ANDROID) - background_fetch::JobDetails* job_details = - GetJobDetails(job_id, /*allow_null=*/true); - if (job_details && job_details->job_state == - background_fetch::JobDetails::State::kJobComplete) { - // The UI should have already been updated to the Completed state, however, - // sometimes Android drops notification updates if there have been too many - // requested in a short span of time, so make sure the completed state is - // reflected in the UI after a brief delay. See - // https://developer.android.com/training/notify-user/build-notification#Updating - static constexpr auto kDelay = base::Milliseconds(1500); - base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&BackgroundFetchDelegateImpl::DoUpdateUi, - weak_ptr_factory_.GetWeakPtr(), job_id), - kDelay); - } -#endif -} - -void BackgroundFetchDelegateImpl::UpdateUI( - const std::string& job_id, - const absl::optional<std::string>& title, - const absl::optional<SkBitmap>& icon) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(title || icon); // One of the UI options must be updatable. - DCHECK(!icon || !icon->isNull()); // The |icon|, if provided, is not null. - - background_fetch::JobDetails* job_details = - GetJobDetails(job_id, /*allow_null=*/true); - if (!job_details) - return; - - if (title) - job_details->fetch_description->title = *title; - - if (icon) - job_details->fetch_description->icon = *icon; - - DoUpdateUi(job_id); - - if (auto client = GetClient(job_id)) - client->OnUIUpdated(job_id); -} - -download::BackgroundDownloadService* -BackgroundFetchDelegateImpl::GetDownloadService() { - return BackgroundDownloadServiceFactory::GetForBrowserContext(context()); -} - -void BackgroundFetchDelegateImpl::OnJobDetailsCreated( - const std::string& job_id) { - // WebLayer doesn't create the UI until a download actually starts. -} - -void BackgroundFetchDelegateImpl::DoShowUi(const std::string& job_id) { - // Create the UI the first time a download starts. (There may be multiple - // downloads for a single background fetch job.) - background_fetch::JobDetails* job = GetJobDetails(job_id); - auto inserted = ui_item_map_.emplace( - std::piecewise_construct, std::forward_as_tuple(job_id), - std::forward_as_tuple(this, job_id, job)); - DCHECK(inserted.second); - ProfileImpl::FromBrowserContext(context()) - ->download_delegate() - ->DownloadStarted(&inserted.first->second); -} - -void BackgroundFetchDelegateImpl::DoUpdateUi(const std::string& job_id) { - auto iter = ui_item_map_.find(job_id); - if (iter == ui_item_map_.end()) - return; - - BackgroundFetchDownload* download = &iter->second; - - if (!download->HasBeenAddedToUi()) - return; - - ProfileImpl::FromBrowserContext(context()) - ->download_delegate() - ->DownloadProgressChanged(download); -} - -void BackgroundFetchDelegateImpl::DoCleanUpUi(const std::string& job_id) { - ui_item_map_.erase(job_id); -} - -} // namespace weblayer
diff --git a/weblayer/browser/background_fetch/background_fetch_delegate_impl.h b/weblayer/browser/background_fetch/background_fetch_delegate_impl.h deleted file mode 100644 index a7ed90b..0000000 --- a/weblayer/browser/background_fetch/background_fetch_delegate_impl.h +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DELEGATE_IMPL_H_ - -#include <map> -#include <memory> -#include <set> -#include <string> - -#include "base/memory/weak_ptr.h" -#include "components/background_fetch/background_fetch_delegate_base.h" -#include "components/download/public/background_service/download_params.h" -#include "components/keyed_service/core/keyed_service.h" -#include "ui/gfx/image/image.h" -#include "url/origin.h" -#include "weblayer/browser/background_fetch/background_fetch_download.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -// Implementation of BackgroundFetchDelegate using the -// BackgroundDownloadService. -class BackgroundFetchDelegateImpl - : public background_fetch::BackgroundFetchDelegateBase, - public KeyedService { - public: - explicit BackgroundFetchDelegateImpl(content::BrowserContext* context); - BackgroundFetchDelegateImpl(const BackgroundFetchDelegateImpl&) = delete; - BackgroundFetchDelegateImpl& operator=(const BackgroundFetchDelegateImpl&) = - delete; - ~BackgroundFetchDelegateImpl() override; - - // BackgroundFetchDelegate: - void MarkJobComplete(const std::string& job_id) override; - void UpdateUI(const std::string& job_id, - const absl::optional<std::string>& title, - const absl::optional<SkBitmap>& icon) override; - - protected: - // BackgroundFetchDelegateBase: - download::BackgroundDownloadService* GetDownloadService() override; - void OnJobDetailsCreated(const std::string& job_id) override; - void DoShowUi(const std::string& job_id) override; - void DoUpdateUi(const std::string& job_id) override; - void DoCleanUpUi(const std::string& job_id) override; - - private: - // Map from job unique ids to the UI item for the job. - std::map<std::string, BackgroundFetchDownload> ui_item_map_; - - base::WeakPtrFactory<BackgroundFetchDelegateImpl> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/background_fetch/background_fetch_download.cc b/weblayer/browser/background_fetch/background_fetch_download.cc deleted file mode 100644 index fe7f283..0000000 --- a/weblayer/browser/background_fetch/background_fetch_download.cc +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/background_fetch/background_fetch_download.h" - -#include "base/strings/utf_string_conversions.h" -#include "components/background_fetch/job_details.h" -#include "content/public/browser/background_fetch_description.h" -#include "url/origin.h" -#include "weblayer/browser/background_fetch/background_fetch_delegate_impl.h" - -using background_fetch::JobDetails; - -namespace weblayer { - -BackgroundFetchDownload::BackgroundFetchDownload( - BackgroundFetchDelegateImpl* controller, - const std::string& job_id, - const JobDetails* job) - : controller_(controller), job_id_(job_id), job_(job) { - // The only other kind of DownloadImpl uses the DownloadItem's ID as its - // notification ID, and that's constrained to positive integers. - static int id = 0; - if (id > 0) - id = 0; - notification_id_ = --id; -} - -BackgroundFetchDownload::~BackgroundFetchDownload() = default; - -DownloadState BackgroundFetchDownload::GetState() { - switch (job_->job_state) { - case JobDetails::State::kPendingWillStartDownloading: - case JobDetails::State::kStartedAndDownloading: - return DownloadState::kInProgress; - - case JobDetails::State::kPendingWillStartPaused: - case JobDetails::State::kStartedButPaused: - return DownloadState::kPaused; - - case JobDetails::State::kCancelled: - return DownloadState::kCancelled; - - case JobDetails::State::kDownloadsComplete: - case JobDetails::State::kJobComplete: - return DownloadState::kComplete; - } -} - -int64_t BackgroundFetchDownload::GetTotalBytes() { - return job_->GetTotalBytes(); -} - -int64_t BackgroundFetchDownload::GetReceivedBytes() { - return job_->GetProcessedBytes(); -} - -void BackgroundFetchDownload::Pause() { - controller_->PauseDownload(job_id_); -} - -void BackgroundFetchDownload::Resume() { - controller_->ResumeDownload(job_id_); -} - -void BackgroundFetchDownload::Cancel() { - controller_->CancelDownload(job_id_); -} - -base::FilePath BackgroundFetchDownload::GetLocation() { - NOTREACHED(); - return {}; -} - -std::u16string BackgroundFetchDownload::GetFileNameToReportToUser() { - return base::UTF8ToUTF16(job_->fetch_description->title); -} - -std::string BackgroundFetchDownload::GetMimeType() { - NOTREACHED(); - return {}; -} - -DownloadError BackgroundFetchDownload::GetError() { - NOTREACHED(); - return DownloadError::kNoError; -} - -int BackgroundFetchDownload::GetNotificationId() { - return notification_id_; -} - -bool BackgroundFetchDownload::IsTransient() { - return true; -} - -GURL BackgroundFetchDownload::GetSourceUrl() { - return job_->fetch_description->origin.GetURL(); -} - -const SkBitmap* BackgroundFetchDownload::GetLargeIcon() { - return &job_->fetch_description->icon; -} - -void BackgroundFetchDownload::OnFinished(bool activated) { - if (activated) - controller_->OnUiActivated(job_id_); - controller_->OnUiFinished(job_id_); - // |this| is deleted. -} - -} // namespace weblayer
diff --git a/weblayer/browser/background_fetch/background_fetch_download.h b/weblayer/browser/background_fetch/background_fetch_download.h deleted file mode 100644 index 93cdc79..0000000 --- a/weblayer/browser/background_fetch/background_fetch_download.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DOWNLOAD_H_ -#define WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DOWNLOAD_H_ - -#include <string> - -#include "base/memory/raw_ptr.h" -#include "weblayer/browser/download_impl.h" - -namespace background_fetch { -struct JobDetails; -} - -namespace weblayer { - -class BackgroundFetchDelegateImpl; - -// The UI object for an in-progress BackgroundFetch download job. -class BackgroundFetchDownload : public DownloadImpl { - public: - BackgroundFetchDownload(BackgroundFetchDelegateImpl* controller, - const std::string& job_id, - const background_fetch::JobDetails* job); - BackgroundFetchDownload(const BackgroundFetchDownload& other) = delete; - BackgroundFetchDownload& operator=(const BackgroundFetchDownload& other) = - delete; - ~BackgroundFetchDownload() override; - - // Download implementation: - DownloadState GetState() override; - int64_t GetTotalBytes() override; - int64_t GetReceivedBytes() override; - void Pause() override; - void Resume() override; - void Cancel() override; - base::FilePath GetLocation() override; - std::u16string GetFileNameToReportToUser() override; - std::string GetMimeType() override; - DownloadError GetError() override; - - // DownloadImpl: - int GetNotificationId() override; - bool IsTransient() override; - GURL GetSourceUrl() override; - const SkBitmap* GetLargeIcon() override; - void OnFinished(bool activated) override; - - private: - raw_ptr<BackgroundFetchDelegateImpl> controller_; - std::string job_id_; - int notification_id_ = 0; - raw_ptr<const background_fetch::JobDetails> job_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DOWNLOAD_H_
diff --git a/weblayer/browser/background_fetch/background_fetch_permission_context.cc b/weblayer/browser/background_fetch/background_fetch_permission_context.cc deleted file mode 100644 index acf7e5a..0000000 --- a/weblayer/browser/background_fetch/background_fetch_permission_context.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/background_fetch/background_fetch_permission_context.h" - -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "content/public/browser/web_contents.h" -#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -BackgroundFetchPermissionContext::BackgroundFetchPermissionContext( - content::BrowserContext* browser_context) - : PermissionContextBase(browser_context, - ContentSettingsType::BACKGROUND_FETCH, - blink::mojom::PermissionsPolicyFeature::kNotFound) { -} - -ContentSetting BackgroundFetchPermissionContext::GetPermissionStatusInternal( - content::RenderFrameHost* render_frame_host, - const GURL& requesting_origin, - const GURL& embedding_origin) const { - // Follow the AUTOMATIC_DOWNLOADS setting. TODO(crbug.com/1189247): can this - // be improved upon? It's not really "automatic" if it's in direct response to - // a user action, but WebLayer doesn't implement Chrome's download request - // limiting logic. - auto* host_content_settings_map = - HostContentSettingsMapFactory::GetForBrowserContext(browser_context()); - ContentSetting setting = host_content_settings_map->GetContentSetting( - requesting_origin, requesting_origin, - ContentSettingsType::AUTOMATIC_DOWNLOADS); - - // Matching Chrome behavior: when the request originates from a non-main frame - // or a service worker, the most permissive we'll allow is ASK. This causes - // the download to start in a paused state. - if (setting == CONTENT_SETTING_ALLOW && - (!render_frame_host || render_frame_host->GetParent())) { - setting = CONTENT_SETTING_ASK; - } - - return setting; -} - -} // namespace weblayer
diff --git a/weblayer/browser/background_fetch/background_fetch_permission_context.h b/weblayer/browser/background_fetch/background_fetch_permission_context.h deleted file mode 100644 index 570a1d3..0000000 --- a/weblayer/browser/background_fetch/background_fetch_permission_context.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_PERMISSION_CONTEXT_H_ -#define WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_PERMISSION_CONTEXT_H_ - -#include "components/content_settings/core/common/content_settings.h" -#include "components/permissions/permission_context_base.h" - -class GURL; - -namespace weblayer { - -// Manages user permissions for Background Fetch. Background Fetch permission -// is currently dynamic and relies on the Automatic Downloads content setting. -class BackgroundFetchPermissionContext - : public permissions::PermissionContextBase { - public: - explicit BackgroundFetchPermissionContext( - content::BrowserContext* browser_context); - BackgroundFetchPermissionContext( - const BackgroundFetchPermissionContext& other) = delete; - BackgroundFetchPermissionContext& operator=( - const BackgroundFetchPermissionContext& other) = delete; - ~BackgroundFetchPermissionContext() override = default; - - private: - // PermissionContextBase implementation. - ContentSetting GetPermissionStatusInternal( - content::RenderFrameHost* render_frame_host, - const GURL& requesting_origin, - const GURL& embedding_origin) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_PERMISSION_CONTEXT_H_
diff --git a/weblayer/browser/background_sync/background_sync_browsertest.cc b/weblayer/browser/background_sync/background_sync_browsertest.cc deleted file mode 100644 index 64196e43..0000000 --- a/weblayer/browser/background_sync/background_sync_browsertest.cc +++ /dev/null
@@ -1,226 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/run_loop.h" -#include "base/threading/thread_restrictions.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "components/background_sync/background_sync_controller_impl.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/content_settings/core/common/content_settings.h" -#include "content/public/browser/background_sync_parameters.h" -#include "content/public/test/background_sync_test_util.h" -#include "content/public/test/browser_test_utils.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" -#include "weblayer/browser/background_sync/background_sync_controller_factory.h" -#include "weblayer/browser/background_sync/background_sync_delegate_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -#if !BUILDFLAG(IS_ANDROID) -#include "components/keep_alive_registry/keep_alive_registry.h" -#include "components/keep_alive_registry/keep_alive_state_observer.h" - -namespace { -class TestKeepAliveStateObserver : public KeepAliveStateObserver { - public: - TestKeepAliveStateObserver() { - KeepAliveRegistry::GetInstance()->AddObserver(this); - } - - ~TestKeepAliveStateObserver() override { - KeepAliveRegistry::GetInstance()->RemoveObserver(this); - } - - void OnKeepAliveStateChanged(bool is_keeping_alive) override { - if (is_keeping_alive_loop_ && !is_keeping_alive) - is_keeping_alive_loop_->Quit(); - } - - void OnKeepAliveRestartStateChanged(bool can_restart) override {} - - void WaitUntilNoKeepAlives() { - if (!KeepAliveRegistry::GetInstance()->IsKeepingAlive()) - return; - is_keeping_alive_loop_ = std::make_unique<base::RunLoop>(); - is_keeping_alive_loop_->Run(); - is_keeping_alive_loop_ = nullptr; - CHECK(!KeepAliveRegistry::GetInstance()->IsKeepingAlive()); - } - - private: - std::unique_ptr<base::RunLoop> is_keeping_alive_loop_; -}; -} // namespace -#endif // !BUILDFLAG(IS_ANDROID) - -namespace { -const char kExampleUrl[] = "https://www.example.com/"; -const char kTag[] = "test_tag"; -} // namespace - -namespace weblayer { - -class BackgroundSyncBrowserTest : public WebLayerBrowserTest { - public: - BackgroundSyncBrowserTest() = default; - ~BackgroundSyncBrowserTest() override = default; - - void SetUpOnMainThread() override { - sync_event_received_ = std::make_unique<base::RunLoop>(); - content::background_sync_test_util::SetIgnoreNetworkChanges( - /* ignore= */ true); - - https_server_ = std::make_unique<net::EmbeddedTestServer>( - net::EmbeddedTestServer::TYPE_HTTPS); - https_server_->RegisterRequestHandler(base::BindRepeating( - &BackgroundSyncBrowserTest::HandleRequest, base::Unretained(this))); - https_server_->AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - ASSERT_TRUE(https_server_->Start()); - } - - // Intercepts all requests. - std::unique_ptr<net::test_server::HttpResponse> HandleRequest( - const net::test_server::HttpRequest& request) { - if (request.GetURL().query() == "syncreceived") { - if (sync_event_received_) - sync_event_received_->Quit(); - } - - // The default handlers will take care of this request. - return nullptr; - } - -#if !BUILDFLAG(IS_ANDROID) - void PostRunTestOnMainThread() override { - keep_alive_observer_.WaitUntilNoKeepAlives(); - WebLayerBrowserTest::PostRunTestOnMainThread(); - } -#endif // !BUILDFLAG(IS_ANDROID) - - protected: - content::WebContents* web_contents() { - return static_cast<TabImpl*>(shell()->tab())->web_contents(); - } - - std::unique_ptr<base::RunLoop> sync_event_received_; - std::unique_ptr<net::EmbeddedTestServer> https_server_; -#if !BUILDFLAG(IS_ANDROID) - TestKeepAliveStateObserver keep_alive_observer_; -#endif // !BUILDFLAG(IS_ANDROID) -}; - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, GetBackgroundSyncController) { - EXPECT_TRUE(BackgroundSyncControllerFactory::GetForBrowserContext( - GetBrowserContext())); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, ZeroSiteEngagementPenalty) { - // TODO(crbug.com/1091211): Update when we add support for Periodic Background - // Sync. - auto* controller = BackgroundSyncControllerFactory::GetForBrowserContext( - GetBrowserContext()); - ASSERT_TRUE(controller); - - url::Origin origin = url::Origin::Create(GURL(kExampleUrl)); - content::BackgroundSyncRegistration registration; - registration.set_origin(origin); - - // min interval >=0 implies Periodic Background Sync. - blink::mojom::SyncRegistrationOptions options( - kTag, - /* min_interval= */ base::Hours(12).InMilliseconds()); - *registration.options() = std::move(options); - // First attempt. - registration.set_num_attempts(0); - - content::BackgroundSyncParameters parameters; - - base::TimeDelta delay = controller->GetNextEventDelay( - registration, ¶meters, - /* time_till_soonest_scheduled_event_for_origin= */ - base::TimeDelta::Max()); - EXPECT_EQ(delay, base::TimeDelta::Max()); -} - -#if BUILDFLAG(IS_ANDROID) -// TODO(crbug.com/1154332): Fix flaky test. -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, - DISABLED_BackgroundSyncNotDisabled) { - auto* controller = BackgroundSyncControllerFactory::GetForBrowserContext( - GetBrowserContext()); - ASSERT_TRUE(controller); - - // TODO(crbug.com/1087486, 1091211): Update logic here if we need to support - // Android L when we add browser wakeup logic. - content::BackgroundSyncParameters parameters; - controller->GetParameterOverrides(¶meters); - EXPECT_FALSE(parameters.disable); -} -#endif // defined (OS_ANDROID) - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, ContentSettings) { - auto* browser_context = GetBrowserContext(); - auto* controller = - BackgroundSyncControllerFactory::GetForBrowserContext(browser_context); - ASSERT_TRUE(controller); - - url::Origin origin = url::Origin::Create(GURL(kExampleUrl)); - controller->AddToTrackedOrigins(origin); - ASSERT_TRUE(controller->IsOriginTracked(origin)); - - auto* host_content_settings_map = - HostContentSettingsMapFactory::GetForBrowserContext(browser_context); - ASSERT_TRUE(host_content_settings_map); - - host_content_settings_map->SetContentSettingDefaultScope( - /* primary_url= */ GURL(kExampleUrl), - /* secondary_url= */ GURL(kExampleUrl), - ContentSettingsType::BACKGROUND_SYNC, CONTENT_SETTING_BLOCK); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(controller->IsOriginTracked(origin)); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, NormalProfile) { - // TODO(crbug.com/1087486, 1091211): Make this use - // BackgroundSyncController::ScheduleBrowserWakeup() once we support waking - // the browser up. - auto delegate = - std::make_unique<BackgroundSyncDelegateImpl>(GetBrowserContext()); - ASSERT_TRUE(delegate); - EXPECT_FALSE(delegate->IsProfileOffTheRecord()); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, SyncEventFired) { - content::background_sync_test_util::SetOnline(web_contents(), false); - NavigateAndWaitForCompletion( - https_server_->GetURL("/background_sync_browsertest.html"), shell()); - content::background_sync_test_util::SetOnline(web_contents(), true); - sync_event_received_->Run(); -} - -class IncognitoBackgroundSyncBrowserTest : public BackgroundSyncBrowserTest { - public: - IncognitoBackgroundSyncBrowserTest() { SetShellStartsInIncognitoMode(); } -}; - -IN_PROC_BROWSER_TEST_F(IncognitoBackgroundSyncBrowserTest, - DISABLED_OffTheRecordProfile) { - base::ScopedAllowBlockingForTesting allow_blocking; - - // TODO(crbug.com/1087486, 1091211): Make this use - // BackgroundSyncController::ScheduleBrowserWakeup() once we support waking - // the browser up. - auto delegate = - std::make_unique<BackgroundSyncDelegateImpl>(GetBrowserContext()); - EXPECT_TRUE(delegate->IsProfileOffTheRecord()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/background_sync/background_sync_controller_factory.cc b/weblayer/browser/background_sync/background_sync_controller_factory.cc deleted file mode 100644 index d7e42fb..0000000 --- a/weblayer/browser/background_sync/background_sync_controller_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/background_sync/background_sync_controller_factory.h" - -#include "base/no_destructor.h" -#include "components/background_sync/background_sync_controller_impl.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "weblayer/browser/background_sync/background_sync_delegate_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -BackgroundSyncControllerImpl* -BackgroundSyncControllerFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - // This is safe because BuildServiceInstanceFor(), which this method calls, - // returns a pointer to a BackgroundSyncControllerImpl object. - return static_cast<BackgroundSyncControllerImpl*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -BackgroundSyncControllerFactory* -BackgroundSyncControllerFactory::GetInstance() { - static base::NoDestructor<BackgroundSyncControllerFactory> factory; - return factory.get(); -} - -BackgroundSyncControllerFactory::BackgroundSyncControllerFactory() - : BrowserContextKeyedServiceFactory( - "BackgroundSyncService", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -BackgroundSyncControllerFactory::~BackgroundSyncControllerFactory() = default; - -KeyedService* BackgroundSyncControllerFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return new BackgroundSyncControllerImpl( - context, std::make_unique<BackgroundSyncDelegateImpl>(context)); -} - -content::BrowserContext* -BackgroundSyncControllerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - // Background sync operates in incognito mode, and as incognito profiles in - // Weblayer are not tied to regular profiles, return |context| itself. - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/background_sync/background_sync_controller_factory.h b/weblayer/browser/background_sync/background_sync_controller_factory.h deleted file mode 100644 index 2e124cb..0000000 --- a/weblayer/browser/background_sync/background_sync_controller_factory.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_FACTORY_H_ -#define WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class BackgroundSyncControllerImpl; - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -// Creates and maintains a BackgroundSyncController instance per BrowserContext. -class BackgroundSyncControllerFactory - : public BrowserContextKeyedServiceFactory { - public: - static BackgroundSyncControllerImpl* GetForBrowserContext( - content::BrowserContext* browser_context); - static BackgroundSyncControllerFactory* GetInstance(); - - BackgroundSyncControllerFactory(const BackgroundSyncControllerFactory&) = - delete; - BackgroundSyncControllerFactory& operator=( - const BackgroundSyncControllerFactory&) = delete; - - private: - friend class base::NoDestructor<BackgroundSyncControllerFactory>; - - BackgroundSyncControllerFactory(); - ~BackgroundSyncControllerFactory() override; - - // BrowserContextKeyedServiceFactory methods: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_FACTORY_H_
diff --git a/weblayer/browser/background_sync/background_sync_delegate_impl.cc b/weblayer/browser/background_sync/background_sync_delegate_impl.cc deleted file mode 100644 index 2687b21..0000000 --- a/weblayer/browser/background_sync/background_sync_delegate_impl.cc +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/background_sync/background_sync_delegate_impl.h" - -#include "build/build_config.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/web_contents.h" -#include "services/metrics/public/cpp/ukm_recorder.h" -#include "services/metrics/public/cpp/ukm_source_id.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -BackgroundSyncDelegateImpl::BackgroundSyncDelegateImpl( - content::BrowserContext* browser_context) - : browser_context_(browser_context) { - DCHECK(browser_context_); -} - -BackgroundSyncDelegateImpl::~BackgroundSyncDelegateImpl() = default; - -#if !BUILDFLAG(IS_ANDROID) -std::unique_ptr<content::BackgroundSyncController::BackgroundSyncEventKeepAlive> -BackgroundSyncDelegateImpl::CreateBackgroundSyncEventKeepAlive() { - return nullptr; -} -#endif // !BUILDFLAG(IS_ANDROID) - -void BackgroundSyncDelegateImpl::GetUkmSourceId( - const url::Origin& origin, - base::OnceCallback<void(absl::optional<ukm::SourceId>)> callback) { - // The exact URL which registered the Background Sync event is not saved, - // and the current main frame URL might not correspond to |origin|. Thus, we - // associate a new source ID with the origin. - // The only way WebLayer can lose history information is through the - // clearBrowsingHistory() API which also deletes all existing service workers. - // Therefore, if this method is called, it's safe to assume that the origin - // associated with the Background Sync registration is in WebLayer's browsing - // history. It's okay to log UKM for it. - ukm::SourceId source_id = ukm::ConvertToSourceId( - ukm::AssignNewSourceId(), ukm::SourceIdType::HISTORY_ID); - ukm::UkmRecorder* recorder = ukm::UkmRecorder::Get(); - DCHECK(recorder); - recorder->UpdateSourceURL(source_id, origin.GetURL()); - - std::move(callback).Run(source_id); -} - -void BackgroundSyncDelegateImpl::Shutdown() { - // Clear the BrowserContext as we're not supposed to use it anymore. - browser_context_ = nullptr; -} - -HostContentSettingsMap* -BackgroundSyncDelegateImpl::GetHostContentSettingsMap() { - return HostContentSettingsMapFactory::GetForBrowserContext(browser_context_); -} - -bool BackgroundSyncDelegateImpl::IsProfileOffTheRecord() { - DCHECK(browser_context_); - return browser_context_->IsOffTheRecord(); -} - -void BackgroundSyncDelegateImpl::NoteSuspendedPeriodicSyncOrigins( - std::set<url::Origin> suspended_origins) { - // TODO(crbug.com/1091211): Consider site engagement when adding support for - // Periodic Background Sync. -} - -int BackgroundSyncDelegateImpl::GetSiteEngagementPenalty(const GURL& url) { - // TODO(crbug.com/1091211): Consider site engagement when adding support for - // Periodic Background Sync. - return 0; -} - -#if BUILDFLAG(IS_ANDROID) - -void BackgroundSyncDelegateImpl::ScheduleBrowserWakeUpWithDelay( - blink::mojom::BackgroundSyncType sync_type, - base::TimeDelta delay) { - // TODO(crbug.com/1087486, 1091211): Add logic to wake up the browser. -} - -void BackgroundSyncDelegateImpl::CancelBrowserWakeup( - blink::mojom::BackgroundSyncType sync_type) { - // TODO(crbug.com/1087486, 1091211): Add logic to wake up the browser. -} - -bool BackgroundSyncDelegateImpl::ShouldDisableBackgroundSync() { - // TODO(crbug.com/1087486, 1091211): Add logic here if we need to support - // Android L. - return false; -} - -bool BackgroundSyncDelegateImpl::ShouldDisableAndroidNetworkDetection() { - // TODO(crbug.com/1141778): Remove this once waking up the WebLayer - // embedder is supported. - return true; -} -#endif // BUILDFLAG(IS_ANDROID) - -} // namespace weblayer
diff --git a/weblayer/browser/background_sync/background_sync_delegate_impl.h b/weblayer/browser/background_sync/background_sync_delegate_impl.h deleted file mode 100644 index 0bbc7c1..0000000 --- a/weblayer/browser/background_sync/background_sync_delegate_impl.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_DELEGATE_IMPL_H_ - -#include "base/memory/raw_ptr.h" -#include "build/build_config.h" -#include "components/background_sync/background_sync_delegate.h" -#include "url/origin.h" - -namespace content { -class BrowserContext; -} // namespace content - -namespace weblayer { - -// WebLayer's customization of the logic in components/background_sync. -class BackgroundSyncDelegateImpl - : public background_sync::BackgroundSyncDelegate { - public: - explicit BackgroundSyncDelegateImpl(content::BrowserContext* browser_context); - ~BackgroundSyncDelegateImpl() override; - -#if !BUILDFLAG(IS_ANDROID) - std::unique_ptr< - content::BackgroundSyncController::BackgroundSyncEventKeepAlive> - CreateBackgroundSyncEventKeepAlive() override; -#endif // !BUILDFLAG(IS_ANDROID) - - void GetUkmSourceId(const url::Origin& origin, - base::OnceCallback<void(absl::optional<ukm::SourceId>)> - callback) override; - void Shutdown() override; - HostContentSettingsMap* GetHostContentSettingsMap() override; - bool IsProfileOffTheRecord() override; - void NoteSuspendedPeriodicSyncOrigins( - std::set<url::Origin> suspended_origins) override; - int GetSiteEngagementPenalty(const GURL& url) override; -#if BUILDFLAG(IS_ANDROID) - void ScheduleBrowserWakeUpWithDelay( - blink::mojom::BackgroundSyncType sync_type, - base::TimeDelta delay) override; - void CancelBrowserWakeup(blink::mojom::BackgroundSyncType sync_type) override; - bool ShouldDisableBackgroundSync() override; - bool ShouldDisableAndroidNetworkDetection() override; -#endif // BUILDFLAG(IS_ANDROID) - - private: - raw_ptr<content::BrowserContext> browser_context_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.cc b/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.cc deleted file mode 100644 index f5f47a69..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.h" - -#include "base/android/jni_android.h" -#include "components/security_state/content/content_utils.h" -#include "weblayer/browser/java/jni/WebLayerBluetoothChooserAndroidDelegate_jni.h" - -namespace weblayer { - -WebLayerBluetoothChooserAndroidDelegate:: - WebLayerBluetoothChooserAndroidDelegate() { - JNIEnv* env = base::android::AttachCurrentThread(); - java_delegate_.Reset( - Java_WebLayerBluetoothChooserAndroidDelegate_create(env)); -} - -WebLayerBluetoothChooserAndroidDelegate:: - ~WebLayerBluetoothChooserAndroidDelegate() = default; - -base::android::ScopedJavaLocalRef<jobject> -WebLayerBluetoothChooserAndroidDelegate::GetJavaObject() { - return base::android::ScopedJavaLocalRef<jobject>(java_delegate_); -} - -security_state::SecurityLevel -WebLayerBluetoothChooserAndroidDelegate::GetSecurityLevel( - content::WebContents* web_contents) { - auto state = security_state::GetVisibleSecurityState(web_contents); - return security_state::GetSecurityLevel( - *state, - /*used_policy_installed_certificate=*/false); -} - -} // namespace weblayer
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.h b/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.h deleted file mode 100644 index c7421c72..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_CHOOSER_ANDROID_DELEGATE_H_ -#define WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_CHOOSER_ANDROID_DELEGATE_H_ - -#include "components/permissions/android/bluetooth_chooser_android_delegate.h" - -#include "base/android/scoped_java_ref.h" - -namespace weblayer { - -// The implementation of BluetoothChooserAndroidDelegate for WebLayer. -class WebLayerBluetoothChooserAndroidDelegate - : public permissions::BluetoothChooserAndroidDelegate { - public: - WebLayerBluetoothChooserAndroidDelegate(); - - WebLayerBluetoothChooserAndroidDelegate( - const WebLayerBluetoothChooserAndroidDelegate&) = delete; - WebLayerBluetoothChooserAndroidDelegate& operator=( - const WebLayerBluetoothChooserAndroidDelegate&) = delete; - - ~WebLayerBluetoothChooserAndroidDelegate() override; - - // BluetoothChooserAndroidDelegate implementation: - base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override; - security_state::SecurityLevel GetSecurityLevel( - content::WebContents* web_contents) override; - - private: - base::android::ScopedJavaGlobalRef<jobject> java_delegate_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_CHOOSER_ANDROID_DELEGATE_H_
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.cc b/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.cc deleted file mode 100644 index 7c52f58..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.cc +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/permissions/contexts/bluetooth_chooser_context.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -WebLayerBluetoothChooserContextFactory* -WebLayerBluetoothChooserContextFactory::GetInstance() { - static base::NoDestructor<WebLayerBluetoothChooserContextFactory> factory; - return factory.get(); -} - -// static -permissions::BluetoothChooserContext* -WebLayerBluetoothChooserContextFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<permissions::BluetoothChooserContext*>( - GetInstance()->GetServiceForBrowserContext(context, /*create=*/true)); -} - -// static -permissions::BluetoothChooserContext* -WebLayerBluetoothChooserContextFactory::GetForBrowserContextIfExists( - content::BrowserContext* context) { - return static_cast<permissions::BluetoothChooserContext*>( - GetInstance()->GetServiceForBrowserContext(context, /*create=*/false)); -} - -WebLayerBluetoothChooserContextFactory::WebLayerBluetoothChooserContextFactory() - : BrowserContextKeyedServiceFactory( - "BluetoothChooserContext", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -WebLayerBluetoothChooserContextFactory:: - ~WebLayerBluetoothChooserContextFactory() = default; - -std::unique_ptr<KeyedService> -WebLayerBluetoothChooserContextFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<permissions::BluetoothChooserContext>(context); -} - -content::BrowserContext* -WebLayerBluetoothChooserContextFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -void WebLayerBluetoothChooserContextFactory::BrowserContextShutdown( - content::BrowserContext* context) { - auto* bluetooth_chooser_context = GetForBrowserContextIfExists(context); - if (bluetooth_chooser_context) - bluetooth_chooser_context->FlushScheduledSaveSettingsCalls(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.h b/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.h deleted file mode 100644 index e0f9a25..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_CHOOSER_CONTEXT_FACTORY_H_ -#define WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_CHOOSER_CONTEXT_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace permissions { -class BluetoothChooserContext; -} - -namespace weblayer { - -class WebLayerBluetoothChooserContextFactory - : public BrowserContextKeyedServiceFactory { - public: - static permissions::BluetoothChooserContext* GetForBrowserContext( - content::BrowserContext* context); - static permissions::BluetoothChooserContext* GetForBrowserContextIfExists( - content::BrowserContext* context); - static WebLayerBluetoothChooserContextFactory* GetInstance(); - - WebLayerBluetoothChooserContextFactory( - const WebLayerBluetoothChooserContextFactory&) = delete; - WebLayerBluetoothChooserContextFactory& operator=( - const WebLayerBluetoothChooserContextFactory&) = delete; - - private: - friend base::NoDestructor<WebLayerBluetoothChooserContextFactory>; - - WebLayerBluetoothChooserContextFactory(); - ~WebLayerBluetoothChooserContextFactory() override; - - // BrowserContextKeyedServiceFactory implementation: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - void BrowserContextShutdown(content::BrowserContext* context) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_CHOOSER_CONTEXT_FACTORY_H_
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc b/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc deleted file mode 100644 index 35133a7..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h" - -#include "build/build_config.h" -#include "content/public/browser/render_frame_host.h" -#include "weblayer/browser/bluetooth/weblayer_bluetooth_chooser_context_factory.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/permissions/android/bluetooth_chooser_android.h" -#include "components/permissions/android/bluetooth_scanning_prompt_android.h" -#include "weblayer/browser/bluetooth/weblayer_bluetooth_chooser_android_delegate.h" -#include "weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.h" -#endif // BUILDFLAG(IS_ANDROID) - -namespace weblayer { - -WebLayerBluetoothDelegateImplClient::WebLayerBluetoothDelegateImplClient() = - default; - -WebLayerBluetoothDelegateImplClient::~WebLayerBluetoothDelegateImplClient() = - default; - -permissions::BluetoothChooserContext* -WebLayerBluetoothDelegateImplClient::GetBluetoothChooserContext( - content::RenderFrameHost* frame) { - return WebLayerBluetoothChooserContextFactory::GetForBrowserContext( - frame->GetBrowserContext()); -} - -std::unique_ptr<content::BluetoothChooser> -WebLayerBluetoothDelegateImplClient::RunBluetoothChooser( - content::RenderFrameHost* frame, - const content::BluetoothChooser::EventHandler& event_handler) { -#if BUILDFLAG(IS_ANDROID) - // TODO(https://crbug.com/1231932): Return nullptr if suppressed in vr. - return std::make_unique<permissions::BluetoothChooserAndroid>( - frame, event_handler, - std::make_unique<WebLayerBluetoothChooserAndroidDelegate>()); -#else - // Web Bluetooth is not supported for desktop in WebLayer. - return nullptr; -#endif -} - -std::unique_ptr<content::BluetoothScanningPrompt> -WebLayerBluetoothDelegateImplClient::ShowBluetoothScanningPrompt( - content::RenderFrameHost* frame, - const content::BluetoothScanningPrompt::EventHandler& event_handler) { -#if BUILDFLAG(IS_ANDROID) - return std::make_unique<permissions::BluetoothScanningPromptAndroid>( - frame, event_handler, - std::make_unique<WebLayerBluetoothScanningPromptAndroidDelegate>()); -#else - // Web Bluetooth is not supported for desktop in WebLayer. - return nullptr; -#endif -} - -void WebLayerBluetoothDelegateImplClient::ShowBluetoothDevicePairDialog( - content::RenderFrameHost* frame, - const std::u16string& device_identifier, - content::BluetoothDelegate::PairPromptCallback callback, - content::BluetoothDelegate::PairingKind, - const absl::optional<std::u16string>& pin) { - // Web Bluetooth is not supported for desktop in WebLayer and Android already - // bonds on demand, so this should not be called on any platform. - std::move(callback).Run(content::BluetoothDelegate::PairPromptResult( - content::BluetoothDelegate::PairPromptStatus::kCancelled)); - NOTREACHED(); -} -} // namespace weblayer
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h b/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h deleted file mode 100644 index 4d9f4c2..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_DELEGATE_IMPL_CLIENT_H_ -#define WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_DELEGATE_IMPL_CLIENT_H_ - -#include <memory> - -#include "components/permissions/bluetooth_chooser_controller.h" -#include "components/permissions/bluetooth_delegate_impl.h" -#include "content/public/browser/bluetooth_delegate.h" - -namespace content { -class RenderFrameHost; -} // namespace content - -namespace permissions { -class BluetoothChooserContext; -} // namespace permissions - -namespace weblayer { - -// Provides embedder-level functionality to BluetoothDelegateImpl in WebLayer. -class WebLayerBluetoothDelegateImplClient - : public permissions::BluetoothDelegateImpl::Client { - public: - WebLayerBluetoothDelegateImplClient(); - ~WebLayerBluetoothDelegateImplClient() override; - - WebLayerBluetoothDelegateImplClient( - const WebLayerBluetoothDelegateImplClient&) = delete; - WebLayerBluetoothDelegateImplClient& operator=( - const WebLayerBluetoothDelegateImplClient&) = delete; - - // BluetoothDelegateImpl::Client implementation: - permissions::BluetoothChooserContext* GetBluetoothChooserContext( - content::RenderFrameHost* frame) override; - std::unique_ptr<content::BluetoothChooser> RunBluetoothChooser( - content::RenderFrameHost* frame, - const content::BluetoothChooser::EventHandler& event_handler) override; - std::unique_ptr<content::BluetoothScanningPrompt> ShowBluetoothScanningPrompt( - content::RenderFrameHost* frame, - const content::BluetoothScanningPrompt::EventHandler& event_handler) - override; - - void ShowBluetoothDevicePairDialog( - content::RenderFrameHost* frame, - const std::u16string& device_identifier, - content::BluetoothDelegate::PairPromptCallback callback, - content::BluetoothDelegate::PairingKind, - const absl::optional<std::u16string>& pin) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_DELEGATE_IMPL_CLIENT_H_
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.cc b/weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.cc deleted file mode 100644 index c2be1ae7..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.h" - -#include "base/android/jni_android.h" -#include "components/security_state/content/content_utils.h" -#include "weblayer/browser/java/jni/WebLayerBluetoothScanningPromptAndroidDelegate_jni.h" - -namespace weblayer { - -WebLayerBluetoothScanningPromptAndroidDelegate:: - WebLayerBluetoothScanningPromptAndroidDelegate() { - JNIEnv* env = base::android::AttachCurrentThread(); - java_delegate_.Reset( - Java_WebLayerBluetoothScanningPromptAndroidDelegate_create(env)); -} - -WebLayerBluetoothScanningPromptAndroidDelegate:: - ~WebLayerBluetoothScanningPromptAndroidDelegate() = default; - -base::android::ScopedJavaLocalRef<jobject> -WebLayerBluetoothScanningPromptAndroidDelegate::GetJavaObject() { - return base::android::ScopedJavaLocalRef<jobject>(java_delegate_); -} - -security_state::SecurityLevel -WebLayerBluetoothScanningPromptAndroidDelegate::GetSecurityLevel( - content::WebContents* web_contents) { - auto state = security_state::GetVisibleSecurityState(web_contents); - return security_state::GetSecurityLevel( - *state, - /*used_policy_installed_certificate=*/false); -} - -} // namespace weblayer
diff --git a/weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.h b/weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.h deleted file mode 100644 index fd340c39b..0000000 --- a/weblayer/browser/bluetooth/weblayer_bluetooth_scanning_prompt_android_delegate.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_SCANNING_PROMPT_ANDROID_DELEGATE_H_ -#define WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_SCANNING_PROMPT_ANDROID_DELEGATE_H_ - -#include "components/permissions/android/bluetooth_scanning_prompt_android_delegate.h" - -#include "base/android/scoped_java_ref.h" - -namespace weblayer { - -// The implementation of BluetoothScanningPromptAndroidDelegate for WebLayer. -class WebLayerBluetoothScanningPromptAndroidDelegate - : public permissions::BluetoothScanningPromptAndroidDelegate { - public: - WebLayerBluetoothScanningPromptAndroidDelegate(); - - WebLayerBluetoothScanningPromptAndroidDelegate( - const WebLayerBluetoothScanningPromptAndroidDelegate&) = delete; - WebLayerBluetoothScanningPromptAndroidDelegate& operator=( - const WebLayerBluetoothScanningPromptAndroidDelegate&) = delete; - - ~WebLayerBluetoothScanningPromptAndroidDelegate() override; - - // permissions::BluetoothScanningPromptAndroidDelegate implementation: - base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override; - security_state::SecurityLevel GetSecurityLevel( - content::WebContents* web_contents) override; - - private: - base::android::ScopedJavaGlobalRef<jobject> java_delegate_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BLUETOOTH_WEBLAYER_BLUETOOTH_SCANNING_PROMPT_ANDROID_DELEGATE_H_
diff --git a/weblayer/browser/browser_context_impl.cc b/weblayer/browser/browser_context_impl.cc deleted file mode 100644 index dee3be0..0000000 --- a/weblayer/browser/browser_context_impl.cc +++ /dev/null
@@ -1,368 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_context_impl.h" - -#include "base/memory/raw_ptr.h" -#include "base/threading/thread_restrictions.h" -#include "build/build_config.h" -#include "components/background_sync/background_sync_controller_impl.h" -#include "components/blocked_content/safe_browsing_triggered_popup_blocker.h" -#include "components/client_hints/browser/client_hints.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/download/public/common/in_progress_download_manager.h" -#include "components/embedder_support/pref_names.h" -#include "components/heavy_ad_intervention/heavy_ad_service.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/language/core/browser/language_prefs.h" -#include "components/origin_trials/browser/origin_trials.h" -#include "components/payments/core/payment_prefs.h" -#include "components/permissions/permission_manager.h" -#include "components/pref_registry/pref_registry_syncable.h" -#include "components/prefs/in_memory_pref_store.h" -#include "components/prefs/json_pref_store.h" -#include "components/prefs/pref_service.h" -#include "components/prefs/pref_service_factory.h" -#include "components/reduce_accept_language/browser/reduce_accept_language_service.h" -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h" -#include "components/site_isolation/pref_names.h" -#include "components/site_isolation/site_isolation_policy.h" -#include "components/translate/core/browser/translate_pref_names.h" -#include "components/translate/core/browser/translate_prefs.h" -#include "components/user_prefs/user_prefs.h" -#include "components/variations/proto/study.pb.h" -#include "components/variations/variations.mojom.h" -#include "components/variations/variations_client.h" -#include "components/variations/variations_ids_provider.h" -#include "content/public/browser/device_service.h" -#include "content/public/browser/download_request_utils.h" -#include "content/public/browser/resource_context.h" -#include "content/public/browser/storage_partition.h" -#include "third_party/blink/public/common/web_preferences/web_preferences.h" -#include "weblayer/browser/background_fetch/background_fetch_delegate_factory.h" -#include "weblayer/browser/background_fetch/background_fetch_delegate_impl.h" -#include "weblayer/browser/background_sync/background_sync_controller_factory.h" -#include "weblayer/browser/browsing_data_remover_delegate.h" -#include "weblayer/browser/browsing_data_remover_delegate_factory.h" -#include "weblayer/browser/client_hints_factory.h" -#include "weblayer/browser/heavy_ad_service_factory.h" -#include "weblayer/browser/origin_trials_factory.h" -#include "weblayer/browser/permissions/permission_manager_factory.h" -#include "weblayer/browser/reduce_accept_language_factory.h" -#include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h" -#include "weblayer/public/common/switches.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/path_utils.h" -#include "components/browser_ui/accessibility/android/font_size_prefs_android.h" -#include "components/cdm/browser/media_drm_storage_impl.h" // nogncheck -#include "components/permissions/contexts/geolocation_permission_context_android.h" -#include "components/site_engagement/content/site_engagement_service.h" -#include "components/unified_consent/pref_names.h" -#elif BUILDFLAG(IS_WIN) -#include <windows.h> - -#include <KnownFolders.h> -#include <shlobj.h> -#include "base/win/scoped_co_mem.h" -#elif BUILDFLAG(IS_POSIX) -#include "base/nix/xdg_util.h" -#endif - -namespace weblayer { - -namespace { - -// Ignores origin security check. DownloadManagerImpl will provide its own -// implementation when InProgressDownloadManager object is passed to it. -bool IgnoreOriginSecurityCheck(const GURL& url) { - return true; -} - -void BindWakeLockProvider( - mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) { - content::GetDeviceService().BindWakeLockProvider(std::move(receiver)); -} - -} // namespace - -namespace prefs { -// Used to persist the public SettingType::NETWORK_PREDICTION_ENABLED API. -const char kNoStatePrefetchEnabled[] = "weblayer.network_prediction_enabled"; - -// Used to persist the public SettingType::UKM_ENABLED API. -const char kUkmEnabled[] = "weblayer.ukm_enabled"; -} // namespace prefs - -class ResourceContextImpl : public content::ResourceContext { - public: - ResourceContextImpl() = default; - - ResourceContextImpl(const ResourceContextImpl&) = delete; - ResourceContextImpl& operator=(const ResourceContextImpl&) = delete; - - ~ResourceContextImpl() override = default; -}; - -BrowserContextImpl::BrowserContextImpl(ProfileImpl* profile_impl, - const base::FilePath& path) - : profile_impl_(profile_impl), - path_(path), - simple_factory_key_(path, path.empty()), - resource_context_(new ResourceContextImpl()), - download_delegate_(GetDownloadManager()) { - CreateUserPrefService(); - - BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices( - this); - - auto* heavy_ad_service = HeavyAdServiceFactory::GetForBrowserContext(this); - if (IsOffTheRecord()) { - heavy_ad_service->InitializeOffTheRecord(); - } else { - heavy_ad_service->Initialize(GetPath()); - } - - site_isolation::SiteIsolationPolicy::ApplyPersistedIsolatedOrigins(this); - - // Ensure the delegate is initialized early to give it time to load its - // persistence. - GetOriginTrialsControllerDelegate(); -} - -BrowserContextImpl::~BrowserContextImpl() { - BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( - this); -} - -base::FilePath BrowserContextImpl::GetDefaultDownloadDirectory() { - // Note: if we wanted to productionize this on Windows/Linux, refactor - // src/chrome's GetDefaultDownloadDirectory. - base::FilePath download_dir; -#if BUILDFLAG(IS_ANDROID) - base::android::GetDownloadsDirectory(&download_dir); -#elif BUILDFLAG(IS_WIN) - base::win::ScopedCoMem<wchar_t> path_buf; - if (SUCCEEDED( - SHGetKnownFolderPath(FOLDERID_Downloads, 0, nullptr, &path_buf))) { - download_dir = base::FilePath(path_buf.get()); - } -#else - download_dir = base::nix::GetXDGUserDirectory("DOWNLOAD", "Downloads"); -#endif - return download_dir; -} - -std::unique_ptr<content::ZoomLevelDelegate> -BrowserContextImpl::CreateZoomLevelDelegate(const base::FilePath&) { - return nullptr; -} - -base::FilePath BrowserContextImpl::GetPath() { - return path_; -} - -bool BrowserContextImpl::IsOffTheRecord() { - return path_.empty(); -} - -content::DownloadManagerDelegate* -BrowserContextImpl::GetDownloadManagerDelegate() { - return &download_delegate_; -} - -content::ResourceContext* BrowserContextImpl::GetResourceContext() { - return resource_context_.get(); -} - -content::BrowserPluginGuestManager* BrowserContextImpl::GetGuestManager() { - return nullptr; -} - -storage::SpecialStoragePolicy* BrowserContextImpl::GetSpecialStoragePolicy() { - return nullptr; -} - -content::PlatformNotificationService* -BrowserContextImpl::GetPlatformNotificationService() { - return nullptr; -} - -content::PushMessagingService* BrowserContextImpl::GetPushMessagingService() { - return nullptr; -} - -content::StorageNotificationService* -BrowserContextImpl::GetStorageNotificationService() { - return nullptr; -} - -content::SSLHostStateDelegate* BrowserContextImpl::GetSSLHostStateDelegate() { - return StatefulSSLHostStateDelegateFactory::GetForBrowserContext(this); -} - -content::PermissionControllerDelegate* -BrowserContextImpl::GetPermissionControllerDelegate() { - return PermissionManagerFactory::GetForBrowserContext(this); -} - -content::ClientHintsControllerDelegate* -BrowserContextImpl::GetClientHintsControllerDelegate() { - return ClientHintsFactory::GetForBrowserContext(this); -} - -content::BackgroundFetchDelegate* -BrowserContextImpl::GetBackgroundFetchDelegate() { - return BackgroundFetchDelegateFactory::GetForBrowserContext(this); -} - -content::BackgroundSyncController* -BrowserContextImpl::GetBackgroundSyncController() { - return BackgroundSyncControllerFactory::GetForBrowserContext(this); -} - -content::BrowsingDataRemoverDelegate* -BrowserContextImpl::GetBrowsingDataRemoverDelegate() { - return BrowsingDataRemoverDelegateFactory::GetForBrowserContext(this); -} - -content::ReduceAcceptLanguageControllerDelegate* -BrowserContextImpl::GetReduceAcceptLanguageControllerDelegate() { - return ReduceAcceptLanguageFactory::GetForBrowserContext(this); -} - -content::OriginTrialsControllerDelegate* -BrowserContextImpl::GetOriginTrialsControllerDelegate() { - return OriginTrialsFactory::GetForBrowserContext(this); -} - -std::unique_ptr<download::InProgressDownloadManager> -BrowserContextImpl::RetrieveInProgressDownloadManager() { - // Override this to provide a connection to the wake lock service. - auto download_manager = std::make_unique<download::InProgressDownloadManager>( - nullptr, path_, - path_.empty() ? nullptr - : GetDefaultStoragePartition()->GetProtoDatabaseProvider(), - base::BindRepeating(&IgnoreOriginSecurityCheck), - base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe), - base::BindRepeating(&BindWakeLockProvider)); - -#if BUILDFLAG(IS_ANDROID) - download_manager->set_default_download_dir(GetDefaultDownloadDirectory()); -#endif - - return download_manager; -} - -content::ContentIndexProvider* BrowserContextImpl::GetContentIndexProvider() { - return nullptr; -} - -void BrowserContextImpl::CreateUserPrefService() { - auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>(); - RegisterPrefs(pref_registry.get()); - - PrefServiceFactory pref_service_factory; - if (IsOffTheRecord()) { - pref_service_factory.set_user_prefs( - base::MakeRefCounted<InMemoryPrefStore>()); - } else { - pref_service_factory.set_user_prefs(base::MakeRefCounted<JsonPrefStore>( - path_.Append(FILE_PATH_LITERAL("Preferences")))); - } - { - // Creating the prefs service may require reading the preferences from disk. - base::ScopedAllowBlocking allow_io; - user_pref_service_ = pref_service_factory.Create(pref_registry); - } - // Note: UserPrefs::Set also ensures that the user_pref_service_ has not - // been set previously. - user_prefs::UserPrefs::Set(this, user_pref_service_.get()); -} - -void BrowserContextImpl::RegisterPrefs( - user_prefs::PrefRegistrySyncable* pref_registry) { - pref_registry->RegisterBooleanPref(prefs::kNoStatePrefetchEnabled, true); - pref_registry->RegisterBooleanPref(prefs::kUkmEnabled, false); - - // This pref is used by captive_portal::CaptivePortalService (as well as other - // potential use cases in the future, as it is used for various purposes - // through //chrome). - pref_registry->RegisterBooleanPref( - embedder_support::kAlternateErrorPagesEnabled, true); - pref_registry->RegisterListPref( - site_isolation::prefs::kUserTriggeredIsolatedOrigins); - pref_registry->RegisterDictionaryPref( - site_isolation::prefs::kWebTriggeredIsolatedOrigins); - - StatefulSSLHostStateDelegate::RegisterProfilePrefs(pref_registry); - HostContentSettingsMap::RegisterProfilePrefs(pref_registry); - safe_browsing::RegisterProfilePrefs(pref_registry); - language::LanguagePrefs::RegisterProfilePrefs(pref_registry); - translate::TranslatePrefs::RegisterProfilePrefs(pref_registry); - blocked_content::SafeBrowsingTriggeredPopupBlocker::RegisterProfilePrefs( - pref_registry); - payments::RegisterProfilePrefs(pref_registry); - pref_registry->RegisterBooleanPref( - translate::prefs::kOfferTranslateEnabled, true, - user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); -#if BUILDFLAG(IS_ANDROID) - site_engagement::SiteEngagementService::RegisterProfilePrefs(pref_registry); - cdm::MediaDrmStorageImpl::RegisterProfilePrefs(pref_registry); - permissions::GeolocationPermissionContextAndroid::RegisterProfilePrefs( - pref_registry); - pref_registry->RegisterBooleanPref( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, false); - - pref_registry->RegisterDoublePref(browser_ui::prefs::kWebKitFontScaleFactor, - 1.0); - blink::web_pref::WebPreferences pref_defaults; - pref_registry->RegisterBooleanPref(browser_ui::prefs::kWebKitForceEnableZoom, - pref_defaults.force_enable_zoom); - pref_registry->SetDefaultPrefValue(::prefs::kSafeBrowsingEnhanced, - base::Value(true)); -#endif - - BrowserContextDependencyManager::GetInstance() - ->RegisterProfilePrefsForServices(pref_registry); -} - -class BrowserContextImpl::WebLayerVariationsClient - : public variations::VariationsClient { - public: - explicit WebLayerVariationsClient(content::BrowserContext* browser_context) - : browser_context_(browser_context) {} - - ~WebLayerVariationsClient() override = default; - - bool IsOffTheRecord() const override { - return browser_context_->IsOffTheRecord(); - } - - variations::mojom::VariationsHeadersPtr GetVariationsHeaders() - const override { - // As the embedder supplies the set of ids, the signed-in state should be - // ignored. The value supplied (`is_signed_in`) doesn't matter as - // VariationsIdsProvider is configured to ignore the signed in state. - const bool is_signed_in = true; - DCHECK_EQ(variations::VariationsIdsProvider::Mode::kIgnoreSignedInState, - variations::VariationsIdsProvider::GetInstance()->mode()); - return variations::VariationsIdsProvider::GetInstance() - ->GetClientDataHeaders(is_signed_in); - } - - private: - raw_ptr<content::BrowserContext> browser_context_; -}; - -variations::VariationsClient* BrowserContextImpl::GetVariationsClient() { - if (!weblayer_variations_client_) { - weblayer_variations_client_ = - std::make_unique<WebLayerVariationsClient>(this); - } - return weblayer_variations_client_.get(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/browser_context_impl.h b/weblayer/browser/browser_context_impl.h deleted file mode 100644 index b9efe78..0000000 --- a/weblayer/browser/browser_context_impl.h +++ /dev/null
@@ -1,112 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_CONTEXT_IMPL_H_ -#define WEBLAYER_BROWSER_BROWSER_CONTEXT_IMPL_H_ - -#include "base/files/file_path.h" -#include "base/memory/raw_ptr.h" -#include "build/build_config.h" -#include "components/keyed_service/core/simple_factory_key.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "weblayer/browser/download_manager_delegate_impl.h" -#include "weblayer/public/profile.h" - -namespace user_prefs { -class PrefRegistrySyncable; -} -class PrefService; - -namespace weblayer { -class ProfileImpl; -class ResourceContextImpl; - -namespace prefs { -// WebLayer specific pref names. -extern const char kNoStatePrefetchEnabled[]; -extern const char kUkmEnabled[]; -} // namespace prefs - -class BrowserContextImpl : public content::BrowserContext { - public: - BrowserContextImpl(ProfileImpl* profile_impl, const base::FilePath& path); - ~BrowserContextImpl() override; - BrowserContextImpl(const BrowserContextImpl&) = delete; - BrowserContextImpl& operator=(const BrowserContextImpl&) = delete; - - static base::FilePath GetDefaultDownloadDirectory(); - - // BrowserContext implementation: - std::unique_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate( - const base::FilePath&) override; - base::FilePath GetPath() override; - bool IsOffTheRecord() override; - variations::VariationsClient* GetVariationsClient() override; - content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; - - content::ResourceContext* GetResourceContext() override; - content::BrowserPluginGuestManager* GetGuestManager() override; - storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; - content::PlatformNotificationService* GetPlatformNotificationService() - override; - content::PushMessagingService* GetPushMessagingService() override; - content::StorageNotificationService* GetStorageNotificationService() override; - content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; - content::PermissionControllerDelegate* GetPermissionControllerDelegate() - override; - content::ClientHintsControllerDelegate* GetClientHintsControllerDelegate() - override; - content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override; - content::BackgroundSyncController* GetBackgroundSyncController() override; - content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate() - override; - std::unique_ptr<download::InProgressDownloadManager> - RetrieveInProgressDownloadManager() override; - content::ContentIndexProvider* GetContentIndexProvider() override; - content::ReduceAcceptLanguageControllerDelegate* - GetReduceAcceptLanguageControllerDelegate() override; - content::OriginTrialsControllerDelegate* GetOriginTrialsControllerDelegate() - override; - - ProfileImpl* profile_impl() const { return profile_impl_; } - - PrefService* pref_service() const { return user_pref_service_.get(); } - - SimpleFactoryKey* simple_factory_key() { return &simple_factory_key_; } - - private: - class WebLayerVariationsClient; - - // Creates a simple in-memory pref service. - // TODO(timvolodine): Investigate whether WebLayer needs persistent pref - // service. - void CreateUserPrefService(); - - // Registers the preferences that WebLayer accesses. - void RegisterPrefs(user_prefs::PrefRegistrySyncable* pref_registry); - - const raw_ptr<ProfileImpl> profile_impl_; - base::FilePath path_; - // In Chrome, a SimpleFactoryKey is used as a minimal representation of a - // BrowserContext used before full browser mode has started. WebLayer doesn't - // have an incomplete mode, so this is just a member variable for - // compatibility with components that expect a SimpleFactoryKey. - SimpleFactoryKey simple_factory_key_; - // ResourceContext needs to be deleted on the IO thread in general (and in - // particular due to the destruction of the safebrowsing mojo interface - // that has been added in ContentBrowserClient::ExposeInterfacesToRenderer - // on IO thread, see crbug.com/1029317). Also this is similar to how Chrome - // handles ProfileIOData. - // TODO(timvolodine): consider a more general Profile shutdown/destruction - // sequence for the IO/UI bits (crbug.com/1029879). - std::unique_ptr<ResourceContextImpl, content::BrowserThread::DeleteOnIOThread> - resource_context_; - DownloadManagerDelegateImpl download_delegate_; - std::unique_ptr<PrefService> user_pref_service_; - std::unique_ptr<WebLayerVariationsClient> weblayer_variations_client_; -}; -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_CONTEXT_IMPL_H_
diff --git a/weblayer/browser/browser_fragment_impl.cc b/weblayer/browser/browser_fragment_impl.cc deleted file mode 100644 index 5d44518..0000000 --- a/weblayer/browser/browser_fragment_impl.cc +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_fragment_impl.h" - -#include "weblayer/browser/browser_fragment_list.h" -#include "weblayer/browser/java/jni/BrowserFragmentImpl_jni.h" - -namespace weblayer { - -BrowserFragmentImpl::BrowserFragmentImpl() { - BrowserFragmentList::GetInstance()->AddBrowserFragment(this); -} - -BrowserFragmentImpl::~BrowserFragmentImpl() { - BrowserFragmentList::GetInstance()->RemoveBrowserFragment(this); -} - -void BrowserFragmentImpl::OnFragmentResume(JNIEnv* env) { - UpdateFragmentResumedState(true); -} - -void BrowserFragmentImpl::OnFragmentPause(JNIEnv* env) { - UpdateFragmentResumedState(false); -} - -void BrowserFragmentImpl::DeleteBrowserFragment(JNIEnv* env) { - delete this; -} - -void BrowserFragmentImpl::UpdateFragmentResumedState(bool state) { - const bool old_has_at_least_one_active_browser = - BrowserFragmentList::GetInstance()->HasAtLeastOneResumedBrowser(); - fragment_resumed_ = state; - if (old_has_at_least_one_active_browser != - BrowserFragmentList::GetInstance()->HasAtLeastOneResumedBrowser()) { - BrowserFragmentList::GetInstance() - ->NotifyHasAtLeastOneResumedBrowserFragmentChanged(); - } -} - -static jlong JNI_BrowserFragmentImpl_CreateBrowserFragment(JNIEnv* env) { - return reinterpret_cast<intptr_t>(new BrowserFragmentImpl()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/browser_fragment_impl.h b/weblayer/browser/browser_fragment_impl.h deleted file mode 100644 index 5e158f9e..0000000 --- a/weblayer/browser/browser_fragment_impl.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_FRAGMENT_IMPL_H_ -#define WEBLAYER_BROWSER_BROWSER_FRAGMENT_IMPL_H_ - -#include "base/android/jni_android.h" - -namespace weblayer { - -class BrowserFragmentImpl { - public: - BrowserFragmentImpl(); - ~BrowserFragmentImpl(); - BrowserFragmentImpl(const BrowserFragmentImpl&) = delete; - BrowserFragmentImpl& operator=(const BrowserFragmentImpl&) = delete; - - void OnFragmentResume(JNIEnv* env); - void OnFragmentPause(JNIEnv* env); - - void DeleteBrowserFragment(JNIEnv* env); - - bool fragment_resumed() { return fragment_resumed_; } - - private: - void UpdateFragmentResumedState(bool state); - - bool fragment_resumed_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_FRAGMENT_IMPL_H_
diff --git a/weblayer/browser/browser_fragment_list.cc b/weblayer/browser/browser_fragment_list.cc deleted file mode 100644 index b54cda2b3..0000000 --- a/weblayer/browser/browser_fragment_list.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_fragment_list.h" - -#include "base/no_destructor.h" -#include "weblayer/browser/browser_fragment_impl.h" -#include "weblayer/browser/browser_fragment_list_observer.h" - -namespace weblayer { - -inline BrowserFragmentList::BrowserFragmentList() = default; -inline BrowserFragmentList::~BrowserFragmentList() = default; - -// static -BrowserFragmentList* BrowserFragmentList::GetInstance() { - static base::NoDestructor<BrowserFragmentList> browser_fragment_list; - return browser_fragment_list.get(); -} - -void BrowserFragmentList::AddBrowserFragment( - BrowserFragmentImpl* browser_fragment) { - CHECK(!browser_fragments_.contains(browser_fragment)); - browser_fragments_.insert(browser_fragment); -} - -void BrowserFragmentList::RemoveBrowserFragment( - BrowserFragmentImpl* browser_fragment) { - CHECK(browser_fragments_.contains(browser_fragment)); - browser_fragments_.erase(browser_fragment); -} - -void BrowserFragmentList::AddObserver(BrowserFragmentListObserver* observer) { - observers_.AddObserver(observer); -} - -void BrowserFragmentList::RemoveObserver( - BrowserFragmentListObserver* observer) { - observers_.RemoveObserver(observer); -} - -bool BrowserFragmentList::HasAtLeastOneResumedBrowser() { - return base::ranges::any_of(browser_fragments_, - &BrowserFragmentImpl::fragment_resumed); -} - -void BrowserFragmentList::NotifyHasAtLeastOneResumedBrowserFragmentChanged() { - const bool value = HasAtLeastOneResumedBrowser(); - for (BrowserFragmentListObserver& observer : observers_) { - observer.OnHasAtLeastOneResumedBrowserFragmentStateChanged(value); - } -} - -} // namespace weblayer
diff --git a/weblayer/browser/browser_fragment_list.h b/weblayer/browser/browser_fragment_list.h deleted file mode 100644 index 740ee1a..0000000 --- a/weblayer/browser/browser_fragment_list.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_FRAGMENT_LIST_H_ -#define WEBLAYER_BROWSER_BROWSER_FRAGMENT_LIST_H_ - -#include "base/containers/flat_set.h" -#include "base/no_destructor.h" -#include "base/observer_list.h" - -namespace weblayer { - -class BrowserFragmentImpl; -class BrowserFragmentListObserver; - -// Tracks the set of browsers. -class BrowserFragmentList { - public: - BrowserFragmentList(); - ~BrowserFragmentList(); - - BrowserFragmentList(const BrowserFragmentList&) = delete; - BrowserFragmentList& operator=(const BrowserFragmentList&) = delete; - - static BrowserFragmentList* GetInstance(); - - const base::flat_set<BrowserFragmentImpl*>& browser_fragments() { - return browser_fragments_; - } - - // Returns true if there is at least one BrowserFragmentImpl in a resumed - // state. - bool HasAtLeastOneResumedBrowser(); - - void AddObserver(BrowserFragmentListObserver* observer); - void RemoveObserver(BrowserFragmentListObserver* observer); - - private: - friend class BrowserFragmentImpl; - friend class base::NoDestructor<BrowserFragmentList>; - - void AddBrowserFragment(BrowserFragmentImpl* browser_fragment); - void RemoveBrowserFragment(BrowserFragmentImpl* browser_fragment); - - void NotifyHasAtLeastOneResumedBrowserFragmentChanged(); - - base::flat_set<BrowserFragmentImpl*> browser_fragments_; - base::ObserverList<BrowserFragmentListObserver> observers_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_FRAGMENT_LIST_H_
diff --git a/weblayer/browser/browser_fragment_list_observer.h b/weblayer/browser/browser_fragment_list_observer.h deleted file mode 100644 index 86e7acd..0000000 --- a/weblayer/browser/browser_fragment_list_observer.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_FRAGMENT_LIST_OBSERVER_H_ -#define WEBLAYER_BROWSER_BROWSER_FRAGMENT_LIST_OBSERVER_H_ - -#include "base/observer_list_types.h" -#include "build/build_config.h" - -namespace weblayer { - -class BrowserFragmentListObserver : public base::CheckedObserver { - public: - // Called when the value of BrowserFragmentList::HasAtLeastOneResumedBrowser() - // changes. - virtual void OnHasAtLeastOneResumedBrowserFragmentStateChanged( - bool new_value) {} - - protected: - ~BrowserFragmentListObserver() override = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_FRAGMENT_LIST_OBSERVER_H_
diff --git a/weblayer/browser/browser_impl.cc b/weblayer/browser/browser_impl.cc deleted file mode 100644 index 6bfccd1e..0000000 --- a/weblayer/browser/browser_impl.cc +++ /dev/null
@@ -1,393 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_impl.h" - -#include "base/containers/unique_ptr_adapters.h" -#include "base/memory/ptr_util.h" -#include "base/path_service.h" -#include "base/ranges/algorithm.h" -#include "build/build_config.h" -#include "components/base32/base32.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/web_contents.h" -#include "third_party/blink/public/common/web_preferences/web_preferences.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_list.h" -#include "weblayer/browser/feature_list_creator.h" -#include "weblayer/browser/persistence/browser_persister.h" -#include "weblayer/browser/persistence/browser_persister_file_utils.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/common/weblayer_paths.h" -#include "weblayer/public/browser_observer.h" -#include "weblayer/public/browser_restore_observer.h" - -#include "base/android/callback_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/json/json_writer.h" -#include "components/browser_ui/accessibility/android/font_size_prefs_android.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/java/jni/BrowserImpl_jni.h" - -using base::android::AttachCurrentThread; -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -// This MUST match the values defined in -// org.chromium.weblayer_private.interfaces.DarkModeStrategy. -enum class DarkModeStrategy { - kWebThemeDarkeningOnly = 0, - kUserAgentDarkeningOnly = 1, - kPreferWebThemeOverUserAgentDarkening = 2, -}; - -// static -constexpr char BrowserImpl::kPersistenceFilePrefix[]; - -std::unique_ptr<Browser> Browser::Create( - Profile* profile, - const PersistenceInfo* persistence_info) { - // BrowserImpl's constructor is private. - auto browser = - base::WrapUnique(new BrowserImpl(static_cast<ProfileImpl*>(profile))); - if (persistence_info) - browser->RestoreStateIfNecessary(*persistence_info); - - DCHECK(FeatureListCreator::GetInstance()); - FeatureListCreator::GetInstance()->OnBrowserCreated(); - - return browser; -} - -BrowserImpl::~BrowserImpl() { - // Android side should always remove tabs first (because the Java Tab class - // owns the C++ Tab). See BrowserImpl.destroy() (in the Java BrowserImpl - // class). - DCHECK(tabs_.empty()); - BrowserList::GetInstance()->RemoveBrowser(this); - - if (BrowserList::GetInstance()->browsers().empty()) - BrowserProcess::GetInstance()->StopSafeBrowsingService(); -} - -TabImpl* BrowserImpl::CreateTabForSessionRestore( - std::unique_ptr<content::WebContents> web_contents, - const std::string& guid) { - if (!web_contents) { - content::WebContents::CreateParams create_params( - profile_->GetBrowserContext()); - web_contents = content::WebContents::Create(create_params); - } - std::unique_ptr<TabImpl> tab = - std::make_unique<TabImpl>(profile_, std::move(web_contents), guid); - Java_BrowserImpl_createJavaTabForNativeTab( - AttachCurrentThread(), java_impl_, reinterpret_cast<jlong>(tab.get())); - return AddTab(std::move(tab)); -} - -TabImpl* BrowserImpl::CreateTab( - std::unique_ptr<content::WebContents> web_contents) { - return CreateTabForSessionRestore(std::move(web_contents), std::string()); -} - -bool BrowserImpl::CompositorHasSurface() { - return Java_BrowserImpl_compositorHasSurface(AttachCurrentThread(), - java_impl_); -} - -void BrowserImpl::AddTab(JNIEnv* env, long native_tab) { - AddTab(reinterpret_cast<TabImpl*>(native_tab)); -} - -ScopedJavaLocalRef<jobjectArray> BrowserImpl::GetTabs(JNIEnv* env) { - ScopedJavaLocalRef<jclass> clazz = - base::android::GetClass(env, "org/chromium/weblayer_private/TabImpl"); - jobjectArray tabs = env->NewObjectArray(tabs_.size(), clazz.obj(), - nullptr /* initialElement */); - base::android::CheckException(env); - - for (size_t i = 0; i < tabs_.size(); ++i) { - TabImpl* tab = static_cast<TabImpl*>(tabs_[i].get()); - env->SetObjectArrayElement(tabs, i, tab->GetJavaTab().obj()); - } - return ScopedJavaLocalRef<jobjectArray>(env, tabs); -} - -void BrowserImpl::SetActiveTab(JNIEnv* env, long native_tab) { - SetActiveTab(reinterpret_cast<TabImpl*>(native_tab)); -} - -ScopedJavaLocalRef<jobject> BrowserImpl::GetActiveTab(JNIEnv* env) { - if (!active_tab_) - return nullptr; - return ScopedJavaLocalRef<jobject>(active_tab_->GetJavaTab()); -} - -void BrowserImpl::PrepareForShutdown(JNIEnv* env) { - PrepareForShutdown(); -} - -void BrowserImpl::RestoreStateIfNecessary( - JNIEnv* env, - const JavaParamRef<jstring>& j_persistence_id) { - if (!j_persistence_id.obj()) - return; - - Browser::PersistenceInfo persistence_info; - persistence_info.id = - base::android::ConvertJavaStringToUTF8(j_persistence_id); - if (persistence_info.id.empty()) - return; - - RestoreStateIfNecessary(persistence_info); -} - -void BrowserImpl::WebPreferencesChanged(JNIEnv* env) { - OnWebPreferenceChanged(std::string()); -} - -void BrowserImpl::SetWebPreferences(blink::web_pref::WebPreferences* prefs) { - PrefService* pref_service = profile()->GetBrowserContext()->pref_service(); - prefs->password_echo_enabled = Java_BrowserImpl_getPasswordEchoEnabled( - AttachCurrentThread(), java_impl_); - prefs->font_scale_factor = static_cast<float>( - pref_service->GetDouble(browser_ui::prefs::kWebKitFontScaleFactor)); - prefs->force_enable_zoom = - pref_service->GetBoolean(browser_ui::prefs::kWebKitForceEnableZoom); - bool is_dark = - Java_BrowserImpl_getDarkThemeEnabled(AttachCurrentThread(), java_impl_); - if (is_dark) { - DarkModeStrategy dark_strategy = - static_cast<DarkModeStrategy>(Java_BrowserImpl_getDarkModeStrategy( - AttachCurrentThread(), java_impl_)); - switch (dark_strategy) { - case DarkModeStrategy::kPreferWebThemeOverUserAgentDarkening: - // Blink's behavior is that if the preferred color scheme matches the - // browser's color scheme, then force dark will be disabled, otherwise - // the preferred color scheme will be reset to 'light'. Therefore - // when enabling force dark, we also set the preferred color scheme to - // dark so that dark themed content will be preferred over force - // darkening. - prefs->preferred_color_scheme = - blink::mojom::PreferredColorScheme::kDark; - prefs->force_dark_mode_enabled = true; - break; - case DarkModeStrategy::kWebThemeDarkeningOnly: - prefs->preferred_color_scheme = - blink::mojom::PreferredColorScheme::kDark; - prefs->force_dark_mode_enabled = false; - break; - case DarkModeStrategy::kUserAgentDarkeningOnly: - prefs->preferred_color_scheme = - blink::mojom::PreferredColorScheme::kLight; - prefs->force_dark_mode_enabled = true; - break; - } - } else { - prefs->preferred_color_scheme = blink::mojom::PreferredColorScheme::kLight; - prefs->force_dark_mode_enabled = false; - } -} - -void BrowserImpl::RemoveTabBeforeDestroyingFromJava(Tab* tab) { - // The java side owns the Tab, and is going to delete it shortly. See - // JNI_TabImpl_DeleteTab. - RemoveTab(tab).release(); -} - -void BrowserImpl::AddTab(Tab* tab) { - DCHECK(tab); - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - std::unique_ptr<Tab> owned_tab; - if (tab_impl->browser()) - owned_tab = tab_impl->browser()->RemoveTab(tab_impl); - else - owned_tab.reset(tab_impl); - AddTab(std::move(owned_tab)); -} - -void BrowserImpl::DestroyTab(Tab* tab) { - // Route destruction through the java side. - Java_BrowserImpl_destroyTabImpl(AttachCurrentThread(), java_impl_, - static_cast<TabImpl*>(tab)->GetJavaTab()); -} - -void BrowserImpl::SetActiveTab(Tab* tab) { - if (GetActiveTab() == tab) - return; - if (active_tab_) - active_tab_->OnLosingActive(); - // TODO: currently the java side sets visibility, this code likely should - // too and it should be removed from the java side. - active_tab_ = static_cast<TabImpl*>(tab); - Java_BrowserImpl_onActiveTabChanged( - AttachCurrentThread(), java_impl_, - active_tab_ ? active_tab_->GetJavaTab() : nullptr); - VisibleSecurityStateOfActiveTabChanged(); - for (BrowserObserver& obs : browser_observers_) - obs.OnActiveTabChanged(active_tab_); - if (active_tab_) - active_tab_->OnGainedActive(); -} - -Tab* BrowserImpl::GetActiveTab() { - return active_tab_; -} - -std::vector<Tab*> BrowserImpl::GetTabs() { - std::vector<Tab*> tabs(tabs_.size()); - for (size_t i = 0; i < tabs_.size(); ++i) - tabs[i] = tabs_[i].get(); - return tabs; -} - -Tab* BrowserImpl::CreateTab() { - return CreateTab(nullptr); -} - -void BrowserImpl::OnRestoreCompleted() { - for (BrowserRestoreObserver& obs : browser_restore_observers_) - obs.OnRestoreCompleted(); - Java_BrowserImpl_onRestoreCompleted(AttachCurrentThread(), java_impl_); -} - -void BrowserImpl::PrepareForShutdown() { - browser_persister_.reset(); -} - -std::string BrowserImpl::GetPersistenceId() { - return persistence_id_; -} - -bool BrowserImpl::IsRestoringPreviousState() { - return browser_persister_ && browser_persister_->is_restore_in_progress(); -} - -void BrowserImpl::AddObserver(BrowserObserver* observer) { - browser_observers_.AddObserver(observer); -} - -void BrowserImpl::RemoveObserver(BrowserObserver* observer) { - browser_observers_.RemoveObserver(observer); -} - -void BrowserImpl::AddBrowserRestoreObserver(BrowserRestoreObserver* observer) { - browser_restore_observers_.AddObserver(observer); -} - -void BrowserImpl::RemoveBrowserRestoreObserver( - BrowserRestoreObserver* observer) { - browser_restore_observers_.RemoveObserver(observer); -} - -void BrowserImpl::VisibleSecurityStateOfActiveTabChanged() { - if (visible_security_state_changed_callback_for_tests_) - std::move(visible_security_state_changed_callback_for_tests_).Run(); - - JNIEnv* env = base::android::AttachCurrentThread(); - Java_BrowserImpl_onVisibleSecurityStateOfActiveTabChanged(env, java_impl_); -} - -BrowserImpl::BrowserImpl(ProfileImpl* profile) : profile_(profile) { - BrowserList::GetInstance()->AddBrowser(this); - - profile_pref_change_registrar_.Init( - profile_->GetBrowserContext()->pref_service()); - auto pref_change_callback = base::BindRepeating( - &BrowserImpl::OnWebPreferenceChanged, base::Unretained(this)); - profile_pref_change_registrar_.Add(browser_ui::prefs::kWebKitFontScaleFactor, - pref_change_callback); - profile_pref_change_registrar_.Add(browser_ui::prefs::kWebKitForceEnableZoom, - pref_change_callback); -} - -void BrowserImpl::RestoreStateIfNecessary( - const PersistenceInfo& persistence_info) { - persistence_id_ = persistence_info.id; - if (!persistence_id_.empty()) { - browser_persister_ = - std::make_unique<BrowserPersister>(GetBrowserPersisterDataPath(), this); - } -} - -TabImpl* BrowserImpl::AddTab(std::unique_ptr<Tab> tab) { - TabImpl* tab_impl = static_cast<TabImpl*>(tab.get()); - DCHECK(!tab_impl->browser()); - tabs_.push_back(std::move(tab)); - tab_impl->set_browser(this); - Java_BrowserImpl_onTabAdded(AttachCurrentThread(), java_impl_, - tab_impl->GetJavaTab()); - for (BrowserObserver& obs : browser_observers_) - obs.OnTabAdded(tab_impl); - return tab_impl; -} - -std::unique_ptr<Tab> BrowserImpl::RemoveTab(Tab* tab) { - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - DCHECK_EQ(this, tab_impl->browser()); - static_cast<TabImpl*>(tab)->set_browser(nullptr); - auto iter = base::ranges::find_if(tabs_, base::MatchesUniquePtr(tab)); - DCHECK(iter != tabs_.end()); - std::unique_ptr<Tab> owned_tab = std::move(*iter); - tabs_.erase(iter); - const bool active_tab_changed = active_tab_ == tab; - if (active_tab_changed) - SetActiveTab(nullptr); - - Java_BrowserImpl_onTabRemoved(AttachCurrentThread(), java_impl_, - tab ? tab_impl->GetJavaTab() : nullptr); - for (BrowserObserver& obs : browser_observers_) - obs.OnTabRemoved(tab, active_tab_changed); - return owned_tab; -} - -base::FilePath BrowserImpl::GetBrowserPersisterDataPath() { - return BuildBasePathForBrowserPersister( - profile_->GetBrowserPersisterDataBaseDir(), GetPersistenceId()); -} - -void BrowserImpl::OnWebPreferenceChanged(const std::string& pref_name) { - for (const auto& tab : tabs_) { - TabImpl* tab_impl = static_cast<TabImpl*>(tab.get()); - tab_impl->WebPreferencesChanged(); - } -} - -// This function is friended. JNI_BrowserImpl_CreateBrowser can not be -// friended, as it requires browser_impl.h to include BrowserImpl_jni.h, which -// is problematic (meaning not really supported and generates compile errors). -BrowserImpl* CreateBrowserForAndroid(ProfileImpl* profile, - const std::string& package_name, - const JavaParamRef<jobject>& java_impl) { - BrowserImpl* browser = new BrowserImpl(profile); - browser->java_impl_ = java_impl; - browser->package_name_ = package_name; - return browser; -} - -static jlong JNI_BrowserImpl_CreateBrowser( - JNIEnv* env, - jlong profile, - const base::android::JavaParamRef<jstring>& package_name, - const JavaParamRef<jobject>& java_impl) { - // The android side does not trigger restore from the constructor as at the - // time this is called not enough of WebLayer has been wired up. Specifically, - // when this is called BrowserImpl.java hasn't obtained the return value so - // that it can't call any functions and further the client side hasn't been - // fully created, leading to all sort of assertions if Tabs are created - // and/or navigations start (which restore may trigger). - return reinterpret_cast<intptr_t>(CreateBrowserForAndroid( - reinterpret_cast<ProfileImpl*>(profile), - base::android::ConvertJavaStringToUTF8(env, package_name), java_impl)); -} - -static void JNI_BrowserImpl_DeleteBrowser(JNIEnv* env, jlong browser) { - delete reinterpret_cast<BrowserImpl*>(browser); -} - -} // namespace weblayer
diff --git a/weblayer/browser/browser_impl.h b/weblayer/browser/browser_impl.h deleted file mode 100644 index b58cdcb7..0000000 --- a/weblayer/browser/browser_impl.h +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_IMPL_H_ -#define WEBLAYER_BROWSER_BROWSER_IMPL_H_ - -#include <memory> -#include <vector> - -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "base/observer_list.h" -#include "build/build_config.h" -#include "components/prefs/pref_change_registrar.h" -#include "weblayer/public/browser.h" - -#include "base/android/scoped_java_ref.h" - -namespace base { -class FilePath; -} - -namespace blink { -namespace web_pref { -struct WebPreferences; -} -} // namespace blink - -namespace content { -class WebContents; -} - -namespace weblayer { - -class BrowserPersister; -class ProfileImpl; -class TabImpl; - -class BrowserImpl : public Browser { - public: - // Prefix used for storing persistence state. - static constexpr char kPersistenceFilePrefix[] = "State"; - - BrowserImpl(const BrowserImpl&) = delete; - BrowserImpl& operator=(const BrowserImpl&) = delete; - ~BrowserImpl() override; - - BrowserPersister* browser_persister() { return browser_persister_.get(); } - - ProfileImpl* profile() { return profile_; } - - // Creates and adds a Tab from session restore. The returned tab is owned by - // this Browser. - TabImpl* CreateTabForSessionRestore( - std::unique_ptr<content::WebContents> web_contents, - const std::string& guid); - TabImpl* CreateTab(std::unique_ptr<content::WebContents> web_contents); - - // Called from BrowserPersister when restore has completed. - void OnRestoreCompleted(); - - const std::string& GetPackageName() { return package_name_; } - - bool CompositorHasSurface(); - - base::android::ScopedJavaGlobalRef<jobject> java_browser() { - return java_impl_; - } - - void AddTab(JNIEnv* env, long native_tab); - base::android::ScopedJavaLocalRef<jobjectArray> GetTabs(JNIEnv* env); - void SetActiveTab(JNIEnv* env, long native_tab); - base::android::ScopedJavaLocalRef<jobject> GetActiveTab(JNIEnv* env); - void PrepareForShutdown(JNIEnv* env); - base::android::ScopedJavaLocalRef<jstring> GetPersistenceId(JNIEnv* env); - void SaveBrowserPersisterIfNecessary(JNIEnv* env); - base::android::ScopedJavaLocalRef<jbyteArray> GetMinimalPersistenceState( - JNIEnv* env, - int max_navigations_per_tab); - void RestoreStateIfNecessary( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& j_persistence_id); - void WebPreferencesChanged(JNIEnv* env); - - bool IsRestoringPreviousState(JNIEnv* env) { - return IsRestoringPreviousState(); - } - - // Used in tests to specify a non-default max (0 means use the default). - std::vector<uint8_t> GetMinimalPersistenceState(int max_navigations_per_tab, - int max_size_in_bytes); - - // Used by tests to specify a callback to listen to changes to visible - // security state. - void set_visible_security_state_callback_for_tests( - base::OnceClosure closure) { - visible_security_state_changed_callback_for_tests_ = std::move(closure); - } - - bool GetPasswordEchoEnabled(); - void SetWebPreferences(blink::web_pref::WebPreferences* prefs); - - // On Android the Java Tab class owns the C++ Tab. DestroyTab() calls to the - // Java Tab class to initiate deletion. This function is called from the Java - // side to remove the tab from the browser and shortly followed by deleting - // the tab. - void RemoveTabBeforeDestroyingFromJava(Tab* tab); - - // Browser: - void AddTab(Tab* tab) override; - void DestroyTab(Tab* tab) override; - void SetActiveTab(Tab* tab) override; - Tab* GetActiveTab() override; - std::vector<Tab*> GetTabs() override; - Tab* CreateTab() override; - void PrepareForShutdown() override; - std::string GetPersistenceId() override; - bool IsRestoringPreviousState() override; - void AddObserver(BrowserObserver* observer) override; - void RemoveObserver(BrowserObserver* observer) override; - void AddBrowserRestoreObserver(BrowserRestoreObserver* observer) override; - void RemoveBrowserRestoreObserver(BrowserRestoreObserver* observer) override; - void VisibleSecurityStateOfActiveTabChanged() override; - - private: - // For creation. - friend class Browser; - - friend BrowserImpl* CreateBrowserForAndroid( - ProfileImpl*, - const std::string&, - const base::android::JavaParamRef<jobject>&); - - explicit BrowserImpl(ProfileImpl* profile); - - void RestoreStateIfNecessary(const PersistenceInfo& persistence_info); - - TabImpl* AddTab(std::unique_ptr<Tab> tab); - std::unique_ptr<Tab> RemoveTab(Tab* tab); - - // Returns the path used by |browser_persister_|. - base::FilePath GetBrowserPersisterDataPath(); - - void OnWebPreferenceChanged(const std::string& pref_name); - - base::android::ScopedJavaGlobalRef<jobject> java_impl_; - base::ObserverList<BrowserObserver> browser_observers_; - base::ObserverList<BrowserRestoreObserver> browser_restore_observers_; - const raw_ptr<ProfileImpl> profile_; - std::vector<std::unique_ptr<Tab>> tabs_; - raw_ptr<TabImpl> active_tab_ = nullptr; - std::string persistence_id_; - std::unique_ptr<BrowserPersister> browser_persister_; - base::OnceClosure visible_security_state_changed_callback_for_tests_; - PrefChangeRegistrar profile_pref_change_registrar_; - std::string package_name_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_IMPL_H_
diff --git a/weblayer/browser/browser_list.cc b/weblayer/browser/browser_list.cc deleted file mode 100644 index 5ab5a16..0000000 --- a/weblayer/browser/browser_list.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_list.h" - -#include <functional> - -#include "base/no_destructor.h" -#include "base/ranges/algorithm.h" -#include "build/build_config.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/browser_list_observer.h" - -#include "weblayer/browser/browser_list_proxy.h" - -namespace weblayer { - -// static -BrowserList* BrowserList::GetInstance() { - static base::NoDestructor<BrowserList> browser_list; - return browser_list.get(); -} - -void BrowserList::AddObserver(BrowserListObserver* observer) { - observers_.AddObserver(observer); -} - -void BrowserList::RemoveObserver(BrowserListObserver* observer) { - observers_.RemoveObserver(observer); -} - -BrowserList::BrowserList() { - browser_list_proxy_ = std::make_unique<BrowserListProxy>(); - AddObserver(browser_list_proxy_.get()); -} - -BrowserList::~BrowserList() { - RemoveObserver(browser_list_proxy_.get()); -} - -void BrowserList::AddBrowser(BrowserImpl* browser) { - DCHECK(!browsers_.contains(browser)); - browsers_.insert(browser); - for (BrowserListObserver& observer : observers_) - observer.OnBrowserCreated(browser); -} - -void BrowserList::RemoveBrowser(BrowserImpl* browser) { - DCHECK(browsers_.contains(browser)); - browsers_.erase(browser); - - for (BrowserListObserver& observer : observers_) - observer.OnBrowserDestroyed(browser); -} - -} // namespace weblayer
diff --git a/weblayer/browser/browser_list.h b/weblayer/browser/browser_list.h deleted file mode 100644 index cb07546c..0000000 --- a/weblayer/browser/browser_list.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_LIST_H_ -#define WEBLAYER_BROWSER_BROWSER_LIST_H_ - -#include "base/containers/flat_set.h" -#include "base/no_destructor.h" -#include "base/observer_list.h" -#include "build/build_config.h" - -namespace weblayer { - -class BrowserImpl; -class BrowserListObserver; - -class BrowserListProxy; - -// Tracks the set of browsers. -class BrowserList { - public: - BrowserList(const BrowserList&) = delete; - BrowserList& operator=(const BrowserList&) = delete; - - static BrowserList* GetInstance(); - - const base::flat_set<BrowserImpl*>& browsers() { return browsers_; } - -#if BUILDFLAG(IS_ANDROID) - // Returns true if there is at least one Browser in a resumed state. - bool HasAtLeastOneResumedBrowser(); -#endif - - void AddObserver(BrowserListObserver* observer); - void RemoveObserver(BrowserListObserver* observer); - - private: - friend class BrowserImpl; - friend class base::NoDestructor<BrowserList>; - - BrowserList(); - ~BrowserList(); - - void AddBrowser(BrowserImpl* browser); - void RemoveBrowser(BrowserImpl* browser); - -#if BUILDFLAG(IS_ANDROID) - void NotifyHasAtLeastOneResumedBrowserChanged(); -#endif - - base::flat_set<BrowserImpl*> browsers_; - base::ObserverList<BrowserListObserver> observers_; - std::unique_ptr<BrowserListProxy> browser_list_proxy_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_LIST_H_
diff --git a/weblayer/browser/browser_list_observer.h b/weblayer/browser/browser_list_observer.h deleted file mode 100644 index 5cfbb1d..0000000 --- a/weblayer/browser/browser_list_observer.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_LIST_OBSERVER_H_ -#define WEBLAYER_BROWSER_BROWSER_LIST_OBSERVER_H_ - -#include "base/observer_list_types.h" -#include "build/build_config.h" - -namespace weblayer { - -class Browser; - -class BrowserListObserver : public base::CheckedObserver { - public: - virtual void OnBrowserCreated(Browser* browser) {} - - virtual void OnBrowserDestroyed(Browser* browser) {} - - protected: - ~BrowserListObserver() override = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_LIST_OBSERVER_H_
diff --git a/weblayer/browser/browser_list_proxy.cc b/weblayer/browser/browser_list_proxy.cc deleted file mode 100644 index 0d02eb8..0000000 --- a/weblayer/browser/browser_list_proxy.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_list_proxy.h" - -#include "base/android/jni_android.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/browser_list.h" -#include "weblayer/browser/java/jni/BrowserList_jni.h" - -namespace weblayer { - -BrowserListProxy::BrowserListProxy() - : java_browser_list_(Java_BrowserList_createBrowserList( - base::android::AttachCurrentThread())) {} - -BrowserListProxy::~BrowserListProxy() = default; - -void BrowserListProxy::OnBrowserCreated(Browser* browser) { - Java_BrowserList_onBrowserCreated( - base::android::AttachCurrentThread(), java_browser_list_, - static_cast<BrowserImpl*>(browser)->java_browser()); -} - -void BrowserListProxy::OnBrowserDestroyed(Browser* browser) { - Java_BrowserList_onBrowserDestroyed( - base::android::AttachCurrentThread(), java_browser_list_, - static_cast<BrowserImpl*>(browser)->java_browser()); -} - -static void JNI_BrowserList_CreateBrowserList(JNIEnv* env) { - BrowserList::GetInstance(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/browser_list_proxy.h b/weblayer/browser/browser_list_proxy.h deleted file mode 100644 index bd4b317..0000000 --- a/weblayer/browser/browser_list_proxy.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_LIST_PROXY_H_ -#define WEBLAYER_BROWSER_BROWSER_LIST_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "weblayer/browser/browser_list_observer.h" - -namespace weblayer { - -// Owns the Java BrowserList implementation and funnels all BrowserListObserver -// calls to the java side. -class BrowserListProxy : public BrowserListObserver { - public: - BrowserListProxy(); - BrowserListProxy(const BrowserListProxy&) = delete; - BrowserListProxy& operator=(const BrowserListProxy&) = delete; - ~BrowserListProxy() override; - - // BrowserListObserver: - void OnBrowserCreated(Browser* browser) override; - void OnBrowserDestroyed(Browser* browser) override; - - private: - base::android::ScopedJavaGlobalRef<jobject> java_browser_list_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_LIST_PROXY_H_
diff --git a/weblayer/browser/browser_main_parts_impl.cc b/weblayer/browser/browser_main_parts_impl.cc deleted file mode 100644 index 89b35e9..0000000 --- a/weblayer/browser/browser_main_parts_impl.cc +++ /dev/null
@@ -1,312 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_main_parts_impl.h" - -#include "base/base_switches.h" -#include "base/functional/bind.h" -#include "base/functional/callback_helpers.h" -#include "base/json/json_reader.h" -#include "base/run_loop.h" -#include "base/task/current_thread.h" -#include "base/task/task_traits.h" -#include "base/threading/thread.h" -#include "base/threading/thread_restrictions.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "cc/base/switches.h" -#include "components/captive_portal/core/buildflags.h" -#include "components/performance_manager/embedder/graph_features.h" -#include "components/performance_manager/embedder/performance_manager_lifetime.h" -#include "components/prefs/pref_service.h" -#include "components/startup_metric_utils/browser/startup_metric_utils.h" -#include "components/startup_metric_utils/common/startup_metric_utils.h" -#include "components/subresource_filter/content/browser/ruleset_service.h" -#include "components/translate/core/browser/translate_download_manager.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/devtools_agent_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/main_function_params.h" -#include "content/public/common/page_visibility_state.h" -#include "content/public/common/result_codes.h" -#include "content/public/common/url_constants.h" -#include "ui/base/resource/resource_bundle.h" -#include "weblayer/browser/accept_languages_service_factory.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/cookie_settings_factory.h" -#include "weblayer/browser/feature_list_creator.h" -#include "weblayer/browser/heavy_ad_service_factory.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" -#include "weblayer/browser/origin_trials_factory.h" -#include "weblayer/browser/permissions/weblayer_permissions_client.h" -#include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h" -#include "weblayer/browser/subresource_filter_profile_context_factory.h" -#include "weblayer/browser/translate_ranker_factory.h" -#include "weblayer/browser/web_data_service_factory.h" -#include "weblayer/browser/webui/web_ui_controller_factory.h" -#include "weblayer/grit/weblayer_resources.h" -#include "weblayer/public/main.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/command_line.h" -#include "components/crash/content/browser/child_exit_observer_android.h" -#include "components/crash/content/browser/child_process_crash_observer_android.h" -#include "components/crash/core/common/crash_key.h" -#include "components/javascript_dialogs/android/app_modal_dialog_view_android.h" // nogncheck -#include "components/javascript_dialogs/app_modal_dialog_manager.h" // nogncheck -#include "components/metrics/content/subprocess_metrics_provider.h" -#include "components/metrics/metrics_service.h" -#include "components/variations/synthetic_trials_active_group_id_provider.h" -#include "components/variations/variations_ids_provider.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/content_switches.h" -#include "net/android/network_change_notifier_factory_android.h" -#include "net/base/network_change_notifier.h" -#include "weblayer/browser/android/metrics/uma_utils.h" -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" -#include "weblayer/browser/java/jni/MojoInterfaceRegistrar_jni.h" -#include "weblayer/browser/media/local_presentation_manager_factory.h" -#include "weblayer/browser/media/media_router_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" -#include "weblayer/browser/site_engagement/site_engagement_service_factory.h" -#include "weblayer/browser/webapps/weblayer_webapps_client.h" -#include "weblayer/browser/weblayer_factory_impl_android.h" -#include "weblayer/common/features.h" -#endif - -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if defined(USE_AURA) && (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) -#include "ui/base/ime/init/input_method_initializer.h" -#endif - -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) -#include "weblayer/browser/captive_portal_service_factory.h" -#endif - -namespace weblayer { - -namespace { - -// Indexes and publishes the subresource filter ruleset data from resources in -// the resource bundle. -void PublishSubresourceFilterRulesetFromResourceBundle() { - // First obtain the version of the ruleset data from the manifest. - std::string ruleset_manifest_string = - ui::ResourceBundle::GetSharedInstance().LoadDataResourceString( - IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON); - auto ruleset_manifest = base::JSONReader::Read(ruleset_manifest_string); - DCHECK(ruleset_manifest); - std::string* content_version = - ruleset_manifest->GetDict().FindString("version"); - - // Instruct the RulesetService to obtain the unindexed ruleset data from the - // ResourceBundle and give it the version of that data. - auto* ruleset_service = - BrowserProcess::GetInstance()->subresource_filter_ruleset_service(); - subresource_filter::UnindexedRulesetInfo ruleset_info; - ruleset_info.resource_id = IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET; - ruleset_info.content_version = *content_version; - ruleset_service->IndexAndStoreAndPublishRulesetIfNeeded(ruleset_info); -} - -// Instantiates all weblayer KeyedService factories, which is -// especially important for services that should be created at profile -// creation time as compared to lazily on first access. -void EnsureBrowserContextKeyedServiceFactoriesBuilt() { -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) - CaptivePortalServiceFactory::GetInstance(); -#endif - HeavyAdServiceFactory::GetInstance(); - HostContentSettingsMapFactory::GetInstance(); - StatefulSSLHostStateDelegateFactory::GetInstance(); - CookieSettingsFactory::GetInstance(); - AcceptLanguagesServiceFactory::GetInstance(); - TranslateRankerFactory::GetInstance(); - NoStatePrefetchLinkManagerFactory::GetInstance(); - NoStatePrefetchManagerFactory::GetInstance(); - SubresourceFilterProfileContextFactory::GetInstance(); - OriginTrialsFactory::GetInstance(); -#if BUILDFLAG(IS_ANDROID) - SiteEngagementServiceFactory::GetInstance(); - SafeBrowsingMetricsCollectorFactory::GetInstance(); - SafeBrowsingNavigationObserverManagerFactory::GetInstance(); - if (MediaRouterFactory::IsFeatureEnabled()) { - LocalPresentationManagerFactory::GetInstance(); - MediaRouterFactory::GetInstance(); - } -#endif - WebDataServiceFactory::GetInstance(); -} - -void StopMessageLoop(base::OnceClosure quit_closure) { - for (auto it = content::RenderProcessHost::AllHostsIterator(); !it.IsAtEnd(); - it.Advance()) { - it.GetCurrentValue()->DisableRefCounts(); - } - - std::move(quit_closure).Run(); -} - -} // namespace - -BrowserMainPartsImpl::BrowserMainPartsImpl( - MainParams* params, - std::unique_ptr<PrefService> local_state) - : params_(params), local_state_(std::move(local_state)) {} - -BrowserMainPartsImpl::~BrowserMainPartsImpl() = default; - -int BrowserMainPartsImpl::PreCreateThreads() { - // Make sure permissions client has been set. - WebLayerPermissionsClient::GetInstance(); -#if BUILDFLAG(IS_ANDROID) - // The ChildExitObserver needs to be created before any child process is - // created because it needs to be notified during process creation. - child_exit_observer_ = std::make_unique<crash_reporter::ChildExitObserver>(); - child_exit_observer_->RegisterClient( - std::make_unique<crash_reporter::ChildProcessCrashObserver>()); - - crash_reporter::InitializeCrashKeys(); - CHECK(metrics::SubprocessMetricsProvider::CreateInstance()); - - // WebLayer initializes the MetricsService once consent is determined. - // Determining consent is async and potentially slow. VariationsIdsProvider - // is responsible for updating the X-Client-Data header. - // SyntheticTrialsActiveGroupIdProvider is responsible for updating the - // variations crash keys. To ensure the header and crash keys are always - // provided, they are registered now. - // - // Chrome registers these providers from PreCreateThreads() as well. - auto* synthetic_trial_registry = WebLayerMetricsServiceClient::GetInstance() - ->GetMetricsService() - ->GetSyntheticTrialRegistry(); - synthetic_trial_registry->AddSyntheticTrialObserver( - variations::VariationsIdsProvider::GetInstance()); - synthetic_trial_registry->AddSyntheticTrialObserver( - variations::SyntheticTrialsActiveGroupIdProvider::GetInstance()); -#endif - - return content::RESULT_CODE_NORMAL_EXIT; -} - -int BrowserMainPartsImpl::PreEarlyInitialization() { - browser_process_ = std::make_unique<BrowserProcess>(std::move(local_state_)); - -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if defined(USE_AURA) && (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) - ui::InitializeInputMethodForTesting(); -#endif -#if BUILDFLAG(IS_ANDROID) - net::NetworkChangeNotifier::SetFactory( - new net::NetworkChangeNotifierFactoryAndroid()); - - WebLayerWebappsClient::Create(); -#endif - - return content::RESULT_CODE_NORMAL_EXIT; -} - -void BrowserMainPartsImpl::PostCreateThreads() { - performance_manager_lifetime_ = - std::make_unique<performance_manager::PerformanceManagerLifetime>( - performance_manager::GraphFeatures::WithMinimal() - // Reports performance-related UMA/UKM. - .EnableMetricsCollector(), - base::DoNothing()); - - translate::TranslateDownloadManager* download_manager = - translate::TranslateDownloadManager::GetInstance(); - download_manager->set_url_loader_factory( - BrowserProcess::GetInstance()->GetSharedURLLoaderFactory()); - download_manager->set_application_locale(i18n::GetApplicationLocale()); -} - -int BrowserMainPartsImpl::PreMainMessageLoopRun() { - FeatureListCreator::GetInstance()->PerformPreMainMessageLoopStartup(); - - // It's necessary to have a complete dependency graph of - // BrowserContextKeyedServices before calling out to the delegate (which - // will potentially create a profile), so that a profile creation message is - // properly dispatched to the factories that want to create their services - // at profile creation time. - EnsureBrowserContextKeyedServiceFactoriesBuilt(); - - params_->delegate->PreMainMessageLoopRun(); - - content::WebUIControllerFactory::RegisterFactory( - WebUIControllerFactory::GetInstance()); - - BrowserProcess::GetInstance()->PreMainMessageLoopRun(); - - // Publish the ruleset data. On the vast majority of runs this will - // effectively be a no-op as the version of the data changes at most once per - // release. Nonetheless, post it as a best-effort task to take it off the - // critical path of startup. Note that best-effort tasks are guaranteed to - // execute within a reasonable delay (assuming of course that the app isn't - // shut down first). - content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) - ->PostTask( - FROM_HERE, - base::BindOnce(&PublishSubresourceFilterRulesetFromResourceBundle)); - -#if BUILDFLAG(IS_ANDROID) - // On Android, retrieve the application start time from Java and record it. On - // other platforms, the application start time was already recorded in the - // constructor of ContentMainDelegateImpl. - startup_metric_utils::GetCommon().RecordApplicationStartTime( - GetApplicationStartTime()); -#endif // BUILDFLAG(IS_ANDROID) - // Record the time at which the main message loop starts. Must be recorded - // after application start time (see startup_metric_utils.h). - startup_metric_utils::GetBrowser().RecordBrowserMainMessageLoopStart( - base::TimeTicks::Now(), /* is_first_run */ false); - -#if BUILDFLAG(IS_ANDROID) - memory_metrics_logger_ = std::make_unique<metrics::MemoryMetricsLogger>(); - - // Set the global singleton app modal dialog factory. - javascript_dialogs::AppModalDialogManager::GetInstance() - ->SetNativeDialogFactory(base::BindRepeating( - [](javascript_dialogs::AppModalDialogController* controller) - -> javascript_dialogs::AppModalDialogView* { - return new javascript_dialogs::AppModalDialogViewAndroid( - base::android::AttachCurrentThread(), controller, - controller->web_contents()->GetTopLevelNativeWindow()); - })); - - Java_MojoInterfaceRegistrar_registerMojoInterfaces( - base::android::AttachCurrentThread()); -#endif - - return content::RESULT_CODE_NORMAL_EXIT; -} - -void BrowserMainPartsImpl::WillRunMainMessageLoop( - std::unique_ptr<base::RunLoop>& run_loop) { - // Wrap the method that stops the message loop so we can do other shutdown - // cleanup inside content. - params_->delegate->SetMainMessageLoopQuitClosure( - base::BindOnce(StopMessageLoop, run_loop->QuitClosure())); -} - -void BrowserMainPartsImpl::OnFirstIdle() { - startup_metric_utils::GetBrowser().RecordBrowserMainLoopFirstIdle( - base::TimeTicks::Now()); -} - -void BrowserMainPartsImpl::PostMainMessageLoopRun() { - params_->delegate->PostMainMessageLoopRun(); - browser_process_->StartTearDown(); - - performance_manager_lifetime_.reset(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/browser_main_parts_impl.h b/weblayer/browser/browser_main_parts_impl.h deleted file mode 100644 index 6bd3391..0000000 --- a/weblayer/browser/browser_main_parts_impl.h +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_MAIN_PARTS_IMPL_H_ -#define WEBLAYER_BROWSER_BROWSER_MAIN_PARTS_IMPL_H_ - -#include <memory> - -#include "base/memory/raw_ptr.h" -#include "base/metrics/field_trial.h" -#include "build/build_config.h" -#include "components/embedder_support/android/metrics/memory_metrics_logger.h" -#include "content/public/browser/browser_main_parts.h" -#include "content/public/common/main_function_params.h" - -class PrefService; - -namespace performance_manager { -class PerformanceManagerLifetime; -} - -#if BUILDFLAG(IS_ANDROID) -namespace crash_reporter { -class ChildExitObserver; -} -#endif - -namespace weblayer { -class BrowserProcess; -struct MainParams; - -class BrowserMainPartsImpl : public content::BrowserMainParts { - public: - BrowserMainPartsImpl(MainParams* params, - std::unique_ptr<PrefService> local_state); - - BrowserMainPartsImpl(const BrowserMainPartsImpl&) = delete; - BrowserMainPartsImpl& operator=(const BrowserMainPartsImpl&) = delete; - - ~BrowserMainPartsImpl() override; - - // BrowserMainParts overrides. - int PreCreateThreads() override; - int PreEarlyInitialization() override; - void PostCreateThreads() override; - int PreMainMessageLoopRun() override; - void WillRunMainMessageLoop( - std::unique_ptr<base::RunLoop>& run_loop) override; - void OnFirstIdle() override; - void PostMainMessageLoopRun() override; - - private: - raw_ptr<MainParams> params_; - - std::unique_ptr<BrowserProcess> browser_process_; - std::unique_ptr<performance_manager::PerformanceManagerLifetime> - performance_manager_lifetime_; -#if BUILDFLAG(IS_ANDROID) - std::unique_ptr<metrics::MemoryMetricsLogger> memory_metrics_logger_; - std::unique_ptr<crash_reporter::ChildExitObserver> child_exit_observer_; -#endif // BUILDFLAG(IS_ANDROID) - - // Ownership of this moves to BrowserProcess. See - // ContentBrowserClientImpl::local_state_ for details. - std::unique_ptr<PrefService> local_state_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_MAIN_PARTS_IMPL_H_
diff --git a/weblayer/browser/browser_process.cc b/weblayer/browser/browser_process.cc deleted file mode 100644 index 03406f2..0000000 --- a/weblayer/browser/browser_process.cc +++ /dev/null
@@ -1,138 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browser_process.h" - -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" -#include "base/path_service.h" -#include "base/time/default_clock.h" -#include "base/time/default_tick_clock.h" -#include "build/build_config.h" -#include "components/embedder_support/user_agent_utils.h" -#include "components/network_time/network_time_tracker.h" -#include "components/prefs/pref_service.h" -#include "components/subresource_filter/content/browser/ruleset_service.h" -#include "content/public/browser/network_quality_observer_factory.h" -#include "content/public/browser/network_service_instance.h" -#include "services/network/public/cpp/network_quality_tracker.h" -#include "weblayer/browser/system_network_context_manager.h" -#include "weblayer/common/weblayer_paths.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#endif - -namespace weblayer { - -namespace { -BrowserProcess* g_browser_process = nullptr; -} // namespace - -BrowserProcess::BrowserProcess(std::unique_ptr<PrefService> local_state) - : local_state_(std::move(local_state)) { - g_browser_process = this; -} - -BrowserProcess::~BrowserProcess() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - g_browser_process = nullptr; - - SystemNetworkContextManager::DeleteInstance(); -} - -// static -BrowserProcess* BrowserProcess::GetInstance() { - return g_browser_process; -} - -void BrowserProcess::PreMainMessageLoopRun() { - CreateNetworkQualityObserver(); -} - -void BrowserProcess::StartTearDown() { - if (local_state_) - local_state_->CommitPendingWrite(); -} - -PrefService* BrowserProcess::GetLocalState() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return local_state_.get(); -} - -scoped_refptr<network::SharedURLLoaderFactory> -BrowserProcess::GetSharedURLLoaderFactory() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - return SystemNetworkContextManager::GetInstance() - ->GetSharedURLLoaderFactory(); -} - -network_time::NetworkTimeTracker* BrowserProcess::GetNetworkTimeTracker() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (!network_time_tracker_) { - network_time_tracker_ = std::make_unique<network_time::NetworkTimeTracker>( - base::WrapUnique(new base::DefaultClock()), - base::WrapUnique(new base::DefaultTickClock()), GetLocalState(), - GetSharedURLLoaderFactory()); - } - return network_time_tracker_.get(); -} - -network::NetworkQualityTracker* BrowserProcess::GetNetworkQualityTracker() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!network_quality_tracker_) { - network_quality_tracker_ = std::make_unique<network::NetworkQualityTracker>( - base::BindRepeating(&content::GetNetworkService)); - } - return network_quality_tracker_.get(); -} - -subresource_filter::RulesetService* -BrowserProcess::subresource_filter_ruleset_service() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!subresource_filter_ruleset_service_) - CreateSubresourceFilterRulesetService(); - return subresource_filter_ruleset_service_.get(); -} - -void BrowserProcess::CreateNetworkQualityObserver() { - DCHECK(!network_quality_observer_); - network_quality_observer_ = - content::CreateNetworkQualityObserver(GetNetworkQualityTracker()); - DCHECK(network_quality_observer_); -} - -void BrowserProcess::CreateSubresourceFilterRulesetService() { - DCHECK(!subresource_filter_ruleset_service_); - - base::FilePath user_data_dir; - CHECK(base::PathService::Get(DIR_USER_DATA, &user_data_dir)); - subresource_filter_ruleset_service_ = - subresource_filter::RulesetService::Create(GetLocalState(), - user_data_dir); -} - -#if BUILDFLAG(IS_ANDROID) -SafeBrowsingService* BrowserProcess::GetSafeBrowsingService() { - if (!safe_browsing_service_) { - // Create and initialize safe_browsing_service on first get. - // Note: Initialize() needs to happen on UI thread. - safe_browsing_service_ = - std::make_unique<SafeBrowsingService>(embedder_support::GetUserAgent()); - safe_browsing_service_->Initialize(); - } - return safe_browsing_service_.get(); -} - -void BrowserProcess::StopSafeBrowsingService() { - if (safe_browsing_service_) { - safe_browsing_service_->StopDBManager(); - } -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/browser_process.h b/weblayer/browser/browser_process.h deleted file mode 100644 index b1741c4..0000000 --- a/weblayer/browser/browser_process.h +++ /dev/null
@@ -1,93 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSER_PROCESS_H_ -#define WEBLAYER_BROWSER_BROWSER_PROCESS_H_ - -#include <memory> - -#include "base/memory/scoped_refptr.h" -#include "base/sequence_checker.h" -#include "build/build_config.h" -#include "services/network/public/cpp/network_quality_tracker.h" - -class PrefService; - -namespace network_time { -class NetworkTimeTracker; -} - -namespace network { -class SharedURLLoaderFactory; -} - -namespace subresource_filter { -class RulesetService; -} - -namespace weblayer { -class SafeBrowsingService; - -// Class that holds global state in the browser process. Should be used only on -// the UI thread. -class BrowserProcess { - public: - explicit BrowserProcess(std::unique_ptr<PrefService> local_state); - - BrowserProcess(const BrowserProcess&) = delete; - BrowserProcess& operator=(const BrowserProcess&) = delete; - - ~BrowserProcess(); - - static BrowserProcess* GetInstance(); - - // Called after the threads have been created but before the message loops - // starts running. Allows the browser process to do any initialization that - // requires all threads running. - void PreMainMessageLoopRun(); - - // Does cleanup that needs to occur before threads are torn down. - void StartTearDown(); - - PrefService* GetLocalState(); - scoped_refptr<network::SharedURLLoaderFactory> GetSharedURLLoaderFactory(); - network_time::NetworkTimeTracker* GetNetworkTimeTracker(); - network::NetworkQualityTracker* GetNetworkQualityTracker(); - - // Returns the service providing versioned storage for rules used by the Safe - // Browsing subresource filter. May be null. - subresource_filter::RulesetService* subresource_filter_ruleset_service(); - -#if BUILDFLAG(IS_ANDROID) - SafeBrowsingService* GetSafeBrowsingService(); - void StopSafeBrowsingService(); -#endif - - private: - void CreateNetworkQualityObserver(); - void CreateSubresourceFilterRulesetService(); - - std::unique_ptr<PrefService> local_state_; - std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_; - std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_; - - // Listens to NetworkQualityTracker and sends network quality updates to the - // renderer. - std::unique_ptr< - network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver> - network_quality_observer_; - - std::unique_ptr<subresource_filter::RulesetService> - subresource_filter_ruleset_service_; - -#if BUILDFLAG(IS_ANDROID) - std::unique_ptr<SafeBrowsingService> safe_browsing_service_; -#endif - - SEQUENCE_CHECKER(sequence_checker_); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSER_PROCESS_H_
diff --git a/weblayer/browser/browsing_data_remover_delegate.cc b/weblayer/browser/browsing_data_remover_delegate.cc deleted file mode 100644 index 0befbe0a..0000000 --- a/weblayer/browser/browsing_data_remover_delegate.cc +++ /dev/null
@@ -1,144 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browsing_data_remover_delegate.h" - -#include "base/functional/callback.h" -#include "build/build_config.h" -#include "components/browsing_data/content/browsing_data_helper.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/heavy_ad_intervention/heavy_ad_blocklist.h" -#include "components/heavy_ad_intervention/heavy_ad_service.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browsing_data_filter_builder.h" -#include "content/public/browser/origin_trials_controller_delegate.h" -#include "services/network/public/mojom/cookie_manager.mojom.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/favicon/favicon_service_impl.h" -#include "weblayer/browser/favicon/favicon_service_impl_factory.h" -#include "weblayer/browser/heavy_ad_service_factory.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" - -namespace weblayer { - -BrowsingDataRemoverDelegate::BrowsingDataRemoverDelegate( - content::BrowserContext* browser_context) - : browser_context_(browser_context) {} - -BrowsingDataRemoverDelegate::~BrowsingDataRemoverDelegate() = default; - -BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher -BrowsingDataRemoverDelegate::GetOriginTypeMatcher() { - return EmbedderOriginTypeMatcher(); -} - -bool BrowsingDataRemoverDelegate::MayRemoveDownloadHistory() { - return true; -} - -std::vector<std::string> -BrowsingDataRemoverDelegate::GetDomainsForDeferredCookieDeletion( - content::StoragePartition* storage_partition, - uint64_t remove_mask) { - return {}; -} - -void BrowsingDataRemoverDelegate::RemoveEmbedderData( - const base::Time& delete_begin, - const base::Time& delete_end, - uint64_t remove_mask, - content::BrowsingDataFilterBuilder* filter_builder, - uint64_t origin_type_mask, - base::OnceCallback<void(uint64_t)> callback) { - callback_ = std::move(callback); - - // Note: if history is ever added to WebLayer, also remove isolated origins - // when history is cleared. - if (remove_mask & DATA_TYPE_ISOLATED_ORIGINS) { - browsing_data::RemoveSiteIsolationData( - user_prefs::UserPrefs::Get(browser_context_)); - } - - HostContentSettingsMap* host_content_settings_map = - HostContentSettingsMapFactory::GetForBrowserContext(browser_context_); - - if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_CACHE) { - browsing_data::RemovePrerenderCacheData( - NoStatePrefetchManagerFactory::GetForBrowserContext(browser_context_)); - } - - if (remove_mask & DATA_TYPE_FAVICONS) { - auto* service = - FaviconServiceImplFactory::GetForBrowserContext(browser_context_); - if (service) { - // The favicon database doesn't track enough information to remove - // favicons in a time range. Delete everything. - service->DeleteAndRecreateDatabase(CreateTaskCompletionClosure()); - } - } - - if (remove_mask & DATA_TYPE_AD_INTERVENTIONS) { - heavy_ad_intervention::HeavyAdService* heavy_ad_service = - HeavyAdServiceFactory::GetForBrowserContext(browser_context_); - if (heavy_ad_service->heavy_ad_blocklist()) { - heavy_ad_service->heavy_ad_blocklist()->ClearBlockList(delete_begin, - delete_end); - } - } - - // We ignore the DATA_TYPE_COOKIES request if UNPROTECTED_WEB is not set, - // so that callers who request COOKIES_AND_SITE_DATA with PROTECTED_WEB - // don't accidentally remove the cookies that are associated with the - // UNPROTECTED_WEB origin. This is necessary because cookies are not separated - // between UNPROTECTED_WEB and PROTECTED_WEB. - if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) { - network::mojom::NetworkContext* safe_browsing_context = nullptr; -#if BUILDFLAG(IS_ANDROID) - safe_browsing_context = BrowserProcess::GetInstance() - ->GetSafeBrowsingService() - ->GetNetworkContext(); -#endif - browsing_data::RemoveEmbedderCookieData( - delete_begin, delete_end, filter_builder, host_content_settings_map, - safe_browsing_context, - base::BindOnce( - &BrowsingDataRemoverDelegate::CreateTaskCompletionClosure, - base::Unretained(this))); - } - - if (remove_mask & DATA_TYPE_SITE_SETTINGS) { - browsing_data::RemoveSiteSettingsData(delete_begin, delete_end, - host_content_settings_map); - content::OriginTrialsControllerDelegate* delegate = - browser_context_->GetOriginTrialsControllerDelegate(); - if (delegate) - delegate->ClearPersistedTokens(); - } - - RunCallbackIfDone(); -} - -base::OnceClosure BrowsingDataRemoverDelegate::CreateTaskCompletionClosure() { - ++pending_tasks_; - - return base::BindOnce(&BrowsingDataRemoverDelegate::OnTaskComplete, - weak_ptr_factory_.GetWeakPtr()); -} - -void BrowsingDataRemoverDelegate::OnTaskComplete() { - pending_tasks_--; - RunCallbackIfDone(); -} - -void BrowsingDataRemoverDelegate::RunCallbackIfDone() { - if (pending_tasks_ != 0) - return; - - std::move(callback_).Run(/*failed_data_types=*/0); -} - -} // namespace weblayer
diff --git a/weblayer/browser/browsing_data_remover_delegate.h b/weblayer/browser/browsing_data_remover_delegate.h deleted file mode 100644 index 1ac2c46a..0000000 --- a/weblayer/browser/browsing_data_remover_delegate.h +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSING_DATA_REMOVER_DELEGATE_H_ -#define WEBLAYER_BROWSER_BROWSING_DATA_REMOVER_DELEGATE_H_ - -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "components/keyed_service/core/keyed_service.h" -#include "content/public/browser/browsing_data_remover.h" -#include "content/public/browser/browsing_data_remover_delegate.h" - -namespace content { -class BrowserContext; -class StoragePartition; -} - -namespace weblayer { - -class BrowsingDataRemoverDelegate : public content::BrowsingDataRemoverDelegate, - public KeyedService { - public: - // This is an extension of content::BrowsingDataRemover::RemoveDataMask which - // includes all datatypes therefrom and adds additional WebLayer-specific - // ones. - enum DataType : uint64_t { - // Embedder can start adding datatypes after the last platform datatype. - DATA_TYPE_EMBEDDER_BEGIN = - content::BrowsingDataRemover::DATA_TYPE_CONTENT_END << 1, - - // WebLayer-specific datatypes. - DATA_TYPE_ISOLATED_ORIGINS = DATA_TYPE_EMBEDDER_BEGIN, - DATA_TYPE_FAVICONS = DATA_TYPE_EMBEDDER_BEGIN << 1, - DATA_TYPE_SITE_SETTINGS = DATA_TYPE_EMBEDDER_BEGIN << 2, - DATA_TYPE_AD_INTERVENTIONS = DATA_TYPE_EMBEDDER_BEGIN << 4, - }; - - explicit BrowsingDataRemoverDelegate( - content::BrowserContext* browser_context); - ~BrowsingDataRemoverDelegate() override; - - BrowsingDataRemoverDelegate(const BrowsingDataRemoverDelegate&) = delete; - BrowsingDataRemoverDelegate& operator=(const BrowsingDataRemoverDelegate&) = - delete; - - // content::BrowsingDataRemoverDelegate: - EmbedderOriginTypeMatcher GetOriginTypeMatcher() override; - bool MayRemoveDownloadHistory() override; - std::vector<std::string> GetDomainsForDeferredCookieDeletion( - content::StoragePartition* storage_partition, - uint64_t remove_mask) override; - void RemoveEmbedderData(const base::Time& delete_begin, - const base::Time& delete_end, - uint64_t remove_mask, - content::BrowsingDataFilterBuilder* filter_builder, - uint64_t origin_type_mask, - base::OnceCallback<void(uint64_t)> callback) override; - - private: - base::OnceClosure CreateTaskCompletionClosure(); - - void OnTaskComplete(); - - void RunCallbackIfDone(); - - raw_ptr<content::BrowserContext> browser_context_ = nullptr; - - int pending_tasks_ = 0; - - // Completion callback to call when all data are deleted. - base::OnceCallback<void(uint64_t)> callback_; - - base::WeakPtrFactory<BrowsingDataRemoverDelegate> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSING_DATA_REMOVER_DELEGATE_H_
diff --git a/weblayer/browser/browsing_data_remover_delegate_factory.cc b/weblayer/browser/browsing_data_remover_delegate_factory.cc deleted file mode 100644 index bcff6b52..0000000 --- a/weblayer/browser/browsing_data_remover_delegate_factory.cc +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/browsing_data_remover_delegate_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "weblayer/browser/browsing_data_remover_delegate.h" - -namespace weblayer { - -// static -BrowsingDataRemoverDelegate* -BrowsingDataRemoverDelegateFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<BrowsingDataRemoverDelegate*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -BrowsingDataRemoverDelegateFactory* -BrowsingDataRemoverDelegateFactory::GetInstance() { - static base::NoDestructor<BrowsingDataRemoverDelegateFactory> factory; - return factory.get(); -} - -BrowsingDataRemoverDelegateFactory::BrowsingDataRemoverDelegateFactory() - : BrowserContextKeyedServiceFactory( - "BrowsingDataRemoverDelegate", - BrowserContextDependencyManager::GetInstance()) {} - -BrowsingDataRemoverDelegateFactory::~BrowsingDataRemoverDelegateFactory() = - default; - -std::unique_ptr<KeyedService> -BrowsingDataRemoverDelegateFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<BrowsingDataRemoverDelegate>(context); -} - -content::BrowserContext* -BrowsingDataRemoverDelegateFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/browsing_data_remover_delegate_factory.h b/weblayer/browser/browsing_data_remover_delegate_factory.h deleted file mode 100644 index 163c00f..0000000 --- a/weblayer/browser/browsing_data_remover_delegate_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_BROWSING_DATA_REMOVER_DELEGATE_FACTORY_H_ -#define WEBLAYER_BROWSER_BROWSING_DATA_REMOVER_DELEGATE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace weblayer { -class BrowsingDataRemoverDelegate; - -class BrowsingDataRemoverDelegateFactory - : public BrowserContextKeyedServiceFactory { - public: - BrowsingDataRemoverDelegateFactory( - const BrowsingDataRemoverDelegateFactory&) = delete; - BrowsingDataRemoverDelegateFactory& operator=( - const BrowsingDataRemoverDelegateFactory&) = delete; - - static BrowsingDataRemoverDelegate* GetForBrowserContext( - content::BrowserContext* browser_context); - static BrowsingDataRemoverDelegateFactory* GetInstance(); - - private: - friend class base::NoDestructor<BrowsingDataRemoverDelegateFactory>; - - BrowsingDataRemoverDelegateFactory(); - ~BrowsingDataRemoverDelegateFactory() override; - - // BrowserContextKeyedServiceFactory methods: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_BROWSING_DATA_REMOVER_DELEGATE_FACTORY_H_
diff --git a/weblayer/browser/captive_portal_service_factory.cc b/weblayer/browser/captive_portal_service_factory.cc deleted file mode 100644 index 218b588..0000000 --- a/weblayer/browser/captive_portal_service_factory.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/captive_portal_service_factory.h" - -#include "components/captive_portal/content/captive_portal_service.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" - -namespace weblayer { - -// static -captive_portal::CaptivePortalService* -CaptivePortalServiceFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<captive_portal::CaptivePortalService*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -CaptivePortalServiceFactory* CaptivePortalServiceFactory::GetInstance() { - return base::Singleton<CaptivePortalServiceFactory>::get(); -} - -CaptivePortalServiceFactory::CaptivePortalServiceFactory() - : BrowserContextKeyedServiceFactory( - "captive_portal::CaptivePortalService", - BrowserContextDependencyManager::GetInstance()) {} - -CaptivePortalServiceFactory::~CaptivePortalServiceFactory() = default; - -std::unique_ptr<KeyedService> -CaptivePortalServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser_context) const { - return std::make_unique<captive_portal::CaptivePortalService>( - browser_context, user_prefs::UserPrefs::Get(browser_context)); -} - -content::BrowserContext* CaptivePortalServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/captive_portal_service_factory.h b/weblayer/browser/captive_portal_service_factory.h deleted file mode 100644 index 418637f9..0000000 --- a/weblayer/browser/captive_portal_service_factory.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_CAPTIVE_PORTAL_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_CAPTIVE_PORTAL_SERVICE_FACTORY_H_ - -#include "base/compiler_specific.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace captive_portal { -class CaptivePortalService; -} - -namespace weblayer { - -// Singleton that owns all captive_portal::CaptivePortalServices and associates -// them with BrowserContextImpl instances. -class CaptivePortalServiceFactory : public BrowserContextKeyedServiceFactory { - public: - // Returns the captive_portal::CaptivePortalService for |browser_context|. - static captive_portal::CaptivePortalService* GetForBrowserContext( - content::BrowserContext* browser_context); - - static CaptivePortalServiceFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<CaptivePortalServiceFactory>; - - CaptivePortalServiceFactory(); - ~CaptivePortalServiceFactory() override; - CaptivePortalServiceFactory(const CaptivePortalServiceFactory&) = delete; - CaptivePortalServiceFactory& operator=(const CaptivePortalServiceFactory&) = - delete; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; - - // Incognito profiles have their own instance of - // captive_portal::CaptivePortalService rather than the default behavior of - // the service being null if the profile is incognito. - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_CAPTIVE_PORTAL_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/client_hints_browsertest.cc b/weblayer/browser/client_hints_browsertest.cc deleted file mode 100644 index bf94da9..0000000 --- a/weblayer/browser/client_hints_browsertest.cc +++ /dev/null
@@ -1,152 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string_number_conversions.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/test/browser_test_utils.h" -#include "net/test/embedded_test_server/default_handlers.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -class ClientHintsBrowserTest : public WebLayerBrowserTest { - public: - void SetUpOnMainThread() override { - WebLayerBrowserTest::SetUpOnMainThread(); - BrowserProcess::GetInstance() - ->GetNetworkQualityTracker() - ->ReportRTTsAndThroughputForTesting(base::Milliseconds(500), 100); - - EXPECT_TRUE(embedded_test_server()->Start()); - } - - void SetAcceptClientHints() { - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL( - "/set-header?Accept-CH: device-memory,rtt"), - shell()); - } - - void CheckNavigationHeaders() { - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/echoheader?device-memory"), shell()); - - double device_memory = 0.0; - ASSERT_TRUE(base::StringToDouble(GetBody(), &device_memory)); - EXPECT_GT(device_memory, 0.0); - - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/echoheader?rtt"), shell()); - int rtt = 0; - ASSERT_TRUE(base::StringToInt(GetBody(), &rtt)); - EXPECT_GT(rtt, 0); - } - - void CheckSubresourceHeaders() { - double device_memory = 0.0; - ASSERT_TRUE(base::StringToDouble(GetSubresourceHeader("device-memory"), - &device_memory)); - EXPECT_GT(device_memory, 0.0); - - int rtt = 0; - ASSERT_TRUE(base::StringToInt(GetSubresourceHeader("rtt"), &rtt)); - EXPECT_GT(rtt, 0); - } - - void KillRenderer() { - content::RenderProcessHost* child_process = - static_cast<TabImpl*>(shell()->tab()) - ->web_contents() - ->GetPrimaryMainFrame() - ->GetProcess(); - content::RenderProcessHostWatcher crash_observer( - child_process, - content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - child_process->Shutdown(0); - crash_observer.Wait(); - } - - std::string GetSubresourceHeader(const std::string& header) { - constexpr char kScript[] = R"( - new Promise(function (resolve, reject) { - const xhr = new XMLHttpRequest(); - xhr.open("GET", "/echoheader?" + $1); - xhr.onload = () => { - resolve(xhr.response); - }; - xhr.send(); - }) - )"; - content::WebContents* web_contents = - static_cast<TabImpl*>(shell()->tab())->web_contents(); - return content::EvalJs(web_contents, - content::JsReplace(kScript, "device-memory")) - .ExtractString(); - } - - std::string GetBody() { - return ExecuteScript(shell(), "document.body.innerText", true).GetString(); - } -}; - -IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, Navigation) { - SetAcceptClientHints(); - CheckNavigationHeaders(); -} - -IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, Subresource) { - SetAcceptClientHints(); - CheckSubresourceHeaders(); -} - -IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, SubresourceInNewRenderer) { - SetAcceptClientHints(); - KillRenderer(); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"), - shell()); - CheckSubresourceHeaders(); -} - -IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, - SubresourceAfterContentSettingUpdate) { - // Set accept client hints on the original server. - SetAcceptClientHints(); - - // Start a new server which will not accept client hints. - net::test_server::EmbeddedTestServer other_server; - net::test_server::RegisterDefaultHandlers(&other_server); - ASSERT_TRUE(other_server.Start()); - NavigateAndWaitForCompletion(other_server.GetURL("/echo"), shell()); - EXPECT_EQ(GetSubresourceHeader("device-memory"), "None"); - - // Copy client hints over to the other server. - auto* settings_map = HostContentSettingsMapFactory::GetForBrowserContext( - static_cast<TabImpl*>(shell()->tab()) - ->web_contents() - ->GetBrowserContext()); - base::Value setting = settings_map->GetWebsiteSetting( - embedded_test_server()->base_url(), GURL(), - ContentSettingsType::CLIENT_HINTS, nullptr); - ASSERT_FALSE(setting.is_none()); - settings_map->SetWebsiteSettingDefaultScope(other_server.base_url(), GURL(), - ContentSettingsType::CLIENT_HINTS, - setting.Clone()); - - // Settings take affect after navigation only, so the header shouldn't be - // there yet. - EXPECT_EQ(GetSubresourceHeader("device-memory"), "None"); - - // After re-navigating, should have hints. - NavigateAndWaitForCompletion(other_server.GetURL("/echo"), shell()); - CheckSubresourceHeaders(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/client_hints_factory.cc b/weblayer/browser/client_hints_factory.cc deleted file mode 100644 index c7d91c0..0000000 --- a/weblayer/browser/client_hints_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/client_hints_factory.h" - -#include "base/no_destructor.h" -#include "components/client_hints/browser/client_hints.h" -#include "components/embedder_support/user_agent_utils.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/cookie_settings_factory.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -client_hints::ClientHints* ClientHintsFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<client_hints::ClientHints*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -ClientHintsFactory* ClientHintsFactory::GetInstance() { - static base::NoDestructor<ClientHintsFactory> factory; - return factory.get(); -} - -ClientHintsFactory::ClientHintsFactory() - : BrowserContextKeyedServiceFactory( - "ClientHints", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); - DependsOn(CookieSettingsFactory::GetInstance()); -} - -ClientHintsFactory::~ClientHintsFactory() = default; - -std::unique_ptr<KeyedService> -ClientHintsFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<client_hints::ClientHints>( - context, BrowserProcess::GetInstance()->GetNetworkQualityTracker(), - HostContentSettingsMapFactory::GetForBrowserContext(context), - CookieSettingsFactory::GetForBrowserContext(context), - BrowserProcess::GetInstance()->GetLocalState()); -} - -content::BrowserContext* ClientHintsFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/client_hints_factory.h b/weblayer/browser/client_hints_factory.h deleted file mode 100644 index 31a7995..0000000 --- a/weblayer/browser/client_hints_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_CLIENT_HINTS_FACTORY_H_ -#define WEBLAYER_BROWSER_CLIENT_HINTS_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace client_hints { -class ClientHints; -} - -namespace weblayer { - -class ClientHintsFactory : public BrowserContextKeyedServiceFactory { - public: - ClientHintsFactory(const ClientHintsFactory&) = delete; - ClientHintsFactory& operator=(const ClientHintsFactory&) = delete; - - static client_hints::ClientHints* GetForBrowserContext( - content::BrowserContext* browser_context); - static ClientHintsFactory* GetInstance(); - - private: - friend class base::NoDestructor<ClientHintsFactory>; - - ClientHintsFactory(); - ~ClientHintsFactory() override; - - // BrowserContextKeyedServiceFactory methods: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_CLIENT_HINTS_FACTORY_H_
diff --git a/weblayer/browser/clipboard_browsertest.cc b/weblayer/browser/clipboard_browsertest.cc deleted file mode 100644 index c55450e..0000000 --- a/weblayer/browser/clipboard_browsertest.cc +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -#include "components/permissions/permission_request_manager.h" -#include "components/permissions/test/mock_permission_prompt_factory.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/scoped_page_focus_override.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -class ClipboardBrowserTest : public WebLayerBrowserTest { - public: - ClipboardBrowserTest() = default; - ~ClipboardBrowserTest() override = default; - - // WebLayerBrowserTest: - void SetUpOnMainThread() override { - WebLayerBrowserTest::SetUpOnMainThread(); - permissions::PermissionRequestManager* manager = - permissions::PermissionRequestManager::FromWebContents( - GetWebContents()); - prompt_factory_ = - std::make_unique<permissions::MockPermissionPromptFactory>(manager); - - title_watcher_ = - std::make_unique<content::TitleWatcher>(GetWebContents(), u"success"); - title_watcher_->AlsoWaitForTitle(u"fail"); - - EXPECT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/clipboard.html"), shell()); - - // The Clipboard API requires the page to have focus. - scoped_focus_ = - std::make_unique<content::ScopedPageFocusOverride>(GetWebContents()); - } - - void TearDownOnMainThread() override { - scoped_focus_.reset(); - title_watcher_.reset(); - prompt_factory_.reset(); - } - - protected: - content::WebContents* GetWebContents() { - return static_cast<TabImpl*>(shell()->tab())->web_contents(); - } - - GURL GetBaseOrigin() { - return embedded_test_server()->base_url().DeprecatedGetOriginAsURL(); - } - - permissions::MockPermissionPromptFactory* prompt_factory() { - return prompt_factory_.get(); - } - - content::TitleWatcher* title_watcher() { return title_watcher_.get(); } - - private: - std::unique_ptr<permissions::MockPermissionPromptFactory> prompt_factory_; - std::unique_ptr<content::TitleWatcher> title_watcher_; - std::unique_ptr<content::ScopedPageFocusOverride> scoped_focus_; -}; - -IN_PROC_BROWSER_TEST_F(ClipboardBrowserTest, ReadTextSuccess) { - prompt_factory()->set_response_type( - permissions::PermissionRequestManager::ACCEPT_ALL); - ExecuteScriptWithUserGesture(shell()->tab(), "tryClipboardReadText()"); - EXPECT_EQ(u"success", title_watcher()->WaitAndGetTitle()); - - EXPECT_EQ(1, prompt_factory()->TotalRequestCount()); - EXPECT_TRUE(prompt_factory()->RequestOriginSeen(GetBaseOrigin())); -} - -IN_PROC_BROWSER_TEST_F(ClipboardBrowserTest, WriteSanitizedTextSuccess) { - prompt_factory()->set_response_type( - permissions::PermissionRequestManager::ACCEPT_ALL); - ExecuteScriptWithUserGesture(shell()->tab(), "tryClipboardWriteText()"); - EXPECT_EQ(u"success", title_watcher()->WaitAndGetTitle()); - - // Writing sanitized data to the clipboard does not require a permission. - EXPECT_EQ(0, prompt_factory()->TotalRequestCount()); -} - -IN_PROC_BROWSER_TEST_F(ClipboardBrowserTest, ReadTextWithoutPermission) { - prompt_factory()->set_response_type( - permissions::PermissionRequestManager::DENY_ALL); - ExecuteScriptWithUserGesture(shell()->tab(), "tryClipboardReadText()"); - EXPECT_EQ(u"fail", title_watcher()->WaitAndGetTitle()); - - EXPECT_EQ(1, prompt_factory()->TotalRequestCount()); - EXPECT_TRUE(prompt_factory()->RequestOriginSeen(GetBaseOrigin())); -} - -} // namespace weblayer
diff --git a/weblayer/browser/component_updater/DEPS b/weblayer/browser/component_updater/DEPS deleted file mode 100644 index 6ce3145..0000000 --- a/weblayer/browser/component_updater/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+components/component_updater/installer_policies", -] \ No newline at end of file
diff --git a/weblayer/browser/component_updater/registration.cc b/weblayer/browser/component_updater/registration.cc deleted file mode 100644 index d21b275..0000000 --- a/weblayer/browser/component_updater/registration.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/component_updater/registration.h" - -namespace weblayer { - -component_updater::ComponentLoaderPolicyVector GetComponentLoaderPolicies() { - component_updater::ComponentLoaderPolicyVector policies; - - // TODO(crbug.com/1233490) register AutoFillRegex component loader policy. - - return policies; -} - -} // namespace weblayer
diff --git a/weblayer/browser/component_updater/registration.h b/weblayer/browser/component_updater/registration.h deleted file mode 100644 index b42f4c4..0000000 --- a/weblayer/browser/component_updater/registration.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_COMPONENT_UPDATER_REGISTRATION_H_ -#define WEBLAYER_BROWSER_COMPONENT_UPDATER_REGISTRATION_H_ - -#include "components/component_updater/android/component_loader_policy.h" - -namespace weblayer { - -// ComponentLoaderPolicies for component to load in WebLayer during startup. -component_updater::ComponentLoaderPolicyVector GetComponentLoaderPolicies(); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_COMPONENT_UPDATER_REGISTRATION_H_ \ No newline at end of file
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc deleted file mode 100644 index e0fefa1f..0000000 --- a/weblayer/browser/content_browser_client_impl.cc +++ /dev/null
@@ -1,1269 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/content_browser_client_impl.h" - -#include <memory> -#include <utility> - -#include "base/command_line.h" -#include "base/containers/flat_set.h" -#include "base/files/file.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/strings/string_piece.h" -#include "base/threading/thread_restrictions.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "components/autofill/content/browser/content_autofill_driver_factory.h" -#include "components/blocked_content/popup_blocker.h" -#include "components/captive_portal/core/buildflags.h" -#include "components/content_capture/browser/onscreen_content_provider.h" -#include "components/content_settings/core/browser/cookie_settings.h" -#include "components/embedder_support/content_settings_utils.h" -#include "components/embedder_support/switches.h" -#include "components/embedder_support/user_agent_utils.h" -#include "components/error_page/common/error.h" -#include "components/error_page/common/localized_error.h" -#include "components/error_page/content/browser/net_error_auto_reloader.h" -#include "components/metrics/metrics_service.h" -#include "components/network_time/network_time_tracker.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "components/no_state_prefetch/common/prerender_url_loader_throttle.h" -#include "components/page_load_metrics/browser/metrics_navigation_throttle.h" -#include "components/page_load_metrics/browser/metrics_web_contents_observer.h" -#include "components/performance_manager/embedder/performance_manager_registry.h" -#include "components/prefs/json_pref_store.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/pref_service_factory.h" -#include "components/prefs/scoped_user_pref_update.h" -#include "components/security_interstitials/content/insecure_form_navigation_throttle.h" -#include "components/security_interstitials/content/security_interstitial_tab_helper.h" -#include "components/security_interstitials/content/ssl_cert_reporter.h" -#include "components/security_interstitials/content/ssl_error_handler.h" -#include "components/security_interstitials/content/ssl_error_navigation_throttle.h" -#include "components/site_isolation/pref_names.h" -#include "components/site_isolation/preloaded_isolated_origins.h" -#include "components/site_isolation/site_isolation_policy.h" -#include "components/strings/grit/components_locale_settings.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" -#include "components/subresource_filter/content/browser/ruleset_version.h" -#include "components/user_prefs/user_prefs.h" -#include "components/variations/service/variations_service.h" -#include "components/version_info/version_info.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/client_certificate_delegate.h" -#include "content/public/browser/devtools_manager_delegate.h" -#include "content/public/browser/generated_code_cache_settings.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/navigation_throttle.h" -#include "content/public/browser/network_service_instance.h" -#include "content/public/browser/page_navigator.h" -#include "content/public/browser/permission_controller.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/content_features.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/url_constants.h" -#include "content/public/common/window_container_type.mojom.h" -#include "mojo/public/cpp/bindings/binder_map.h" -#include "net/cert/x509_certificate.h" -#include "net/cookies/site_for_cookies.h" -#include "net/proxy_resolution/proxy_config.h" -#include "net/ssl/client_cert_identity.h" -#include "net/ssl/ssl_private_key.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "services/network/network_service.h" -#include "services/network/public/mojom/network_context.mojom.h" -#include "services/network/public/mojom/network_service.mojom.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" -#include "third_party/blink/public/common/loader/url_loader_throttle.h" -#include "third_party/blink/public/common/permissions/permission_utils.h" -#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" -#include "third_party/blink/public/common/web_preferences/web_preferences.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/page_transition_types.h" -#include "url/gurl.h" -#include "url/origin.h" -#include "url/url_constants.h" -#include "weblayer/browser/browser_main_parts_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/cookie_settings_factory.h" -#include "weblayer/browser/download_manager_delegate_impl.h" -#include "weblayer/browser/feature_list_creator.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/browser/navigation_controller_impl.h" -#include "weblayer/browser/navigation_error_navigation_throttle.h" -#include "weblayer/browser/navigation_ui_data_impl.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h" -#include "weblayer/browser/page_specific_content_settings_delegate.h" -#include "weblayer/browser/password_manager_driver_factory.h" -#include "weblayer/browser/popup_navigation_delegate_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/signin_url_loader_throttle.h" -#include "weblayer/browser/system_network_context_manager.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/browser/web_contents_view_delegate_impl.h" -#include "weblayer/browser/weblayer_browser_interface_binders.h" -#include "weblayer/browser/weblayer_security_blocking_page_factory.h" -#include "weblayer/browser/weblayer_speech_recognition_manager_delegate.h" -#include "weblayer/common/features.h" -#include "weblayer/common/weblayer_paths.h" -#include "weblayer/public/fullscreen_delegate.h" -#include "weblayer/public/main.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/bundle_utils.h" -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/android/path_utils.h" -#include "base/functional/bind.h" -#include "components/browser_ui/client_certificate/android/ssl_client_certificate_request.h" -#include "components/cdm/browser/media_drm_storage_impl.h" // nogncheck -#include "components/crash/content/browser/crash_handler_host_linux.h" -#include "components/embedder_support/android/metrics/android_metrics_service_client.h" -#include "components/media_router/browser/presentation/presentation_service_delegate_impl.h" // nogncheck -#include "components/navigation_interception/intercept_navigation_delegate.h" -#include "components/permissions/bluetooth_delegate_impl.h" -#include "components/safe_browsing/core/browser/realtime/policy_engine.h" // nogncheck -#include "components/safe_browsing/core/browser/realtime/url_lookup_service.h" // nogncheck -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "components/spellcheck/browser/spell_check_host_impl.h" // nogncheck -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "mojo/public/cpp/bindings/self_owned_receiver.h" -#include "ui/base/resource/resource_bundle_android.h" -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" -#include "weblayer/browser/android_descriptors.h" -#include "weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/devtools_manager_delegate_android.h" -#include "weblayer/browser/http_auth_handler_impl.h" -#include "weblayer/browser/media/media_router_factory.h" -#include "weblayer/browser/proxying_url_loader_factory_impl.h" -#include "weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#include "weblayer/browser/tts_environment_android_impl.h" -#include "weblayer/browser/weblayer_factory_impl_android.h" -#endif - -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) || \ - BUILDFLAG(IS_ANDROID) -#include "content/public/common/content_descriptors.h" -#endif - -#if BUILDFLAG(IS_WIN) -#include "sandbox/policy/win/sandbox_win.h" -#include "sandbox/win/src/sandbox.h" -#endif - -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) -#include "weblayer/browser/captive_portal_service_factory.h" -#endif - -#if BUILDFLAG(ENABLE_ARCORE) -#include "weblayer/browser/xr/xr_integration_client_impl.h" -#endif // BUILDFLAG(ENABLE_ARCORE) - -namespace switches { -// Specifies a list of hosts for whom we bypass proxy settings and use direct -// connections. Ignored if --proxy-auto-detect or --no-proxy-server are also -// specified. This is a comma-separated list of bypass rules. See: -// "net/proxy_resolution/proxy_bypass_rules.h" for the format of these rules. -// TODO(alexclarke): Find a better place for this. -const char kProxyBypassList[] = "proxy-bypass-list"; -} // namespace switches - -namespace weblayer { - -namespace { - -bool IsSafebrowsingSupported() { - // TODO(timvolodine): consider the non-android case, see crbug.com/1015809. - // TODO(timvolodine): consider refactoring this out into safe_browsing/. -#if BUILDFLAG(IS_ANDROID) - return true; -#else - return false; -#endif -} - -bool IsNetworkErrorAutoReloadEnabled() { - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(embedder_support::kEnableAutoReload)) - return true; - if (command_line.HasSwitch(embedder_support::kDisableAutoReload)) - return false; - return true; -} - -bool IsInHostedApp(content::WebContents* web_contents) { - return false; -} - -bool ShouldIgnoreInterstitialBecauseNavigationDefaultedToHttps( - content::NavigationHandle* handle) { - return false; -} - -class SSLCertReporterImpl : public SSLCertReporter { - public: - void ReportInvalidCertificateChain( - const std::string& serialized_report) override {} -}; - -// Wrapper for SSLErrorHandler::HandleSSLError() that supplies //weblayer-level -// parameters. -void HandleSSLErrorWrapper( - content::WebContents* web_contents, - int cert_error, - const net::SSLInfo& ssl_info, - const GURL& request_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter, - SSLErrorHandler::BlockingPageReadyCallback blocking_page_ready_callback) { - captive_portal::CaptivePortalService* captive_portal_service = nullptr; - -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) - captive_portal_service = CaptivePortalServiceFactory::GetForBrowserContext( - web_contents->GetBrowserContext()); -#endif - - SSLErrorHandler::HandleSSLError( - web_contents, cert_error, ssl_info, request_url, - std::move(ssl_cert_reporter), std::move(blocking_page_ready_callback), - BrowserProcess::GetInstance()->GetNetworkTimeTracker(), - captive_portal_service, - std::make_unique<WebLayerSecurityBlockingPageFactory>()); -} - -#if BUILDFLAG(IS_ANDROID) -void CreateOriginId(cdm::MediaDrmStorageImpl::OriginIdObtainedCB callback) { - std::move(callback).Run(true, base::UnguessableToken::Create()); -} - -void AllowEmptyOriginIdCB(base::OnceCallback<void(bool)> callback) { - // Since CreateOriginId() always returns a non-empty origin ID, we don't need - // to allow empty origin ID. - std::move(callback).Run(false); -} - -void CreateMediaDrmStorage( - content::RenderFrameHost* render_frame_host, - mojo::PendingReceiver<::media::mojom::MediaDrmStorage> receiver) { - CHECK(render_frame_host); - - if (render_frame_host->GetLastCommittedOrigin().opaque()) { - DVLOG(1) << __func__ << ": Unique origin."; - return; - } - - // The object will be deleted on connection error, or when the frame navigates - // away. - new cdm::MediaDrmStorageImpl( - *render_frame_host, base::BindRepeating(&CreateOriginId), - base::BindRepeating(&AllowEmptyOriginIdCB), std::move(receiver)); -} -#endif // BUILDFLAG(IS_ANDROID) - -void RegisterPrefs(PrefRegistrySimple* pref_registry) { - network_time::NetworkTimeTracker::RegisterPrefs(pref_registry); - pref_registry->RegisterIntegerPref(kDownloadNextIDPref, 0); -#if BUILDFLAG(IS_ANDROID) - metrics::AndroidMetricsServiceClient::RegisterPrefs(pref_registry); - safe_browsing::RegisterLocalStatePrefs(pref_registry); -#else - // Call MetricsService::RegisterPrefs() as VariationsService::RegisterPrefs() - // CHECKs that kVariationsCrashStreak has already been registered. - // - // Note that the above call to AndroidMetricsServiceClient::RegisterPrefs() - // implicitly calls MetricsService::RegisterPrefs(), so the below call is - // necessary only on non-Android platforms. - metrics::MetricsService::RegisterPrefs(pref_registry); -#endif - variations::VariationsService::RegisterPrefs(pref_registry); - subresource_filter::IndexedRulesetVersion::RegisterPrefs(pref_registry); -} - -mojo::PendingRemote<prerender::mojom::PrerenderCanceler> GetPrerenderCanceler( - content::WebContents* web_contents) { - mojo::PendingRemote<prerender::mojom::PrerenderCanceler> canceler; - weblayer::NoStatePrefetchContentsFromWebContents(web_contents) - ->AddPrerenderCancelerReceiver(canceler.InitWithNewPipeAndPassReceiver()); - return canceler; -} - -} // namespace - -ContentBrowserClientImpl::ContentBrowserClientImpl(MainParams* params) - : params_(params) { -} - -ContentBrowserClientImpl::~ContentBrowserClientImpl() = default; - -std::unique_ptr<content::BrowserMainParts> -ContentBrowserClientImpl::CreateBrowserMainParts( - bool /* is_integration_test */) { - // This should be called after CreateFeatureListAndFieldTrials(), which - // creates |local_state_|. - DCHECK(local_state_); - std::unique_ptr<BrowserMainPartsImpl> browser_main_parts = - std::make_unique<BrowserMainPartsImpl>(params_, std::move(local_state_)); - - return browser_main_parts; -} - -std::string ContentBrowserClientImpl::GetApplicationLocale() { - return i18n::GetApplicationLocale(); -} - -std::string ContentBrowserClientImpl::GetAcceptLangs( - content::BrowserContext* context) { - return i18n::GetAcceptLangs(); -} - -content::AllowServiceWorkerResult ContentBrowserClientImpl::AllowServiceWorker( - const GURL& scope, - const net::SiteForCookies& site_for_cookies, - const absl::optional<url::Origin>& top_frame_origin, - const GURL& script_url, - content::BrowserContext* context) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - return embedder_support::AllowServiceWorker( - scope, site_for_cookies, top_frame_origin, - CookieSettingsFactory::GetForBrowserContext(context).get(), - HostContentSettingsMapFactory::GetForBrowserContext(context)); -} - -bool ContentBrowserClientImpl::AllowSharedWorker( - const GURL& worker_url, - const net::SiteForCookies& site_for_cookies, - const absl::optional<url::Origin>& top_frame_origin, - const std::string& name, - const blink::StorageKey& storage_key, - content::BrowserContext* context, - int render_process_id, - int render_frame_id) { - return embedder_support::AllowSharedWorker( - worker_url, site_for_cookies, top_frame_origin, name, storage_key, - render_process_id, render_frame_id, - CookieSettingsFactory::GetForBrowserContext(context).get()); -} - -void ContentBrowserClientImpl::AllowWorkerFileSystem( - const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& render_frames, - base::OnceCallback<void(bool)> callback) { - std::move(callback).Run(embedder_support::AllowWorkerFileSystem( - url, render_frames, - CookieSettingsFactory::GetForBrowserContext(browser_context).get())); -} - -bool ContentBrowserClientImpl::AllowWorkerIndexedDB( - const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& render_frames) { - return embedder_support::AllowWorkerIndexedDB( - url, render_frames, - CookieSettingsFactory::GetForBrowserContext(browser_context).get()); -} - -bool ContentBrowserClientImpl::AllowWorkerCacheStorage( - const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& render_frames) { - return embedder_support::AllowWorkerCacheStorage( - url, render_frames, - CookieSettingsFactory::GetForBrowserContext(browser_context).get()); -} - -bool ContentBrowserClientImpl::AllowWorkerWebLocks( - const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& render_frames) { - return embedder_support::AllowWorkerWebLocks( - url, CookieSettingsFactory::GetForBrowserContext(browser_context).get()); -} - -std::unique_ptr<content::WebContentsViewDelegate> -ContentBrowserClientImpl::GetWebContentsViewDelegate( - content::WebContents* web_contents) { - performance_manager::PerformanceManagerRegistry::GetInstance() - ->MaybeCreatePageNodeForWebContents(web_contents); - return std::make_unique<WebContentsViewDelegateImpl>(web_contents); -} - -bool ContentBrowserClientImpl::CanShutdownGpuProcessNowOnIOThread() { - return true; -} - -std::unique_ptr<content::DevToolsManagerDelegate> -ContentBrowserClientImpl::CreateDevToolsManagerDelegate() { -#if BUILDFLAG(IS_ANDROID) - return std::make_unique<DevToolsManagerDelegateAndroid>(); -#else - return std::make_unique<content::DevToolsManagerDelegate>(); -#endif -} - -void ContentBrowserClientImpl::LogWebFeatureForCurrentPage( - content::RenderFrameHost* render_frame_host, - blink::mojom::WebFeature feature) { - page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage( - render_frame_host, feature); -} - -std::string ContentBrowserClientImpl::GetProduct() { - return std::string(version_info::GetProductNameAndVersionForUserAgent()); -} - -std::string ContentBrowserClientImpl::GetUserAgent() { - return embedder_support::GetUserAgent(); -} - -blink::UserAgentMetadata ContentBrowserClientImpl::GetUserAgentMetadata() { - return embedder_support::GetUserAgentMetadata(); -} - -void ContentBrowserClientImpl::OverrideWebkitPrefs( - content::WebContents* web_contents, - blink::web_pref::WebPreferences* prefs) { - prefs->default_encoding = l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING); - // TODO(crbug.com/1131016): Support Picture in Picture on WebLayer. - prefs->picture_in_picture_enabled = false; - - TabImpl* tab = TabImpl::FromWebContents(web_contents); - if (tab) - tab->SetWebPreferences(prefs); -} - -void ContentBrowserClientImpl::ConfigureNetworkContextParams( - content::BrowserContext* context, - bool in_memory, - const base::FilePath& relative_partition_path, - network::mojom::NetworkContextParams* context_params, - cert_verifier::mojom::CertVerifierCreationParams* - cert_verifier_creation_params) { - SystemNetworkContextManager::ConfigureDefaultNetworkContextParams( - context_params, GetUserAgent()); - // Headers coming from the embedder are implicitly trusted and should not - // trigger CORS checks. - context_params->allow_any_cors_exempt_header_for_browser = true; - context_params->accept_language = GetAcceptLangs(context); - if (!context->IsOffTheRecord()) { - context_params->file_paths = network::mojom::NetworkContextFilePaths::New(); - context_params->file_paths->data_directory = context->GetPath(); - context_params->file_paths->cookie_database_name = - base::FilePath(FILE_PATH_LITERAL("Cookies")); - context_params->file_paths->http_cache_directory = - ProfileImpl::GetCachePath(context).Append(FILE_PATH_LITERAL("Cache")); - } - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(::switches::kProxyServer)) { - std::string proxy_server = - command_line->GetSwitchValueASCII(::switches::kProxyServer); - net::ProxyConfig proxy_config; - proxy_config.proxy_rules().ParseFromString(proxy_server); - if (command_line->HasSwitch(::switches::kProxyBypassList)) { - std::string bypass_list = - command_line->GetSwitchValueASCII(::switches::kProxyBypassList); - proxy_config.proxy_rules().bypass_rules.ParseFromString(bypass_list); - } - context_params->initial_proxy_config = net::ProxyConfigWithAnnotation( - proxy_config, - net::DefineNetworkTrafficAnnotation("undefined", "Nothing here yet.")); - } - if (command_line->HasSwitch(embedder_support::kShortReportingDelay)) { - context_params->reporting_delivery_interval = base::Milliseconds(100); - } -} - -void ContentBrowserClientImpl::OnNetworkServiceCreated( - network::mojom::NetworkService* network_service) { - if (!SystemNetworkContextManager::HasInstance()) - SystemNetworkContextManager::CreateInstance( - embedder_support::GetUserAgent()); - SystemNetworkContextManager::GetInstance()->OnNetworkServiceCreated( - network_service); -} - -std::unique_ptr<blink::URLLoaderThrottle> -ContentBrowserClientImpl::MaybeCreateSafeBrowsingURLLoaderThrottle( - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - int frame_tree_node_id) { - if (base::FeatureList::IsEnabled(features::kWebLayerSafeBrowsing) && - IsSafebrowsingSupported()) { -#if BUILDFLAG(IS_ANDROID) - BrowserContextImpl* browser_context_impl = - static_cast<BrowserContextImpl*>(browser_context); - bool is_safe_browsing_enabled = safe_browsing::IsSafeBrowsingEnabled( - *browser_context_impl->pref_service()); - - if (is_safe_browsing_enabled) { - bool is_url_real_time_lookup_enabled = - safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup( - browser_context_impl->pref_service(), - browser_context_impl->IsOffTheRecord(), - FeatureListCreator::GetInstance()->variations_service()); - - // |url_lookup_service| is used when real time url check is enabled. - safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service = - is_url_real_time_lookup_enabled - ? RealTimeUrlLookupServiceFactory::GetForBrowserContext( - browser_context) - : nullptr; - return GetSafeBrowsingService()->CreateURLLoaderThrottle( - wc_getter, frame_tree_node_id, url_lookup_service); - } -#endif - } - return nullptr; -} - -std::vector<std::unique_ptr<blink::URLLoaderThrottle>> -ContentBrowserClientImpl::CreateURLLoaderThrottles( - const network::ResourceRequest& request, - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) { - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result; - - if (auto safe_browsing_throttle = MaybeCreateSafeBrowsingURLLoaderThrottle( - browser_context, wc_getter, frame_tree_node_id); - safe_browsing_throttle) { - result.push_back(std::move(safe_browsing_throttle)); - } - - auto signin_throttle = - SigninURLLoaderThrottle::Create(browser_context, wc_getter); - if (signin_throttle) - result.push_back(std::move(signin_throttle)); - - // Create prerender URL throttle. - auto* web_contents = wc_getter.Run(); - auto* no_state_prefetch_contents = - NoStatePrefetchContentsFromWebContents(web_contents); - if (no_state_prefetch_contents) { - result.push_back(std::make_unique<prerender::PrerenderURLLoaderThrottle>( - prerender::PrerenderHistograms::GetHistogramPrefix( - no_state_prefetch_contents->origin()), - GetPrerenderCanceler(web_contents))); - } - - return result; -} - -std::vector<std::unique_ptr<blink::URLLoaderThrottle>> -ContentBrowserClientImpl::CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - int frame_tree_node_id) { - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result; - - if (auto safe_browsing_throttle = MaybeCreateSafeBrowsingURLLoaderThrottle( - browser_context, wc_getter, frame_tree_node_id); - safe_browsing_throttle) { - result.push_back(std::move(safe_browsing_throttle)); - } - - return result; -} - -bool ContentBrowserClientImpl::IsHandledURL(const GURL& url) { - if (!url.is_valid()) { - // WebLayer handles error cases. - return true; - } - - std::string scheme = url.scheme(); - - DCHECK_EQ(scheme, base::ToLowerASCII(scheme)); - static const char* const kProtocolList[] = { - url::kHttpScheme, - url::kHttpsScheme, -#if BUILDFLAG(ENABLE_WEBSOCKETS) - url::kWsScheme, - url::kWssScheme, -#endif // BUILDFLAG(ENABLE_WEBSOCKETS) - url::kFileScheme, - content::kChromeDevToolsScheme, - content::kChromeUIScheme, - content::kChromeUIUntrustedScheme, - url::kDataScheme, -#if BUILDFLAG(IS_ANDROID) - url::kContentScheme, -#endif // BUILDFLAG(IS_ANDROID) - url::kAboutScheme, - url::kBlobScheme, - url::kFileSystemScheme, - }; - for (const char* supported_protocol : kProtocolList) { - if (scheme == supported_protocol) - return true; - } - - return false; -} - -std::vector<url::Origin> -ContentBrowserClientImpl::GetOriginsRequiringDedicatedProcess() { - return site_isolation::GetBrowserSpecificBuiltInIsolatedOrigins(); -} - -bool ContentBrowserClientImpl::MayReuseHost( - content::RenderProcessHost* process_host) { - // If there is currently a no-state prefetcher in progress for the host - // provided, it may not be shared. We require prefetchers to be by themselves - // in a separate process so that we can monitor their resource usage. - prerender::NoStatePrefetchManager* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext( - process_host->GetBrowserContext()); - if (no_state_prefetch_manager && - !no_state_prefetch_manager->MayReuseProcessHost(process_host)) { - return false; - } - - return true; -} - -void ContentBrowserClientImpl::OverridePageVisibilityState( - content::RenderFrameHost* render_frame_host, - content::PageVisibilityState* visibility_state) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(render_frame_host); - DCHECK(web_contents); - - prerender::NoStatePrefetchManager* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext( - web_contents->GetBrowserContext()); - if (no_state_prefetch_manager && - no_state_prefetch_manager->IsWebContentsPrefetching(web_contents)) { - *visibility_state = content::PageVisibilityState::kHiddenButPainting; - } -} - -bool ContentBrowserClientImpl::ShouldDisableSiteIsolation( - content::SiteIsolationMode site_isolation_mode) { - return site_isolation::SiteIsolationPolicy:: - ShouldDisableSiteIsolationDueToMemoryThreshold(site_isolation_mode); -} - -std::vector<std::string> -ContentBrowserClientImpl::GetAdditionalSiteIsolationModes() { - if (site_isolation::SiteIsolationPolicy::IsIsolationForPasswordSitesEnabled()) - return {"Isolate Password Sites"}; - return {}; -} - -void ContentBrowserClientImpl::PersistIsolatedOrigin( - content::BrowserContext* context, - const url::Origin& origin, - content::ChildProcessSecurityPolicy::IsolatedOriginSource source) { - site_isolation::SiteIsolationPolicy::PersistIsolatedOrigin(context, origin, - source); -} - -base::OnceClosure ContentBrowserClientImpl::SelectClientCertificate( - content::BrowserContext* browser_context, - content::WebContents* web_contents, - net::SSLCertRequestInfo* cert_request_info, - net::ClientCertIdentityList client_certs, - std::unique_ptr<content::ClientCertificateDelegate> delegate) { -#if BUILDFLAG(IS_ANDROID) - if (web_contents) { - return browser_ui::ShowSSLClientCertificateSelector( - web_contents, cert_request_info, std::move(delegate)); - } - // Otherwise, fall through to continuing without a certificate. -#endif - delegate->ContinueWithCertificate(nullptr, nullptr); - return base::OnceClosure(); -} - -bool ContentBrowserClientImpl::CanCreateWindow( - content::RenderFrameHost* opener, - const GURL& opener_url, - const GURL& opener_top_level_frame_url, - const url::Origin& source_origin, - content::mojom::WindowContainerType container_type, - const GURL& target_url, - const content::Referrer& referrer, - const std::string& frame_name, - WindowOpenDisposition disposition, - const blink::mojom::WindowFeatures& features, - bool user_gesture, - bool opener_suppressed, - bool* no_javascript_access) { - *no_javascript_access = false; - - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(opener); - - // Block popups if there is no NewTabDelegate. - TabImpl* tab = TabImpl::FromWebContents(web_contents); - if (!tab || !tab->has_new_tab_delegate()) - return false; - - if (container_type == content::mojom::WindowContainerType::BACKGROUND || - container_type == content::mojom::WindowContainerType::PERSISTENT) { - // WebLayer does not support extensions/apps, which are the only permitted - // users of background windows. - return false; - } - - // WindowOpenDisposition has a *ton* of types, but the following are really - // the only ones that should be hit for this code path. - switch (disposition) { - case WindowOpenDisposition::NEW_FOREGROUND_TAB: - [[fallthrough]]; - case WindowOpenDisposition::NEW_BACKGROUND_TAB: - [[fallthrough]]; - case WindowOpenDisposition::NEW_POPUP: - [[fallthrough]]; - case WindowOpenDisposition::NEW_WINDOW: - break; - default: - return false; - } - - GURL popup_url(target_url); - opener->GetProcess()->FilterURL(false, &popup_url); - // Use ui::PAGE_TRANSITION_LINK to match the similar logic in //chrome. - content::OpenURLParams params(popup_url, referrer, disposition, - ui::PAGE_TRANSITION_LINK, - /*is_renderer_initiated*/ true); - params.user_gesture = user_gesture; - params.initiator_origin = source_origin; - params.source_render_frame_id = opener->GetRoutingID(); - params.source_render_process_id = opener->GetProcess()->GetID(); - params.source_site_instance = opener->GetSiteInstance(); - // The content::OpenURLParams are created just for the delegate, and do not - // correspond to actual params created by //content, so pass null for the - // |open_url_params| argument here. - return blocked_content::MaybeBlockPopup( - web_contents, &opener_top_level_frame_url, - std::make_unique<PopupNavigationDelegateImpl>(params, web_contents, - opener), - /*open_url_params*/ nullptr, features, - HostContentSettingsMapFactory::GetForBrowserContext( - web_contents->GetBrowserContext())) != nullptr; -} - -content::ControllerPresentationServiceDelegate* -ContentBrowserClientImpl::GetControllerPresentationServiceDelegate( - content::WebContents* web_contents) { -#if BUILDFLAG(IS_ANDROID) - if (WebLayerFactoryImplAndroid::GetClientMajorVersion() < 88) - return nullptr; - - if (MediaRouterFactory::IsFeatureEnabled()) { - MediaRouterFactory::DoPlatformInitIfNeeded(); - return media_router::PresentationServiceDelegateImpl:: - GetOrCreateForWebContents(web_contents); - } -#endif - - return nullptr; -} - -void ContentBrowserClientImpl::OpenURL( - content::SiteInstance* site_instance, - const content::OpenURLParams& params, - base::OnceCallback<void(content::WebContents*)> callback) { - std::move(callback).Run( - ProfileImpl::FromBrowserContext(site_instance->GetBrowserContext()) - ->OpenUrl(params)); -} - -std::vector<std::unique_ptr<content::NavigationThrottle>> -ContentBrowserClientImpl::CreateThrottlesForNavigation( - content::NavigationHandle* handle) { - std::vector<std::unique_ptr<content::NavigationThrottle>> throttles; - - TabImpl* tab = TabImpl::FromWebContents(handle->GetWebContents()); - NavigationControllerImpl* navigation_controller = nullptr; - if (tab) { - navigation_controller = - static_cast<NavigationControllerImpl*>(tab->GetNavigationController()); - } - - NavigationImpl* navigation_impl = nullptr; - if (navigation_controller) { - navigation_impl = - navigation_controller->GetNavigationImplFromHandle(handle); - } - - if (handle->IsInMainFrame()) { - NavigationUIDataImpl* navigation_ui_data = - static_cast<NavigationUIDataImpl*>(handle->GetNavigationUIData()); - - if ((!navigation_ui_data || - !navigation_ui_data->disable_network_error_auto_reload()) && - (!navigation_impl || - !navigation_impl->disable_network_error_auto_reload()) && - IsNetworkErrorAutoReloadEnabled()) { - auto auto_reload_throttle = - error_page::NetErrorAutoReloader::MaybeCreateThrottleFor(handle); - if (auto_reload_throttle) - throttles.push_back(std::move(auto_reload_throttle)); - } - - // MetricsNavigationThrottle requires that it runs before - // NavigationThrottles that may delay or cancel navigations, so only - // NavigationThrottles that don't delay or cancel navigations (e.g. - // throttles that are only observing callbacks without affecting navigation - // behavior) should be added before MetricsNavigationThrottle. - throttles.push_back( - page_load_metrics::MetricsNavigationThrottle::Create(handle)); - if (TabImpl::FromWebContents(handle->GetWebContents())) { - throttles.push_back( - std::make_unique<NavigationErrorNavigationThrottle>(handle)); - } - } - - // The next highest priority throttle *must* be this as it's responsible for - // calling to NavigationController for certain events. - if (tab) { - auto throttle = navigation_controller->CreateNavigationThrottle(handle); - if (throttle) - throttles.push_back(std::move(throttle)); - } - - throttles.push_back(std::make_unique<SSLErrorNavigationThrottle>( - handle, std::make_unique<SSLCertReporterImpl>(), - base::BindOnce(&HandleSSLErrorWrapper), base::BindOnce(&IsInHostedApp), - base::BindOnce( - &ShouldIgnoreInterstitialBecauseNavigationDefaultedToHttps))); - - std::unique_ptr<security_interstitials::InsecureFormNavigationThrottle> - insecure_form_throttle = security_interstitials:: - InsecureFormNavigationThrottle::MaybeCreateNavigationThrottle( - handle, std::make_unique<WebLayerSecurityBlockingPageFactory>(), - nullptr); - if (insecure_form_throttle) { - throttles.push_back(std::move(insecure_form_throttle)); - } - - if (auto* throttle_manager = - subresource_filter::ContentSubresourceFilterThrottleManager:: - FromNavigationHandle(*handle)) { - throttle_manager->MaybeAppendNavigationThrottles(handle, &throttles); - } - -#if BUILDFLAG(IS_ANDROID) - if (IsSafebrowsingSupported()) { - std::unique_ptr<content::NavigationThrottle> safe_browsing_throttle = - GetSafeBrowsingService()->MaybeCreateSafeBrowsingNavigationThrottleFor( - handle); - if (safe_browsing_throttle) - throttles.push_back(std::move(safe_browsing_throttle)); - } - - if (!navigation_impl || !navigation_impl->disable_intent_processing()) { - std::unique_ptr<content::NavigationThrottle> intercept_navigation_throttle = - navigation_interception::InterceptNavigationDelegate:: - MaybeCreateThrottleFor( - handle, navigation_interception::SynchronyMode::kAsync); - if (intercept_navigation_throttle) - throttles.push_back(std::move(intercept_navigation_throttle)); - } -#endif - return throttles; -} - -content::GeneratedCodeCacheSettings -ContentBrowserClientImpl::GetGeneratedCodeCacheSettings( - content::BrowserContext* context) { - DCHECK(context); - // If we pass 0 for size, disk_cache will pick a default size using the - // heuristics based on available disk size. These are implemented in - // disk_cache::PreferredCacheSize in net/disk_cache/cache_util.cc. - return content::GeneratedCodeCacheSettings( - true, 0, ProfileImpl::GetCachePath(context)); -} - -void ContentBrowserClientImpl:: - RegisterAssociatedInterfaceBindersForRenderFrameHost( - content::RenderFrameHost& render_frame_host, - blink::AssociatedInterfaceRegistry& associated_registry) { - // TODO(https://crbug.com/1265864): Move the registry logic below to a - // dedicated file to ensure security review coverage. - // TODO(lingqi): Swap the parameters so that lambda functions are not needed. - associated_registry.AddInterface<autofill::mojom::AutofillDriver>( - base::BindRepeating( - [](content::RenderFrameHost* render_frame_host, - mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver> - receiver) { - autofill::ContentAutofillDriverFactory::BindAutofillDriver( - std::move(receiver), render_frame_host); - }, - &render_frame_host)); - associated_registry.AddInterface<autofill::mojom::PasswordManagerDriver>( - base::BindRepeating( - [](content::RenderFrameHost* render_frame_host, - mojo::PendingAssociatedReceiver< - autofill::mojom::PasswordManagerDriver> receiver) { - PasswordManagerDriverFactory::BindPasswordManagerDriver( - std::move(receiver), render_frame_host); - }, - &render_frame_host)); - associated_registry.AddInterface< - content_capture::mojom::ContentCaptureReceiver>(base::BindRepeating( - [](content::RenderFrameHost* render_frame_host, - mojo::PendingAssociatedReceiver< - content_capture::mojom::ContentCaptureReceiver> receiver) { - content_capture::OnscreenContentProvider::BindContentCaptureReceiver( - std::move(receiver), render_frame_host); - }, - &render_frame_host)); - associated_registry.AddInterface<page_load_metrics::mojom::PageLoadMetrics>( - base::BindRepeating( - [](content::RenderFrameHost* render_frame_host, - mojo::PendingAssociatedReceiver< - page_load_metrics::mojom::PageLoadMetrics> receiver) { - page_load_metrics::MetricsWebContentsObserver::BindPageLoadMetrics( - std::move(receiver), render_frame_host); - }, - &render_frame_host)); - associated_registry.AddInterface< - security_interstitials::mojom::InterstitialCommands>(base::BindRepeating( - [](content::RenderFrameHost* render_frame_host, - mojo::PendingAssociatedReceiver< - security_interstitials::mojom::InterstitialCommands> receiver) { - security_interstitials::SecurityInterstitialTabHelper:: - BindInterstitialCommands(std::move(receiver), render_frame_host); - }, - &render_frame_host)); - associated_registry.AddInterface< - subresource_filter::mojom::SubresourceFilterHost>(base::BindRepeating( - [](content::RenderFrameHost* render_frame_host, - mojo::PendingAssociatedReceiver< - subresource_filter::mojom::SubresourceFilterHost> receiver) { - subresource_filter::ContentSubresourceFilterThrottleManager:: - BindReceiver(std::move(receiver), render_frame_host); - }, - &render_frame_host)); -} - -void ContentBrowserClientImpl::ExposeInterfacesToRenderer( - service_manager::BinderRegistry* registry, - blink::AssociatedInterfaceRegistry* associated_registry, - content::RenderProcessHost* render_process_host) { - performance_manager::PerformanceManagerRegistry::GetInstance() - ->CreateProcessNodeAndExposeInterfacesToRendererProcess( - registry, render_process_host); -#if BUILDFLAG(IS_ANDROID) - auto create_spellcheck_host = - [](mojo::PendingReceiver<spellcheck::mojom::SpellCheckHost> receiver) { - mojo::MakeSelfOwnedReceiver(std::make_unique<SpellCheckHostImpl>(), - std::move(receiver)); - }; - registry->AddInterface<spellcheck::mojom::SpellCheckHost>( - base::BindRepeating(create_spellcheck_host), - content::GetUIThreadTaskRunner({})); - - if (base::FeatureList::IsEnabled(features::kWebLayerSafeBrowsing) && - IsSafebrowsingSupported()) { - GetSafeBrowsingService()->AddInterface(registry, render_process_host); - } -#endif // BUILDFLAG(IS_ANDROID) -} - -void ContentBrowserClientImpl::BindMediaServiceReceiver( - content::RenderFrameHost* render_frame_host, - mojo::GenericPendingReceiver receiver) { -#if BUILDFLAG(IS_ANDROID) - if (auto r = receiver.As<media::mojom::MediaDrmStorage>()) { - CreateMediaDrmStorage(render_frame_host, std::move(r)); - return; - } -#endif -} - -void ContentBrowserClientImpl::RegisterBrowserInterfaceBindersForFrame( - content::RenderFrameHost* render_frame_host, - mojo::BinderMapWithContext<content::RenderFrameHost*>* map) { - PopulateWebLayerFrameBinders(render_frame_host, map); - performance_manager::PerformanceManagerRegistry::GetInstance() - ->ExposeInterfacesToRenderFrame(map); -} - -void ContentBrowserClientImpl::RenderProcessWillLaunch( - content::RenderProcessHost* host) { - PageSpecificContentSettingsDelegate::InitializeRenderer(host); -} - -void ContentBrowserClientImpl::CreateFeatureListAndFieldTrials() { - local_state_ = CreateLocalState(); - feature_list_creator_ = - std::make_unique<FeatureListCreator>(local_state_.get()); - if (!SystemNetworkContextManager::HasInstance()) - SystemNetworkContextManager::CreateInstance(GetUserAgent()); - feature_list_creator_->SetSystemNetworkContextManager( - SystemNetworkContextManager::GetInstance()); - feature_list_creator_->CreateFeatureListAndFieldTrials(); -} - -#if BUILDFLAG(IS_ANDROID) -SafeBrowsingService* ContentBrowserClientImpl::GetSafeBrowsingService() { - return BrowserProcess::GetInstance()->GetSafeBrowsingService(); -} -#endif - -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) || \ - BUILDFLAG(IS_ANDROID) -void ContentBrowserClientImpl::GetAdditionalMappedFilesForChildProcess( - const base::CommandLine& command_line, - int child_process_id, - content::PosixFileDescriptorInfo* mappings) { -#if BUILDFLAG(IS_ANDROID) - base::MemoryMappedFile::Region region; - int fd = ui::GetMainAndroidPackFd(®ion); - mappings->ShareWithRegion(kWebLayerMainPakDescriptor, fd, region); - - fd = ui::GetCommonResourcesPackFd(®ion); - mappings->ShareWithRegion(kWebLayer100PercentPakDescriptor, fd, region); - - fd = ui::GetLocalePackFd(®ion); - mappings->ShareWithRegion(kWebLayerLocalePakDescriptor, fd, region); - - if (base::android::BundleUtils::IsBundle()) { - fd = ui::GetSecondaryLocalePackFd(®ion); - mappings->ShareWithRegion(kWebLayerSecondaryLocalePakDescriptor, fd, - region); - } else { - mappings->ShareWithRegion(kWebLayerSecondaryLocalePakDescriptor, - base::GlobalDescriptors::GetInstance()->Get( - kWebLayerSecondaryLocalePakDescriptor), - base::GlobalDescriptors::GetInstance()->GetRegion( - kWebLayerSecondaryLocalePakDescriptor)); - } - - int crash_signal_fd = - crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket(); - if (crash_signal_fd >= 0) - mappings->Share(kCrashDumpSignal, crash_signal_fd); -#endif // BUILDFLAG(IS_ANDROID) -} -#endif - -void ContentBrowserClientImpl::AppendExtraCommandLineSwitches( - base::CommandLine* command_line, - int child_process_id) { - const base::CommandLine& browser_command_line( - *base::CommandLine::ForCurrentProcess()); - std::string process_type = - command_line->GetSwitchValueASCII(::switches::kProcessType); - if (process_type == ::switches::kRendererProcess) { - // Please keep this in alphabetical order. - static const char* const kSwitchNames[] = { - embedder_support::kOriginTrialDisabledFeatures, - embedder_support::kOriginTrialPublicKey, - }; - command_line->CopySwitchesFrom(browser_command_line, kSwitchNames); - } -} - -// static -std::unique_ptr<PrefService> ContentBrowserClientImpl::CreateLocalState() { - auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>(); - - RegisterPrefs(pref_registry.get()); - base::FilePath path; - CHECK(base::PathService::Get(DIR_USER_DATA, &path)); - path = path.AppendASCII("Local State"); - PrefServiceFactory pref_service_factory; - pref_service_factory.set_user_prefs( - base::MakeRefCounted<JsonPrefStore>(path)); - - { - // Creating the prefs service may require reading the preferences from - // disk. - base::ScopedAllowBlocking allow_io; - return pref_service_factory.Create(pref_registry); - } -} - -#if BUILDFLAG(IS_ANDROID) -bool ContentBrowserClientImpl::WillCreateURLLoaderFactory( - content::BrowserContext* browser_context, - content::RenderFrameHost* frame, - int render_process_id, - URLLoaderFactoryType type, - const url::Origin& request_initiator, - absl::optional<int64_t> navigation_id, - ukm::SourceIdObj ukm_source_id, - mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver, - mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>* - header_client, - bool* bypass_redirect_checks, - bool* disable_secure_dns, - network::mojom::URLLoaderFactoryOverridePtr* factory_override, - scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) { - // The navigation API intercepting API only supports main frame navigations. - if (type != URLLoaderFactoryType::kNavigation || frame->GetParent()) - return false; - - auto* web_contents = content::WebContents::FromRenderFrameHost(frame); - TabImpl* tab = TabImpl::FromWebContents(web_contents); - if (!tab) - return false; - - auto* navigation_controller = - static_cast<NavigationControllerImpl*>(tab->GetNavigationController()); - auto* navigation_impl = - navigation_controller->GetNavigationImplFromId(*navigation_id); - if (!navigation_impl) - return false; - - auto response = navigation_impl->TakeResponse(); - if (!response && !ProxyingURLLoaderFactoryImpl::HasCachedInputStream( - frame->GetFrameTreeNodeId(), - navigation_impl->navigation_entry_unique_id())) { - return false; - } - - mojo::PendingReceiver<network::mojom::URLLoaderFactory> proxied_receiver = - std::move(*factory_receiver); - mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_remote; - *factory_receiver = target_factory_remote.InitWithNewPipeAndPassReceiver(); - - // Owns itself. - new ProxyingURLLoaderFactoryImpl( - std::move(proxied_receiver), std::move(target_factory_remote), - navigation_impl->GetURL(), std::move(response), - frame->GetFrameTreeNodeId(), - navigation_impl->navigation_entry_unique_id()); - - return true; -} - -content::ContentBrowserClient::WideColorGamutHeuristic -ContentBrowserClientImpl::GetWideColorGamutHeuristic() { - // Always match window since a mismatch can cause inefficiency in surface - // flinger. - return WideColorGamutHeuristic::kUseWindow; -} - -std::unique_ptr<content::LoginDelegate> -ContentBrowserClientImpl::CreateLoginDelegate( - const net::AuthChallengeInfo& auth_info, - content::WebContents* web_contents, - const content::GlobalRequestID& request_id, - bool is_request_for_primary_main_frame, - const GURL& url, - scoped_refptr<net::HttpResponseHeaders> response_headers, - bool first_auth_attempt, - LoginAuthRequiredCallback auth_required_callback) { - return std::make_unique<HttpAuthHandlerImpl>( - auth_info, web_contents, first_auth_attempt, - std::move(auth_required_callback)); -} - -std::unique_ptr<content::TtsEnvironmentAndroid> -ContentBrowserClientImpl::CreateTtsEnvironmentAndroid() { - return std::make_unique<TtsEnvironmentAndroidImpl>(); -} - -bool ContentBrowserClientImpl:: - ShouldObserveContainerViewLocationForDialogOverlays() { - // Observe location changes of the container view as WebLayer might be - // embedded in a scrollable container and we need to update the position of - // any DialogOverlays. - return true; -} - -content::BluetoothDelegate* ContentBrowserClientImpl::GetBluetoothDelegate() { - if (!bluetooth_delegate_) { - bluetooth_delegate_ = std::make_unique<permissions::BluetoothDelegateImpl>( - std::make_unique<WebLayerBluetoothDelegateImplClient>()); - } - return bluetooth_delegate_.get(); -} - -#endif // BUILDFLAG(IS_ANDROID) - -content::SpeechRecognitionManagerDelegate* -ContentBrowserClientImpl::CreateSpeechRecognitionManagerDelegate() { - return new WebLayerSpeechRecognitionManagerDelegate(); -} - -bool ContentBrowserClientImpl::ShouldSandboxNetworkService() { -#if BUILDFLAG(IS_WIN) - // Weblayer ConfigureNetworkContextParams does not support data migration - // required for network sandbox to be enabled on Windows. - return false; -#else - return ContentBrowserClient::ShouldSandboxNetworkService(); -#endif // BUILDFLAG(IS_WIN) -} - -#if BUILDFLAG(ENABLE_ARCORE) -content::XrIntegrationClient* -ContentBrowserClientImpl::GetXrIntegrationClient() { - if (!XrIntegrationClientImpl::IsEnabled()) - return nullptr; - - if (!xr_integration_client_) - xr_integration_client_ = std::make_unique<XrIntegrationClientImpl>(); - return xr_integration_client_.get(); -} -#endif // BUILDFLAG(ENABLE_ARCORE) - -ukm::UkmService* ContentBrowserClientImpl::GetUkmService() { -#if BUILDFLAG(IS_ANDROID) - return WebLayerMetricsServiceClient::GetInstance()->GetUkmService(); -#else - return nullptr; -#endif -} - -bool ContentBrowserClientImpl::HasErrorPage(int http_status_code) { - // Use an internal error page, if we have one for the status code. - return error_page::LocalizedError::HasStrings( - error_page::Error::kHttpErrorDomain, http_status_code); -} - -bool ContentBrowserClientImpl::IsClipboardPasteAllowed( - content::RenderFrameHost* render_frame_host) { - DCHECK(render_frame_host); - - content::BrowserContext* browser_context = - render_frame_host->GetBrowserContext(); - DCHECK(browser_context); - - content::PermissionController* permission_controller = - browser_context->GetPermissionController(); - blink::mojom::PermissionStatus status = - permission_controller->GetPermissionStatusForCurrentDocument( - blink::PermissionType::CLIPBOARD_READ_WRITE, render_frame_host); - - if (!render_frame_host->HasTransientUserActivation() && - status != blink::mojom::PermissionStatus::GRANTED) { - // Paste requires either user activation, or granted web permission. - return false; - } - - return true; -} - -bool ContentBrowserClientImpl::ShouldPreconnectNavigation( - content::BrowserContext* browser_context) { - return true; -} - -} // namespace weblayer
diff --git a/weblayer/browser/content_browser_client_impl.h b/weblayer/browser/content_browser_client_impl.h deleted file mode 100644 index 5ea8414..0000000 --- a/weblayer/browser/content_browser_client_impl.h +++ /dev/null
@@ -1,274 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_CONTENT_BROWSER_CLIENT_IMPL_H_ -#define WEBLAYER_BROWSER_CONTENT_BROWSER_CLIENT_IMPL_H_ - -#include <memory> -#include <string> - -#include "base/compiler_specific.h" -#include "base/files/file_path.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/scoped_refptr.h" -#include "base/task/sequenced_task_runner.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "content/public/browser/child_process_security_policy.h" -#include "content/public/browser/content_browser_client.h" -#include "device/vr/buildflags/buildflags.h" -#include "services/service_manager/public/cpp/binder_registry.h" - -class PrefService; - -namespace blink { -class StorageKey; -} // namespace blink - -namespace net { -class SiteForCookies; -} // namespace net - -namespace permissions { -class BluetoothDelegateImpl; -} - -namespace weblayer { - -class FeatureListCreator; -class SafeBrowsingService; -struct MainParams; - -#if BUILDFLAG(ENABLE_ARCORE) -class XrIntegrationClientImpl; -#endif // BUILDFLAG(ENABLE_ARCORE) - -class ContentBrowserClientImpl : public content::ContentBrowserClient { - public: - explicit ContentBrowserClientImpl(MainParams* params); - ~ContentBrowserClientImpl() override; - - // ContentBrowserClient overrides. - std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts( - bool is_integration_test) override; - std::string GetApplicationLocale() override; - std::string GetAcceptLangs(content::BrowserContext* context) override; - content::AllowServiceWorkerResult AllowServiceWorker( - const GURL& scope, - const net::SiteForCookies& site_for_cookies, - const absl::optional<url::Origin>& top_frame_origin, - const GURL& script_url, - content::BrowserContext* context) override; - bool AllowSharedWorker(const GURL& worker_url, - const net::SiteForCookies& site_for_cookies, - const absl::optional<url::Origin>& top_frame_origin, - const std::string& name, - const blink::StorageKey& storage_key, - content::BrowserContext* context, - int render_process_id, - int render_frame_id) override; - void AllowWorkerFileSystem( - const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& render_frames, - base::OnceCallback<void(bool)> callback) override; - bool AllowWorkerIndexedDB(const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& - render_frames) override; - bool AllowWorkerCacheStorage( - const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& render_frames) - override; - bool AllowWorkerWebLocks(const GURL& url, - content::BrowserContext* browser_context, - const std::vector<content::GlobalRenderFrameHostId>& - render_frames) override; - std::unique_ptr<content::WebContentsViewDelegate> GetWebContentsViewDelegate( - content::WebContents* web_contents) override; - bool CanShutdownGpuProcessNowOnIOThread() override; - std::unique_ptr<content::DevToolsManagerDelegate> - CreateDevToolsManagerDelegate() override; - void LogWebFeatureForCurrentPage(content::RenderFrameHost* render_frame_host, - blink::mojom::WebFeature feature) override; - std::string GetProduct() override; - std::string GetUserAgent() override; - blink::UserAgentMetadata GetUserAgentMetadata() override; - void OverrideWebkitPrefs(content::WebContents* web_contents, - blink::web_pref::WebPreferences* prefs) override; - void ConfigureNetworkContextParams( - content::BrowserContext* context, - bool in_memory, - const base::FilePath& relative_partition_path, - network::mojom::NetworkContextParams* network_context_params, - cert_verifier::mojom::CertVerifierCreationParams* - cert_verifier_creation_params) override; - void OnNetworkServiceCreated( - network::mojom::NetworkService* network_service) override; - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> - CreateURLLoaderThrottles( - const network::ResourceRequest& request, - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::NavigationUIData* navigation_ui_data, - int frame_tree_node_id) override; - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> - CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - int frame_tree_node_id) override; - bool IsHandledURL(const GURL& url) override; - std::vector<url::Origin> GetOriginsRequiringDedicatedProcess() override; - bool MayReuseHost(content::RenderProcessHost* process_host) override; - void OverridePageVisibilityState( - content::RenderFrameHost* render_frame_host, - content::PageVisibilityState* visibility_state) override; - bool ShouldDisableSiteIsolation( - content::SiteIsolationMode site_isolation_mode) override; - std::vector<std::string> GetAdditionalSiteIsolationModes() override; - void PersistIsolatedOrigin( - content::BrowserContext* context, - const url::Origin& origin, - content::ChildProcessSecurityPolicy::IsolatedOriginSource source) - override; - base::OnceClosure SelectClientCertificate( - content::BrowserContext* browser_context, - content::WebContents* web_contents, - net::SSLCertRequestInfo* cert_request_info, - net::ClientCertIdentityList client_certs, - std::unique_ptr<content::ClientCertificateDelegate> delegate) override; - bool CanCreateWindow(content::RenderFrameHost* opener, - const GURL& opener_url, - const GURL& opener_top_level_frame_url, - const url::Origin& source_origin, - content::mojom::WindowContainerType container_type, - const GURL& target_url, - const content::Referrer& referrer, - const std::string& frame_name, - WindowOpenDisposition disposition, - const blink::mojom::WindowFeatures& features, - bool user_gesture, - bool opener_suppressed, - bool* no_javascript_access) override; - content::ControllerPresentationServiceDelegate* - GetControllerPresentationServiceDelegate( - content::WebContents* web_contents) override; - void OpenURL( - content::SiteInstance* site_instance, - const content::OpenURLParams& params, - base::OnceCallback<void(content::WebContents*)> callback) override; - std::vector<std::unique_ptr<content::NavigationThrottle>> - CreateThrottlesForNavigation(content::NavigationHandle* handle) override; - content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( - content::BrowserContext* context) override; - void RegisterAssociatedInterfaceBindersForRenderFrameHost( - content::RenderFrameHost& render_frame_host, - blink::AssociatedInterfaceRegistry& associated_registry) override; - void ExposeInterfacesToRenderer( - service_manager::BinderRegistry* registry, - blink::AssociatedInterfaceRegistry* associated_registry, - content::RenderProcessHost* render_process_host) override; - void BindMediaServiceReceiver(content::RenderFrameHost* render_frame_host, - mojo::GenericPendingReceiver receiver) override; - void RegisterBrowserInterfaceBindersForFrame( - content::RenderFrameHost* render_frame_host, - mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override; - void BindHostReceiverForRenderer( - content::RenderProcessHost* render_process_host, - mojo::GenericPendingReceiver receiver) override; - void RenderProcessWillLaunch(content::RenderProcessHost* host) override; -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) || \ - BUILDFLAG(IS_ANDROID) - void GetAdditionalMappedFilesForChildProcess( - const base::CommandLine& command_line, - int child_process_id, - content::PosixFileDescriptorInfo* mappings) override; -#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) || - // BUILDFLAG(IS_ANDROID) - void AppendExtraCommandLineSwitches(base::CommandLine* command_line, - int child_process_id) override; -#if BUILDFLAG(IS_ANDROID) - bool WillCreateURLLoaderFactory( - content::BrowserContext* browser_context, - content::RenderFrameHost* frame, - int render_process_id, - URLLoaderFactoryType type, - const url::Origin& request_initiator, - absl::optional<int64_t> navigation_id, - ukm::SourceIdObj ukm_source_id, - mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver, - mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>* - header_client, - bool* bypass_redirect_checks, - bool* disable_secure_dns, - network::mojom::URLLoaderFactoryOverridePtr* factory_override, - scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) - override; - WideColorGamutHeuristic GetWideColorGamutHeuristic() override; - std::unique_ptr<content::LoginDelegate> CreateLoginDelegate( - const net::AuthChallengeInfo& auth_info, - content::WebContents* web_contents, - const content::GlobalRequestID& request_id, - bool is_request_for_primary_main_frame, - const GURL& url, - scoped_refptr<net::HttpResponseHeaders> response_headers, - bool first_auth_attempt, - LoginAuthRequiredCallback auth_required_callback) override; - std::unique_ptr<content::TtsEnvironmentAndroid> CreateTtsEnvironmentAndroid() - override; - bool ShouldObserveContainerViewLocationForDialogOverlays() override; - content::BluetoothDelegate* GetBluetoothDelegate() override; -#endif // BUILDFLAG(IS_ANDROID) - content::SpeechRecognitionManagerDelegate* - CreateSpeechRecognitionManagerDelegate() override; - bool ShouldSandboxNetworkService() override; -#if BUILDFLAG(ENABLE_ARCORE) - content::XrIntegrationClient* GetXrIntegrationClient() override; -#endif // BUILDFLAG(ENABLE_ARCORE) - ukm::UkmService* GetUkmService() override; - bool HasErrorPage(int http_status_code) override; - bool IsClipboardPasteAllowed( - content::RenderFrameHost* render_frame_host) override; - bool ShouldPreconnectNavigation( - content::BrowserContext* browser_context) override; - - void CreateFeatureListAndFieldTrials(); - - private: - std::unique_ptr<PrefService> CreateLocalState(); - -#if BUILDFLAG(IS_ANDROID) - SafeBrowsingService* GetSafeBrowsingService(); - - std::unique_ptr<permissions::BluetoothDelegateImpl> bluetooth_delegate_; -#endif - std::unique_ptr<blink::URLLoaderThrottle> - MaybeCreateSafeBrowsingURLLoaderThrottle( - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - int frame_tree_node_id); - - raw_ptr<MainParams> params_; - - // Local-state is created early on, before BrowserProcess. Ownership moves to - // BrowserMainParts, then BrowserProcess. BrowserProcess ultimately owns - // local-state so that it can be destroyed along with other BrowserProcess - // state. - std::unique_ptr<PrefService> local_state_; - - std::unique_ptr<FeatureListCreator> feature_list_creator_; - -#if BUILDFLAG(ENABLE_ARCORE) - std::unique_ptr<XrIntegrationClientImpl> xr_integration_client_; -#endif // BUILDFLAG(ENABLE_ARCORE) -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_CONTENT_BROWSER_CLIENT_IMPL_H_
diff --git a/weblayer/browser/content_browser_client_impl_receiver_bindings.cc b/weblayer/browser/content_browser_client_impl_receiver_bindings.cc deleted file mode 100644 index ec967671..0000000 --- a/weblayer/browser/content_browser_client_impl_receiver_bindings.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file exposes services from the browser to child processes. - -#include "weblayer/browser/content_browser_client_impl.h" - -#include "weblayer/browser/content_settings_manager_delegate.h" - -namespace weblayer { - -void ContentBrowserClientImpl::BindHostReceiverForRenderer( - content::RenderProcessHost* render_process_host, - mojo::GenericPendingReceiver receiver) { - if (auto host_receiver = - receiver.As<content_settings::mojom::ContentSettingsManager>()) { - content_settings::ContentSettingsManagerImpl::Create( - render_process_host, std::move(host_receiver), - std::make_unique<ContentSettingsManagerDelegate>()); - return; - } -} - -} // namespace weblayer
diff --git a/weblayer/browser/content_settings_browsertest.cc b/weblayer/browser/content_settings_browsertest.cc deleted file mode 100644 index 22eb3069..0000000 --- a/weblayer/browser/content_settings_browsertest.cc +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/content_settings/core/browser/cookie_settings.h" -#include "content/public/test/browser_test_utils.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/cookie_settings_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { -namespace { -constexpr char kHasLocalStorageScript[] = R"( - new Promise(function (resolve, reject) { - try { - localStorage.setItem('foo', 'bar'); - resolve(true); - } catch(e) { - resolve(false); - } - }) -)"; -} // namespace - -using ContentSettingsBrowserTest = WebLayerBrowserTest; - -IN_PROC_BROWSER_TEST_F(ContentSettingsBrowserTest, LocalStorageAvailable) { - ASSERT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"), - shell()); - content::WebContents* web_contents = - static_cast<TabImpl*>(shell()->tab())->web_contents(); - EXPECT_TRUE( - content::EvalJs(web_contents, kHasLocalStorageScript).ExtractBool()); -} - -IN_PROC_BROWSER_TEST_F(ContentSettingsBrowserTest, LocalStorageDenied) { - ASSERT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"), - shell()); - content::WebContents* web_contents = - static_cast<TabImpl*>(shell()->tab())->web_contents(); - // Blocking cookies for this URL should also block local storage. - CookieSettingsFactory::GetForBrowserContext(web_contents->GetBrowserContext()) - ->SetCookieSetting(embedded_test_server()->base_url(), - CONTENT_SETTING_BLOCK); - EXPECT_FALSE( - content::EvalJs(web_contents, kHasLocalStorageScript).ExtractBool()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/content_settings_manager_delegate.cc b/weblayer/browser/content_settings_manager_delegate.cc deleted file mode 100644 index d97f4a4..0000000 --- a/weblayer/browser/content_settings_manager_delegate.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/content_settings_manager_delegate.h" - -#include "components/content_settings/core/browser/cookie_settings.h" -#include "weblayer/browser/cookie_settings_factory.h" - -namespace weblayer { - -ContentSettingsManagerDelegate::ContentSettingsManagerDelegate() = default; - -ContentSettingsManagerDelegate::~ContentSettingsManagerDelegate() = default; - -scoped_refptr<content_settings::CookieSettings> -ContentSettingsManagerDelegate::GetCookieSettings( - content::BrowserContext* browser_context) { - return CookieSettingsFactory::GetForBrowserContext(browser_context); -} - -bool ContentSettingsManagerDelegate::AllowStorageAccess( - int render_process_id, - int render_frame_id, - content_settings::mojom::ContentSettingsManager::StorageType storage_type, - const GURL& url, - bool allowed, - base::OnceCallback<void(bool)>* callback) { - return false; -} - -std::unique_ptr<content_settings::ContentSettingsManagerImpl::Delegate> -ContentSettingsManagerDelegate::Clone() { - return std::make_unique<ContentSettingsManagerDelegate>(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/content_settings_manager_delegate.h b/weblayer/browser/content_settings_manager_delegate.h deleted file mode 100644 index 323daea..0000000 --- a/weblayer/browser/content_settings_manager_delegate.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_CONTENT_SETTINGS_MANAGER_DELEGATE_H_ -#define WEBLAYER_BROWSER_CONTENT_SETTINGS_MANAGER_DELEGATE_H_ - -#include "components/content_settings/browser/content_settings_manager_impl.h" - -namespace weblayer { - -class ContentSettingsManagerDelegate - : public content_settings::ContentSettingsManagerImpl::Delegate { - public: - ContentSettingsManagerDelegate(); - ~ContentSettingsManagerDelegate() override; - - private: - // content_settings::ContentSettingsManagerImpl::Delegate: - scoped_refptr<content_settings::CookieSettings> GetCookieSettings( - content::BrowserContext* browser_context) override; - bool AllowStorageAccess( - int render_process_id, - int render_frame_id, - content_settings::mojom::ContentSettingsManager::StorageType storage_type, - const GURL& url, - bool allowed, - base::OnceCallback<void(bool)>* callback) override; - std::unique_ptr<Delegate> Clone() override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_CONTENT_SETTINGS_MANAGER_DELEGATE_H_
diff --git a/weblayer/browser/content_view_render_view.cc b/weblayer/browser/content_view_render_view.cc deleted file mode 100644 index c1a08d0..0000000 --- a/weblayer/browser/content_view_render_view.cc +++ /dev/null
@@ -1,237 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/content_view_render_view.h" - -#include <android/bitmap.h> - -#include <memory> -#include <utility> - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/android/scoped_java_ref.h" -#include "base/functional/bind.h" -#include "base/lazy_instance.h" -#include "base/time/time.h" -#include "base/trace_event/trace_event.h" -#include "cc/slim/layer.h" -#include "content/public/browser/android/compositor.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "ui/android/resources/resource_manager.h" -#include "ui/android/view_android.h" -#include "ui/android/window_android.h" -#include "ui/gfx/android/java_bitmap.h" -#include "ui/gfx/geometry/size.h" -#include "weblayer/browser/java/jni/ContentViewRenderView_jni.h" - -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -ContentViewRenderView::ContentViewRenderView(JNIEnv* env, - jobject obj, - gfx::NativeWindow root_window) - : root_window_(root_window) { - java_obj_.Reset(env, obj); -} - -ContentViewRenderView::~ContentViewRenderView() { - DCHECK(content_height_changed_listener_.is_null()); -} - -void ContentViewRenderView::SetContentHeightChangedListener( - base::RepeatingClosure callback) { - DCHECK(content_height_changed_listener_.is_null() || callback.is_null()); - content_height_changed_listener_ = std::move(callback); -} - -// static -static jlong JNI_ContentViewRenderView_Init( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jobject>& jroot_window_android) { - gfx::NativeWindow root_window = - ui::WindowAndroid::FromJavaWindowAndroid(jroot_window_android); - ContentViewRenderView* content_view_render_view = - new ContentViewRenderView(env, obj, root_window); - return reinterpret_cast<intptr_t>(content_view_render_view); -} - -void ContentViewRenderView::Destroy(JNIEnv* env) { - delete this; -} - -void ContentViewRenderView::SetCurrentWebContents( - JNIEnv* env, - const JavaParamRef<jobject>& jweb_contents) { - InitCompositor(); - content::WebContents* web_contents = - content::WebContents::FromJavaWebContents(jweb_contents); - if (web_contents_) - web_contents_->SetPageBaseBackgroundColor(absl::nullopt); - if (web_contents_layer_) - web_contents_layer_->RemoveFromParent(); - - web_contents_ = web_contents; - web_contents_layer_ = web_contents ? web_contents->GetNativeView()->GetLayer() - : scoped_refptr<cc::slim::Layer>(); - - UpdateWebContentsBaseBackgroundColor(); - if (web_contents_layer_) - root_container_layer_->AddChild(web_contents_layer_); -} - -void ContentViewRenderView::OnViewportSizeChanged(JNIEnv* env, - jint width, - jint height) { - bool content_height_changed = content_height_ != height; - content_height_ = height; - if (content_height_changed && !content_height_changed_listener_.is_null()) - content_height_changed_listener_.Run(); -} - -void ContentViewRenderView::OnPhysicalBackingSizeChanged( - JNIEnv* env, - const JavaParamRef<jobject>& jweb_contents, - jint width, - jint height, - jboolean for_config_change) { - content::WebContents* web_contents = - content::WebContents::FromJavaWebContents(jweb_contents); - gfx::Size size(width, height); - - // The default resize timeout on Android is 1s. It was chosen with browser - // use case in mind where resize is rare (eg orientation change, fullscreen) - // and users are generally willing to wait for those cases instead of seeing - // a frame at the wrong size. Weblayer currently can be resized while user - // is interacting with the page, in which case the timeout is too long. - // For now, use the default long timeout only for rotation (ie config change) - // and just use a zero timeout for all other cases. - absl::optional<base::TimeDelta> override_deadline; - if (!for_config_change) - override_deadline = base::TimeDelta(); - web_contents->GetNativeView()->OnPhysicalBackingSizeChanged( - size, override_deadline); -} - -void ContentViewRenderView::SurfaceCreated(JNIEnv* env) { - InitCompositor(); -} - -void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env, - jboolean cache_back_buffer) { - if (cache_back_buffer) - compositor_->CacheBackBufferForCurrentSurface(); - - // When we switch from Chrome to other app we can't detach child surface - // controls because it leads to a visible hole: b/157439199. To avoid this we - // don't detach surfaces if the surface is going to be destroyed, they will be - // detached and freed by OS. - compositor_->PreserveChildSurfaceControls(); - - compositor_->SetSurface(nullptr, false); -} - -void ContentViewRenderView::SurfaceChanged( - JNIEnv* env, - jboolean can_be_used_with_surface_control, - jint width, - jint height, - jboolean transparent_background, - const JavaParamRef<jobject>& new_surface) { - use_transparent_background_ = transparent_background; - UpdateWebContentsBaseBackgroundColor(); - compositor_->SetRequiresAlphaChannel(use_transparent_background_); - // Java side will pass a null `new_surface` if the surface did not change. - if (new_surface) { - compositor_->SetSurface(new_surface, can_be_used_with_surface_control); - } - compositor_->SetWindowBounds(gfx::Size(width, height)); -} - -void ContentViewRenderView::SetNeedsRedraw(JNIEnv* env) { - if (compositor_) { - compositor_->SetNeedsRedraw(); - } -} - -base::android::ScopedJavaLocalRef<jobject> -ContentViewRenderView::GetResourceManager(JNIEnv* env) { - return compositor_->GetResourceManager().GetJavaObject(); -} - -void ContentViewRenderView::UpdateBackgroundColor(JNIEnv* env) { - if (!compositor_) - return; - compositor_->SetBackgroundColor( - requires_alpha_channel_ - ? SK_ColorTRANSPARENT - : Java_ContentViewRenderView_getBackgroundColor(env, java_obj_)); -} - -void ContentViewRenderView::SetRequiresAlphaChannel( - JNIEnv* env, - jboolean requires_alpha_channel) { - requires_alpha_channel_ = requires_alpha_channel; - UpdateBackgroundColor(env); -} - -void ContentViewRenderView::SetDidSwapBuffersCallbackEnabled(JNIEnv* env, - jboolean enable) { - InitCompositor(); - compositor_->SetDidSwapBuffersCallbackEnabled(enable); -} - -void ContentViewRenderView::UpdateLayerTreeHost() { - // TODO(wkorman): Rename Layout to UpdateLayerTreeHost in all Android - // Compositor related classes. -} - -void ContentViewRenderView::DidSwapFrame(int pending_frames) { - JNIEnv* env = base::android::AttachCurrentThread(); - TRACE_EVENT0("weblayer", "Java_ContentViewRenderView_didSwapFrame"); - if (Java_ContentViewRenderView_didSwapFrame(env, java_obj_)) { - compositor_->SetNeedsRedraw(); - } -} - -void ContentViewRenderView::DidSwapBuffers(const gfx::Size& swap_size) { - JNIEnv* env = base::android::AttachCurrentThread(); - bool matches_window_bounds = swap_size == compositor_->GetWindowBounds(); - Java_ContentViewRenderView_didSwapBuffers(env, java_obj_, - matches_window_bounds); -} - -void ContentViewRenderView::EvictCachedSurface(JNIEnv* env) { - compositor_->EvictCachedBackBuffer(); -} - -void ContentViewRenderView::InitCompositor() { - if (compositor_) - return; - - compositor_.reset(content::Compositor::Create(this, root_window_)); - root_container_layer_ = cc::slim::Layer::Create(); - root_container_layer_->SetIsDrawable(false); - compositor_->SetRootLayer(root_container_layer_); - UpdateBackgroundColor(base::android::AttachCurrentThread()); -} - -void ContentViewRenderView::UpdateWebContentsBaseBackgroundColor() { - if (!web_contents_) - return; - web_contents_->SetPageBaseBackgroundColor( - use_transparent_background_ ? absl::make_optional(SK_ColorTRANSPARENT) - : absl::nullopt); -} - -} // namespace weblayer
diff --git a/weblayer/browser/content_view_render_view.h b/weblayer/browser/content_view_render_view.h deleted file mode 100644 index cffc4ba..0000000 --- a/weblayer/browser/content_view_render_view.h +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_CONTENT_VIEW_RENDER_VIEW_H_ -#define WEBLAYER_BROWSER_CONTENT_VIEW_RENDER_VIEW_H_ - -#include <memory> - -#include "base/android/jni_weak_ref.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/android/compositor_client.h" -#include "ui/gfx/native_widget_types.h" - -namespace cc::slim { -class Layer; -} - -namespace content { -class Compositor; -class WebContents; -} // namespace content - -namespace weblayer { - -class ContentViewRenderView : public content::CompositorClient { - public: - ContentViewRenderView(JNIEnv* env, - jobject obj, - gfx::NativeWindow root_window); - - ContentViewRenderView(const ContentViewRenderView&) = delete; - ContentViewRenderView& operator=(const ContentViewRenderView&) = delete; - - content::Compositor* compositor() { return compositor_.get(); } - - scoped_refptr<cc::slim::Layer> root_container_layer() { - return root_container_layer_; - } - - // Content Height, in pixels. - int content_height() const { return content_height_; } - void SetContentHeightChangedListener(base::RepeatingClosure callback); - - // Methods called from Java via JNI ----------------------------------------- - void Destroy(JNIEnv* env); - void SetCurrentWebContents( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& jweb_contents); - void OnPhysicalBackingSizeChanged( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& jweb_contents, - jint width, - jint height, - jboolean for_config_change); - void OnViewportSizeChanged(JNIEnv* env, jint width, jint height); - void SurfaceCreated(JNIEnv* env); - void SurfaceDestroyed(JNIEnv* env, jboolean cache_back_buffer); - void SurfaceChanged(JNIEnv* env, - jboolean can_be_used_with_surface_control, - jint width, - jint height, - jboolean transparent_background, - const base::android::JavaParamRef<jobject>& new_surface); - void SetNeedsRedraw(JNIEnv* env); - void EvictCachedSurface(JNIEnv* env); - base::android::ScopedJavaLocalRef<jobject> GetResourceManager(JNIEnv* env); - void UpdateBackgroundColor(JNIEnv* env); - void SetRequiresAlphaChannel(JNIEnv* env, jboolean requires_alpha_channel); - void SetDidSwapBuffersCallbackEnabled(JNIEnv* env, jboolean enable); - - // CompositorClient implementation - void UpdateLayerTreeHost() override; - void DidSwapFrame(int pending_frames) override; - void DidSwapBuffers(const gfx::Size& swap_size) override; - - private: - ~ContentViewRenderView() override; - - void InitCompositor(); - void UpdateWebContentsBaseBackgroundColor(); - - base::android::ScopedJavaGlobalRef<jobject> java_obj_; - bool use_transparent_background_ = false; - bool requires_alpha_channel_ = false; - raw_ptr<content::WebContents> web_contents_ = nullptr; - - std::unique_ptr<content::Compositor> compositor_; - - gfx::NativeWindow root_window_; - - // Set as the root-layer of the compositor. Contains |web_contents_layer_|. - scoped_refptr<cc::slim::Layer> root_container_layer_; - scoped_refptr<cc::slim::Layer> web_contents_layer_; - - base::RepeatingClosure content_height_changed_listener_; - int content_height_ = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_CONTENT_VIEW_RENDER_VIEW_H_
diff --git a/weblayer/browser/cookie_manager_browsertest.cc b/weblayer/browser/cookie_manager_browsertest.cc deleted file mode 100644 index 8adf01e..0000000 --- a/weblayer/browser/cookie_manager_browsertest.cc +++ /dev/null
@@ -1,175 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/files/file_util.h" -#include "base/test/bind.h" -#include "build/build_config.h" -#include "content/public/browser/browser_context.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/cookie_manager_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/public/cookie_manager.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -class CookieManagerBrowserTest : public WebLayerBrowserTest { - public: - const std::vector<net::CookieChangeInfo>& WaitForChanges(size_t num) { - if (change_infos_.size() >= num) - return change_infos_; - - num_to_wait_for_ = num; - run_loop_ = std::make_unique<base::RunLoop>(); - run_loop_->Run(); - return change_infos_; - } - - void OnCookieChanged(const net::CookieChangeInfo& info) { - change_infos_.push_back(info); - if (run_loop_ && num_to_wait_for_ == change_infos_.size()) - run_loop_->Quit(); - } - - void Reset() { change_infos_.clear(); } - - bool SetCookie(const std::string& cookie) { - GURL base_url = embedded_test_server()->base_url(); - base::RunLoop run_loop; - bool final_result = false; - GetProfile()->GetCookieManager()->SetCookie( - base_url, cookie, - base::BindLambdaForTesting([&run_loop, &final_result](bool result) { - final_result = result; - run_loop.Quit(); - })); - run_loop.Run(); - return final_result; - } - - base::Time GetCookieDbModifiedTime() { - base::FilePath cookie_path = - GetBrowserContext()->GetPath().Append(FILE_PATH_LITERAL("Cookies")); - - base::ScopedAllowBlockingForTesting scoped_allow_blocking; - base::File::Info info; - EXPECT_TRUE(base::GetFileInfo(cookie_path, &info)); - return info.last_modified; - } - - private: - size_t num_to_wait_for_ = 0; - std::vector<net::CookieChangeInfo> change_infos_; - std::unique_ptr<base::RunLoop> run_loop_; -}; - -IN_PROC_BROWSER_TEST_F(CookieManagerBrowserTest, CookieChanged) { - EXPECT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page.html"), shell()); - - GURL base_url = embedded_test_server()->base_url(); - base::CallbackListSubscription subscription = - GetProfile()->GetCookieManager()->AddCookieChangedCallback( - base_url, nullptr, - base::BindRepeating(&CookieManagerBrowserTest::OnCookieChanged, - base::Unretained(this))); - - ASSERT_TRUE(SetCookie("foo=bar")); - const auto& changes = WaitForChanges(1); - ASSERT_EQ(changes.size(), 1u); - const auto& cookie = changes[0].cookie; - EXPECT_EQ(cookie.Name(), "foo"); - EXPECT_EQ(cookie.Value(), "bar"); -} - -IN_PROC_BROWSER_TEST_F(CookieManagerBrowserTest, - CookieChangedRemoveSubscription) { - EXPECT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page.html"), shell()); - - GURL base_url = embedded_test_server()->base_url(); - std::string cookie1 = "cookie1"; - base::CallbackListSubscription subscription1 = - GetProfile()->GetCookieManager()->AddCookieChangedCallback( - base_url, &cookie1, - base::BindRepeating(&CookieManagerBrowserTest::OnCookieChanged, - base::Unretained(this))); - std::string cookie2 = "cookie2"; - base::CallbackListSubscription subscription2 = - GetProfile()->GetCookieManager()->AddCookieChangedCallback( - base_url, &cookie2, - base::BindRepeating(&CookieManagerBrowserTest::OnCookieChanged, - base::Unretained(this))); - - ASSERT_TRUE(SetCookie("cookie1=something")); - { - const auto& changes = WaitForChanges(1); - ASSERT_EQ(changes.size(), 1u); - EXPECT_EQ(changes[0].cookie.Name(), cookie1); - } - - Reset(); - subscription1 = {}; - - // Set cookie1 first and then cookie2. We should only receive a cookie change - // event for cookie2. - ASSERT_TRUE(SetCookie("cookie1=other")); - ASSERT_TRUE(SetCookie("cookie2=something")); - { - const auto& changes = WaitForChanges(1); - ASSERT_EQ(changes.size(), 1u); - EXPECT_EQ(changes[0].cookie.Name(), cookie2); - } -} - -IN_PROC_BROWSER_TEST_F(CookieManagerBrowserTest, - DISABLED_FlushCookiesAfterSet) { - EXPECT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page.html"), shell()); - - base::Time original_modified_time = GetCookieDbModifiedTime(); - - ASSERT_TRUE(SetCookie("a=b; expires=Fri, 01 Jan 2038 00:00:00 GMT")); - EXPECT_EQ(GetCookieDbModifiedTime(), original_modified_time); - - EXPECT_TRUE(static_cast<CookieManagerImpl*>(GetProfile()->GetCookieManager()) - ->FireFlushTimerForTesting()); - EXPECT_GT(GetCookieDbModifiedTime(), original_modified_time); -} - -IN_PROC_BROWSER_TEST_F(CookieManagerBrowserTest, - DISABLED_FlushCookiesAfterSetMultiple) { - EXPECT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page.html"), shell()); - - base::Time original_modified_time = GetCookieDbModifiedTime(); - - ASSERT_TRUE(SetCookie("a=b; expires=Fri, 01 Jan 2038 00:00:00 GMT")); - EXPECT_EQ(GetCookieDbModifiedTime(), original_modified_time); - ASSERT_TRUE(SetCookie("c=d; expires=Fri, 01 Jan 2038 00:00:00 GMT")); - EXPECT_EQ(GetCookieDbModifiedTime(), original_modified_time); - - CookieManagerImpl* cookie_manager = - static_cast<CookieManagerImpl*>(GetProfile()->GetCookieManager()); - EXPECT_TRUE(cookie_manager->FireFlushTimerForTesting()); - EXPECT_GT(GetCookieDbModifiedTime(), original_modified_time); - - // Flush timer should be gone now. - EXPECT_FALSE(cookie_manager->FireFlushTimerForTesting()); - - // Try again to make sure it works a second time. - original_modified_time = GetCookieDbModifiedTime(); - ASSERT_TRUE(SetCookie("d=f; expires=Fri, 01 Jan 2038 00:00:00 GMT")); - EXPECT_EQ(GetCookieDbModifiedTime(), original_modified_time); - - EXPECT_TRUE(cookie_manager->FireFlushTimerForTesting()); - EXPECT_GT(GetCookieDbModifiedTime(), original_modified_time); -} - -} // namespace weblayer
diff --git a/weblayer/browser/cookie_manager_impl.cc b/weblayer/browser/cookie_manager_impl.cc deleted file mode 100644 index 0ce7986..0000000 --- a/weblayer/browser/cookie_manager_impl.cc +++ /dev/null
@@ -1,274 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/cookie_manager_impl.h" - -#include "base/i18n/time_formatting.h" -#include "build/build_config.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/storage_partition.h" -#include "net/cookies/cookie_constants.h" -#include "net/cookies/cookie_util.h" -#include "net/cookies/parsed_cookie.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/callback_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/android/scoped_java_ref.h" -#include "weblayer/browser/java/jni/CookieManagerImpl_jni.h" -#endif - -namespace weblayer { -namespace { -constexpr base::TimeDelta kCookieFlushDelay = base::Seconds(1); - -void GetCookieComplete(CookieManager::GetCookieCallback callback, - const net::CookieAccessResultList& cookies, - const net::CookieAccessResultList& excluded_cookies) { - net::CookieList cookie_list = net::cookie_util::StripAccessResults(cookies); - std::move(callback).Run(net::CanonicalCookie::BuildCookieLine(cookie_list)); -} - -void GetResponseCookiesComplete( - CookieManager::GetResponseCookiesCallback callback, - const net::CookieAccessResultList& cookies, - const net::CookieAccessResultList& excluded_cookies) { - net::CookieList cookie_list = net::cookie_util::StripAccessResults(cookies); - std::vector<std::string> response_cookies; - for (const net::CanonicalCookie& cookie : cookie_list) { - net::ParsedCookie parsed(""); - parsed.SetName(cookie.Name()); - parsed.SetValue(cookie.Value()); - parsed.SetPath(cookie.Path()); - parsed.SetDomain(cookie.Domain()); - if (!cookie.ExpiryDate().is_null()) - parsed.SetExpires(base::TimeFormatHTTP(cookie.ExpiryDate())); - parsed.SetIsSecure(cookie.IsSecure()); - parsed.SetIsHttpOnly(cookie.IsHttpOnly()); - if (cookie.SameSite() != net::CookieSameSite::UNSPECIFIED) - parsed.SetSameSite(net::CookieSameSiteToString(cookie.SameSite())); - parsed.SetPriority(net::CookiePriorityToString(cookie.Priority())); - parsed.SetIsSameParty(cookie.IsSameParty()); - parsed.SetIsPartitioned(cookie.IsPartitioned()); - response_cookies.push_back(parsed.ToCookieLine()); - } - std::move(callback).Run(response_cookies); -} - -#if BUILDFLAG(IS_ANDROID) -void OnCookieChangedAndroid( - base::android::ScopedJavaGlobalRef<jobject> callback, - const net::CookieChangeInfo& change) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_CookieManagerImpl_onCookieChange( - env, callback, - base::android::ConvertUTF8ToJavaString( - env, net::CanonicalCookie::BuildCookieLine({change.cookie})), - static_cast<int>(change.cause)); -} - -void RunGetResponseCookiesCallback( - const base::android::JavaRef<jobject>& callback, - const std::vector<std::string>& cookies) { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::RunObjectCallbackAndroid( - callback, base::android::ToJavaArrayOfStrings(env, cookies)); -} -#endif - -void OnCookieChanged(CookieManager::CookieChangedCallbackList* callback_list, - const net::CookieChangeInfo& change) { - callback_list->Notify(change); -} - -class CookieChangeListenerImpl : public network::mojom::CookieChangeListener { - public: - explicit CookieChangeListenerImpl( - CookieManager::CookieChangedCallback callback) - : callback_(std::move(callback)) {} - - // mojom::CookieChangeListener - void OnCookieChange(const net::CookieChangeInfo& change) override { - callback_.Run(change); - } - - private: - CookieManager::CookieChangedCallback callback_; -}; - -} // namespace - -CookieManagerImpl::CookieManagerImpl(content::BrowserContext* browser_context) - : browser_context_(browser_context) {} - -CookieManagerImpl::~CookieManagerImpl() = default; - -void CookieManagerImpl::SetCookie(const GURL& url, - const std::string& value, - SetCookieCallback callback) { - SetCookieInternal(url, value, std::move(callback)); -} - -void CookieManagerImpl::GetCookie(const GURL& url, GetCookieCallback callback) { - browser_context_->GetDefaultStoragePartition() - ->GetCookieManagerForBrowserProcess() - ->GetCookieList(url, net::CookieOptions::MakeAllInclusive(), - net::CookiePartitionKeyCollection::Todo(), - base::BindOnce(&GetCookieComplete, std::move(callback))); -} - -void CookieManagerImpl::GetResponseCookies( - const GURL& url, - GetResponseCookiesCallback callback) { - browser_context_->GetDefaultStoragePartition() - ->GetCookieManagerForBrowserProcess() - ->GetCookieList( - url, net::CookieOptions::MakeAllInclusive(), - net::CookiePartitionKeyCollection::Todo(), - base::BindOnce(&GetResponseCookiesComplete, std::move(callback))); -} - -base::CallbackListSubscription CookieManagerImpl::AddCookieChangedCallback( - const GURL& url, - const std::string* name, - CookieChangedCallback callback) { - auto callback_list = std::make_unique<CookieChangedCallbackList>(); - auto* callback_list_ptr = callback_list.get(); - int id = AddCookieChangedCallbackInternal( - url, name, - base::BindRepeating(&OnCookieChanged, - base::Owned(std::move(callback_list)))); - callback_list_ptr->set_removal_callback(base::BindRepeating( - &CookieManagerImpl::RemoveCookieChangedCallbackInternal, - weak_factory_.GetWeakPtr(), id)); - return callback_list_ptr->Add(std::move(callback)); -} - -#if BUILDFLAG(IS_ANDROID) -void CookieManagerImpl::SetCookie( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jstring>& value, - const base::android::JavaParamRef<jobject>& callback) { - SetCookieInternal( - GURL(ConvertJavaStringToUTF8(url)), ConvertJavaStringToUTF8(value), - base::BindOnce(&base::android::RunBooleanCallbackAndroid, - base::android::ScopedJavaGlobalRef<jobject>(callback))); -} - -void CookieManagerImpl::GetCookie( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jobject>& callback) { - GetCookie( - GURL(ConvertJavaStringToUTF8(url)), - base::BindOnce(&base::android::RunStringCallbackAndroid, - base::android::ScopedJavaGlobalRef<jobject>(callback))); -} - -void CookieManagerImpl::GetResponseCookies( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jobject>& callback) { - GetResponseCookies( - GURL(ConvertJavaStringToUTF8(url)), - base::BindOnce(&RunGetResponseCookiesCallback, - base::android::ScopedJavaGlobalRef<jobject>(callback))); -} - -int CookieManagerImpl::AddCookieChangedCallback( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jstring>& name, - const base::android::JavaParamRef<jobject>& callback) { - std::string name_str; - if (name) - name_str = ConvertJavaStringToUTF8(name); - return AddCookieChangedCallbackInternal( - GURL(ConvertJavaStringToUTF8(url)), name ? &name_str : nullptr, - base::BindRepeating( - &OnCookieChangedAndroid, - base::android::ScopedJavaGlobalRef<jobject>(callback))); -} - -void CookieManagerImpl::RemoveCookieChangedCallback(JNIEnv* env, int id) { - RemoveCookieChangedCallbackInternal(id); -} -#endif - -bool CookieManagerImpl::FireFlushTimerForTesting() { - if (!flush_timer_) - return false; - - flush_run_loop_for_testing_ = std::make_unique<base::RunLoop>(); - flush_timer_->FireNow(); - flush_run_loop_for_testing_->Run(); - flush_run_loop_for_testing_ = nullptr; - return true; -} - -void CookieManagerImpl::SetCookieInternal(const GURL& url, - const std::string& value, - SetCookieCallback callback) { - auto cc = net::CanonicalCookie::Create(url, value, base::Time::Now(), - absl::nullopt, absl::nullopt); - if (!cc) { - std::move(callback).Run(false); - return; - } - - browser_context_->GetDefaultStoragePartition() - ->GetCookieManagerForBrowserProcess() - ->SetCanonicalCookie( - *cc, url, net::CookieOptions::MakeAllInclusive(), - base::BindOnce(net::cookie_util::IsCookieAccessResultInclude) - .Then(base::BindOnce(&CookieManagerImpl::OnCookieSet, - weak_factory_.GetWeakPtr(), - std::move(callback)))); -} - -int CookieManagerImpl::AddCookieChangedCallbackInternal( - const GURL& url, - const std::string* name, - CookieChangedCallback callback) { - mojo::PendingRemote<network::mojom::CookieChangeListener> listener_remote; - auto receiver = listener_remote.InitWithNewPipeAndPassReceiver(); - browser_context_->GetDefaultStoragePartition() - ->GetCookieManagerForBrowserProcess() - ->AddCookieChangeListener( - url, name ? absl::make_optional(*name) : absl::nullopt, - std::move(listener_remote)); - - auto listener = - std::make_unique<CookieChangeListenerImpl>(std::move(callback)); - auto* listener_ptr = listener.get(); - return cookie_change_receivers_.Add(listener_ptr, std::move(receiver), - std::move(listener)); -} - -void CookieManagerImpl::RemoveCookieChangedCallbackInternal(int id) { - cookie_change_receivers_.Remove(id); -} - -void CookieManagerImpl::OnCookieSet(SetCookieCallback callback, bool success) { - std::move(callback).Run(success); - if (!flush_timer_) { - flush_timer_ = std::make_unique<base::OneShotTimer>(); - flush_timer_->Start(FROM_HERE, kCookieFlushDelay, - base::BindOnce(&CookieManagerImpl::OnFlushTimerFired, - weak_factory_.GetWeakPtr())); - } -} - -void CookieManagerImpl::OnFlushTimerFired() { - browser_context_->GetDefaultStoragePartition() - ->GetCookieManagerForBrowserProcess() - ->FlushCookieStore(flush_run_loop_for_testing_ - ? flush_run_loop_for_testing_->QuitClosure() - : base::DoNothing()); - flush_timer_ = nullptr; -} - -} // namespace weblayer
diff --git a/weblayer/browser/cookie_manager_impl.h b/weblayer/browser/cookie_manager_impl.h deleted file mode 100644 index 2ca1686..0000000 --- a/weblayer/browser/cookie_manager_impl.h +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_COOKIE_MANAGER_IMPL_H_ -#define WEBLAYER_BROWSER_COOKIE_MANAGER_IMPL_H_ - -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/run_loop.h" -#include "build/build_config.h" -#include "mojo/public/cpp/bindings/receiver_set.h" -#include "services/network/public/mojom/cookie_manager.mojom.h" -#include "weblayer/public/cookie_manager.h" - -#if BUILDFLAG(IS_ANDROID) -#include <jni.h> -#include "base/android/scoped_java_ref.h" -#endif - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -class CookieManagerImpl : public CookieManager { - public: - explicit CookieManagerImpl(content::BrowserContext* browser_context); - ~CookieManagerImpl() override; - - CookieManagerImpl(const CookieManagerImpl&) = delete; - CookieManagerImpl& operator=(const CookieManagerImpl&) = delete; - - // CookieManager implementation: - void SetCookie(const GURL& url, - const std::string& value, - SetCookieCallback callback) override; - void GetCookie(const GURL& url, GetCookieCallback callback) override; - void GetResponseCookies(const GURL& url, - GetResponseCookiesCallback callback) override; - base::CallbackListSubscription AddCookieChangedCallback( - const GURL& url, - const std::string* name, - CookieChangedCallback callback) override; - -#if BUILDFLAG(IS_ANDROID) - void SetCookie(JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jstring>& value, - const base::android::JavaParamRef<jobject>& callback); - void GetCookie(JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jobject>& callback); - void GetResponseCookies(JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jobject>& callback); - int AddCookieChangedCallback( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - const base::android::JavaParamRef<jstring>& name, - const base::android::JavaParamRef<jobject>& callback); - void RemoveCookieChangedCallback(JNIEnv* env, int id); -#endif - - // Fires the cookie flush timer immediately and waits for the flush to - // complete. Returns true if the flush timer was running. - bool FireFlushTimerForTesting(); - - private: - void SetCookieInternal(const GURL& url, - const std::string& value, - SetCookieCallback callback); - int AddCookieChangedCallbackInternal(const GURL& url, - const std::string* name, - CookieChangedCallback callback); - void RemoveCookieChangedCallbackInternal(int id); - void OnCookieSet(SetCookieCallback callback, bool success); - void OnFlushTimerFired(); - - raw_ptr<content::BrowserContext> browser_context_; - mojo::ReceiverSet<network::mojom::CookieChangeListener, - std::unique_ptr<network::mojom::CookieChangeListener>> - cookie_change_receivers_; - - std::unique_ptr<base::OneShotTimer> flush_timer_; - std::unique_ptr<base::RunLoop> flush_run_loop_for_testing_; - - base::WeakPtrFactory<CookieManagerImpl> weak_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_COOKIE_MANAGER_IMPL_H_
diff --git a/weblayer/browser/cookie_settings_factory.cc b/weblayer/browser/cookie_settings_factory.cc deleted file mode 100644 index d77cabb..0000000 --- a/weblayer/browser/cookie_settings_factory.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/cookie_settings_factory.h" - -#include "base/no_destructor.h" -#include "components/content_settings/core/browser/cookie_settings.h" -#include "components/content_settings/core/common/pref_names.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/pref_registry/pref_registry_syncable.h" -#include "components/prefs/pref_service.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -scoped_refptr<content_settings::CookieSettings> -CookieSettingsFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<content_settings::CookieSettings*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true).get()); -} - -// static -CookieSettingsFactory* CookieSettingsFactory::GetInstance() { - static base::NoDestructor<CookieSettingsFactory> factory; - return factory.get(); -} - -CookieSettingsFactory::CookieSettingsFactory() - : RefcountedBrowserContextKeyedServiceFactory( - "CookieSettings", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -CookieSettingsFactory::~CookieSettingsFactory() = default; - -void CookieSettingsFactory::RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) { - content_settings::CookieSettings::RegisterProfilePrefs(registry); -} - -content::BrowserContext* CookieSettingsFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -scoped_refptr<RefcountedKeyedService> -CookieSettingsFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return new content_settings::CookieSettings( - HostContentSettingsMapFactory::GetForBrowserContext(context), - static_cast<BrowserContextImpl*>(context)->pref_service(), - context->IsOffTheRecord()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/cookie_settings_factory.h b/weblayer/browser/cookie_settings_factory.h deleted file mode 100644 index a5e3dc6..0000000 --- a/weblayer/browser/cookie_settings_factory.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_COOKIE_SETTINGS_FACTORY_H_ -#define WEBLAYER_BROWSER_COOKIE_SETTINGS_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h" - -namespace content_settings { -class CookieSettings; -} - -namespace weblayer { - -class CookieSettingsFactory - : public RefcountedBrowserContextKeyedServiceFactory { - public: - CookieSettingsFactory(const CookieSettingsFactory&) = delete; - CookieSettingsFactory& operator=(const CookieSettingsFactory&) = delete; - - static scoped_refptr<content_settings::CookieSettings> GetForBrowserContext( - content::BrowserContext* browser_context); - static CookieSettingsFactory* GetInstance(); - - private: - friend class base::NoDestructor<CookieSettingsFactory>; - - CookieSettingsFactory(); - ~CookieSettingsFactory() override; - - // BrowserContextKeyedServiceFactory methods: - void RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_COOKIE_SETTINGS_FACTORY_H_
diff --git a/weblayer/browser/devtools_manager_delegate_android.cc b/weblayer/browser/devtools_manager_delegate_android.cc deleted file mode 100644 index 68d1faa..0000000 --- a/weblayer/browser/devtools_manager_delegate_android.cc +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/devtools_manager_delegate_android.h" - -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" - -namespace weblayer { - -DevToolsManagerDelegateAndroid::DevToolsManagerDelegateAndroid() = default; - -DevToolsManagerDelegateAndroid::~DevToolsManagerDelegateAndroid() = default; - -content::BrowserContext* -DevToolsManagerDelegateAndroid::GetDefaultBrowserContext() { - auto profiles = ProfileImpl::GetAllProfiles(); - if (profiles.empty()) - return nullptr; - - // This is called when granting permissions via devtools in browser tests or WPT. We assume that - // there is only a single profile and just pick the first one here. Note that outside of tests - // there might exist multiple profiles for WebLayer and this assumption won't hold. - ProfileImpl* profile = *profiles.begin(); - return profile->GetBrowserContext(); -} - -std::string DevToolsManagerDelegateAndroid::GetDiscoveryPageHTML() { - const char html[] = - "<html>" - "<head><title>WebLayer remote debugging</title></head>" - "<body>Please use <a href=\'chrome://inspect\'>chrome://inspect</a>" - "</body>" - "</html>"; - return html; -} - -bool DevToolsManagerDelegateAndroid::IsBrowserTargetDiscoverable() { - return true; -} - -} // namespace weblayer
diff --git a/weblayer/browser/devtools_manager_delegate_android.h b/weblayer/browser/devtools_manager_delegate_android.h deleted file mode 100644 index 9b9e9d65..0000000 --- a/weblayer/browser/devtools_manager_delegate_android.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_DEVTOOLS_MANAGER_DELEGATE_ANDROID_H_ -#define WEBLAYER_BROWSER_DEVTOOLS_MANAGER_DELEGATE_ANDROID_H_ - -#include "content/public/browser/devtools_manager_delegate.h" - -namespace weblayer { - -class DevToolsManagerDelegateAndroid : public content::DevToolsManagerDelegate { - public: - DevToolsManagerDelegateAndroid(); - - DevToolsManagerDelegateAndroid(const DevToolsManagerDelegateAndroid&) = - delete; - DevToolsManagerDelegateAndroid& operator=( - const DevToolsManagerDelegateAndroid&) = delete; - - ~DevToolsManagerDelegateAndroid() override; - - // content::DevToolsManagerDelegate implementation. - content::BrowserContext* GetDefaultBrowserContext() override; - std::string GetDiscoveryPageHTML() override; - bool IsBrowserTargetDiscoverable() override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_DEVTOOLS_MANAGER_DELEGATE_ANDROID_H_
diff --git a/weblayer/browser/devtools_server_android.cc b/weblayer/browser/devtools_server_android.cc deleted file mode 100644 index e7ed1ff6..0000000 --- a/weblayer/browser/devtools_server_android.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/devtools_server_android.h" - -#include "base/command_line.h" -#include "base/strings/stringprintf.h" -#include "content/public/browser/android/devtools_auth.h" -#include "content/public/browser/devtools_manager_delegate.h" -#include "content/public/browser/devtools_socket_factory.h" -#include "content/public/common/content_switches.h" -#include "net/base/net_errors.h" -#include "net/socket/unix_domain_server_socket_posix.h" - -namespace weblayer { -namespace { -bool g_remote_debugging_enabled = false; - -const int kBackLog = 10; - -const char kSocketNameFormat[] = "weblayer_devtools_remote_%d"; -const char kTetheringSocketName[] = "weblayer_devtools_tethering_%d_%d"; - -class UnixDomainServerSocketFactory : public content::DevToolsSocketFactory { - public: - explicit UnixDomainServerSocketFactory(const std::string& socket_name) - : socket_name_(socket_name) {} - - UnixDomainServerSocketFactory(const UnixDomainServerSocketFactory&) = delete; - UnixDomainServerSocketFactory& operator=( - const UnixDomainServerSocketFactory&) = delete; - - private: - // content::DevToolsAgentHost::ServerSocketFactory. - std::unique_ptr<net::ServerSocket> CreateForHttpServer() override { - auto socket = std::make_unique<net::UnixDomainServerSocket>( - base::BindRepeating(&content::CanUserConnectToDevTools), - true /* use_abstract_namespace */); - if (socket->BindAndListen(socket_name_, kBackLog) != net::OK) - return nullptr; - - return std::move(socket); - } - - std::unique_ptr<net::ServerSocket> CreateForTethering( - std::string* name) override { - *name = base::StringPrintf(kTetheringSocketName, getpid(), - ++last_tethering_socket_); - auto socket = std::make_unique<net::UnixDomainServerSocket>( - base::BindRepeating(&content::CanUserConnectToDevTools), - true /* use_abstract_namespace */); - if (socket->BindAndListen(*name, kBackLog) != net::OK) - return nullptr; - - return std::move(socket); - } - - std::string socket_name_; - int last_tethering_socket_ = 0; -}; - -} // namespace - -// static -void DevToolsServerAndroid::SetRemoteDebuggingEnabled(bool enabled) { - if (g_remote_debugging_enabled == enabled) - return; - - g_remote_debugging_enabled = enabled; - if (enabled) { - auto factory = std::make_unique<UnixDomainServerSocketFactory>( - base::StringPrintf(kSocketNameFormat, getpid())); - content::DevToolsAgentHost::StartRemoteDebuggingServer( - std::move(factory), base::FilePath(), base::FilePath()); - } else { - content::DevToolsAgentHost::StopRemoteDebuggingServer(); - } -} - -// static -bool DevToolsServerAndroid::GetRemoteDebuggingEnabled() { - return g_remote_debugging_enabled; -} - -} // namespace weblayer
diff --git a/weblayer/browser/devtools_server_android.h b/weblayer/browser/devtools_server_android.h deleted file mode 100644 index 86ee4d81..0000000 --- a/weblayer/browser/devtools_server_android.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_DEVTOOLS_SERVER_ANDROID_H_ -#define WEBLAYER_BROWSER_DEVTOOLS_SERVER_ANDROID_H_ - -namespace weblayer { - -class DevToolsServerAndroid { - public: - static void SetRemoteDebuggingEnabled(bool enabled); - - static bool GetRemoteDebuggingEnabled(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_DEVTOOLS_SERVER_ANDROID_H_
diff --git a/weblayer/browser/download_browsertest.cc b/weblayer/browser/download_browsertest.cc deleted file mode 100644 index 669eaf26..0000000 --- a/weblayer/browser/download_browsertest.cc +++ /dev/null
@@ -1,352 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/task/sequenced_task_runner.h" -#include "base/test/bind.h" -#include "base/threading/thread_restrictions.h" -#include "build/build_config.h" -#include "content/public/browser/download_manager.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/slow_download_http_response.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/download_manager_delegate_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/download.h" -#include "weblayer/public/download_delegate.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -class DownloadBrowserTest : public WebLayerBrowserTest, - public DownloadDelegate { - public: - DownloadBrowserTest() = default; - ~DownloadBrowserTest() override = default; - - void SetUpOnMainThread() override { - embedded_test_server()->RegisterRequestHandler(base::BindRepeating( - &content::SlowDownloadHttpResponse::HandleSlowDownloadRequest)); - ASSERT_TRUE(embedded_test_server()->Start()); - - allow_run_loop_ = std::make_unique<base::RunLoop>(); - started_run_loop_ = std::make_unique<base::RunLoop>(); - intercept_run_loop_ = std::make_unique<base::RunLoop>(); - completed_run_loop_ = std::make_unique<base::RunLoop>(); - failed_run_loop_ = std::make_unique<base::RunLoop>(); - - Tab* tab = shell()->tab(); - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - - tab_impl->profile()->SetDownloadDelegate(this); - - auto* browser_context = tab_impl->web_contents()->GetBrowserContext(); - auto* download_manager_delegate = - browser_context->GetDownloadManager()->GetDelegate(); - static_cast<DownloadManagerDelegateImpl*>(download_manager_delegate) - ->set_download_dropped_closure_for_testing(base::BindRepeating( - &DownloadBrowserTest::DownloadDropped, base::Unretained(this))); - } - - void WaitForAllow() { allow_run_loop_->Run(); } - void WaitForIntercept() { intercept_run_loop_->Run(); } - void WaitForStarted() { started_run_loop_->Run(); } - void WaitForCompleted() { completed_run_loop_->Run(); } - void WaitForFailed() { failed_run_loop_->Run(); } - - void set_intercept() { intercept_ = true; } - void set_disallow() { allow_ = false; } - void set_started_callback( - base::OnceCallback<void(Download* download)> callback) { - started_callback_ = std::move(callback); - } - void set_failed_callback( - base::OnceCallback<void(Download* download)> callback) { - failed_callback_ = std::move(callback); - } - bool started() { return started_; } - base::FilePath download_location() { return download_location_; } - int64_t total_bytes() { return total_bytes_; } - DownloadError download_state() { return download_state_; } - std::string mime_type() { return mime_type_; } - int completed_count() { return completed_count_; } - int failed_count() { return failed_count_; } - int download_dropped_count() { return download_dropped_count_; } - - private: - // DownloadDelegate implementation: - void AllowDownload(Tab* tab, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - AllowDownloadCallback callback) override { - std::move(callback).Run(allow_); - allow_run_loop_->Quit(); - } - - bool InterceptDownload(const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - int64_t content_length) override { - intercept_run_loop_->Quit(); - return intercept_; - } - - void DownloadStarted(Download* download) override { - started_ = true; - started_run_loop_->Quit(); - - CHECK_EQ(download->GetState(), DownloadState::kInProgress); - - if (started_callback_) - std::move(started_callback_).Run(download); - } - - void DownloadCompleted(Download* download) override { - completed_count_++; - download_location_ = download->GetLocation(); - total_bytes_ = download->GetTotalBytes(); - download_state_ = download->GetError(); - mime_type_ = download->GetMimeType(); - CHECK_EQ(download->GetReceivedBytes(), total_bytes_); - CHECK_EQ(download->GetState(), DownloadState::kComplete); - completed_run_loop_->Quit(); - } - - void DownloadFailed(Download* download) override { - failed_count_++; - download_state_ = download->GetError(); - failed_run_loop_->Quit(); - - if (failed_callback_) - std::move(failed_callback_).Run(download); - } - - void DownloadDropped() { download_dropped_count_++; } - - bool intercept_ = false; - bool allow_ = true; - bool started_ = false; - base::OnceCallback<void(Download* download)> started_callback_; - base::OnceCallback<void(Download* download)> failed_callback_; - base::FilePath download_location_; - int64_t total_bytes_ = 0; - DownloadError download_state_ = DownloadError::kNoError; - std::string mime_type_; - int completed_count_ = 0; - int failed_count_ = 0; - int download_dropped_count_ = 0; - std::unique_ptr<base::RunLoop> allow_run_loop_; - std::unique_ptr<base::RunLoop> intercept_run_loop_; - std::unique_ptr<base::RunLoop> started_run_loop_; - std::unique_ptr<base::RunLoop> completed_run_loop_; - std::unique_ptr<base::RunLoop> failed_run_loop_; -}; - -} // namespace - -// Ensures that if the delegate disallows the downloads then WebLayer -// doesn't download it. -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, DisallowNoDownload) { - set_disallow(); - - GURL url(embedded_test_server()->GetURL("/content-disposition.html")); - - // Downloads always count as failed navigations. - TestNavigationObserver observer( - url, TestNavigationObserver::NavigationEvent::kFailure, shell()); - shell()->tab()->GetNavigationController()->Navigate(url); - observer.Wait(); - - WaitForAllow(); - - EXPECT_FALSE(started()); - EXPECT_EQ(completed_count(), 0); - EXPECT_EQ(failed_count(), 0); - EXPECT_EQ(download_dropped_count(), 1); -} - -// Ensures that if the delegate chooses to intercept downloads then WebLayer -// doesn't download it. -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, InterceptNoDownload) { - set_intercept(); - - GURL url(embedded_test_server()->GetURL("/content-disposition.html")); - - shell()->tab()->GetNavigationController()->Navigate(url); - - WaitForIntercept(); - - EXPECT_FALSE(started()); - EXPECT_EQ(completed_count(), 0); - EXPECT_EQ(failed_count(), 0); - EXPECT_EQ(download_dropped_count(), 1); -} - -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, Basic) { - GURL url(embedded_test_server()->GetURL("/content-disposition.html")); - - shell()->tab()->GetNavigationController()->Navigate(url); - - WaitForCompleted(); - - EXPECT_TRUE(started()); - EXPECT_EQ(completed_count(), 1); - EXPECT_EQ(failed_count(), 0); - EXPECT_EQ(download_dropped_count(), 0); - EXPECT_EQ(download_state(), DownloadError::kNoError); - EXPECT_EQ(mime_type(), "text/html"); - - // Check that the size on disk matches what's expected. - { - base::ScopedAllowBlockingForTesting allow_blocking; - int64_t downloaded_file_size, original_file_size; - EXPECT_TRUE(base::GetFileSize(download_location(), &downloaded_file_size)); - base::FilePath test_data_dir; - CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); - EXPECT_TRUE(base::GetFileSize( - test_data_dir.Append(base::FilePath( - FILE_PATH_LITERAL("weblayer/test/data/content-disposition.html"))), - &original_file_size)); - EXPECT_EQ(downloaded_file_size, total_bytes()); - } - - // Ensure browser tests don't write to the default machine download directory - // to avoid filing it up. - EXPECT_NE(BrowserContextImpl::GetDefaultDownloadDirectory(), - download_location().DirName()); -} - -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, OverrideDownloadDirectory) { - base::ScopedAllowBlockingForTesting allow_blocking; - base::ScopedTempDir download_dir; - ASSERT_TRUE(download_dir.CreateUniqueTempDir()); - - TabImpl* tab_impl = static_cast<TabImpl*>(shell()->tab()); - auto* browser_context = tab_impl->web_contents()->GetBrowserContext(); - auto* browser_context_impl = - static_cast<BrowserContextImpl*>(browser_context); - browser_context_impl->profile_impl()->SetDownloadDirectory( - download_dir.GetPath()); - - GURL url(embedded_test_server()->GetURL("/content-disposition.html")); - - shell()->tab()->GetNavigationController()->Navigate(url); - - WaitForCompleted(); - - EXPECT_EQ(completed_count(), 1); - EXPECT_EQ(failed_count(), 0); - EXPECT_EQ(download_dir.GetPath(), download_location().DirName()); -} - -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, Cancel) { - set_started_callback(base::BindLambdaForTesting([&](Download* download) { - download->Cancel(); - - // Also allow the download to complete. - GURL url = embedded_test_server()->GetURL( - content::SlowDownloadHttpResponse::kFinishSlowResponseUrl); - shell()->tab()->GetNavigationController()->Navigate(url); - })); - - set_failed_callback(base::BindLambdaForTesting([](Download* download) { - CHECK_EQ(download->GetState(), DownloadState::kCancelled); - })); - - // Create a request that doesn't complete right away to avoid flakiness. - GURL url(embedded_test_server()->GetURL( - content::SlowDownloadHttpResponse::kKnownSizeUrl)); - - shell()->tab()->GetNavigationController()->Navigate(url); - - WaitForFailed(); - EXPECT_EQ(completed_count(), 0); - EXPECT_EQ(failed_count(), 1); - EXPECT_EQ(download_dropped_count(), 0); - EXPECT_EQ(download_state(), DownloadError::kCancelled); -} - -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, PauseResume) { - // Add an initial navigation to avoid the tab being deleted if the first - // navigation is a download, since we use the tab for convenience in the - // lambda. - OneShotNavigationObserver observer(shell()); - shell()->tab()->GetNavigationController()->Navigate(GURL("about:blank")); - observer.WaitForNavigation(); - - set_started_callback(base::BindLambdaForTesting([&](Download* download) { - download->Pause(); - GURL url = embedded_test_server()->GetURL( - content::SlowDownloadHttpResponse::kFinishSlowResponseUrl); - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce( - [](Download* download, Shell* shell, const GURL& url) { - CHECK_EQ(download->GetState(), DownloadState::kPaused); - download->Resume(); - - // Also allow the download to complete. - shell->tab()->GetNavigationController()->Navigate(url); - }, - download, shell(), url)); - })); - - // Create a request that doesn't complete right away to avoid flakiness. - GURL url(embedded_test_server()->GetURL( - content::SlowDownloadHttpResponse::kKnownSizeUrl)); - shell()->tab()->GetNavigationController()->Navigate(url); - - WaitForCompleted(); - EXPECT_EQ(completed_count(), 1); - EXPECT_EQ(failed_count(), 0); - EXPECT_EQ(download_dropped_count(), 0); -} - -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, NetworkError) { - set_failed_callback(base::BindLambdaForTesting([](Download* download) { - CHECK_EQ(download->GetState(), DownloadState::kFailed); - })); - - // Create a request that doesn't complete right away. - GURL url(embedded_test_server()->GetURL( - content::SlowDownloadHttpResponse::kKnownSizeUrl)); - - shell()->tab()->GetNavigationController()->Navigate(url); - - WaitForStarted(); - EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); - - WaitForFailed(); - EXPECT_EQ(completed_count(), 0); - EXPECT_EQ(failed_count(), 1); - EXPECT_EQ(download_dropped_count(), 0); - EXPECT_EQ(download_state(), DownloadError::kConnectivityError); -} - -IN_PROC_BROWSER_TEST_F(DownloadBrowserTest, PendingOnExist) { - // Create a request that doesn't complete right away. - GURL url(embedded_test_server()->GetURL( - content::SlowDownloadHttpResponse::kKnownSizeUrl)); - - shell()->tab()->GetNavigationController()->Navigate(url); - - WaitForStarted(); - - // If this test crashes later then there'd be a regression. -} - -} // namespace weblayer
diff --git a/weblayer/browser/download_callback_proxy.cc b/weblayer/browser/download_callback_proxy.cc deleted file mode 100644 index 1570c18..0000000 --- a/weblayer/browser/download_callback_proxy.cc +++ /dev/null
@@ -1,128 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/download_callback_proxy.h" - -#include "base/android/jni_string.h" -#include "base/trace_event/trace_event.h" -#include "url/android/gurl_android.h" -#include "url/gurl.h" -#include "weblayer/browser/download_impl.h" -#include "weblayer/browser/java/jni/DownloadCallbackProxy_jni.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertUTF8ToJavaString; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -DownloadCallbackProxy::DownloadCallbackProxy(JNIEnv* env, - jobject obj, - Profile* profile) - : profile_(profile), java_delegate_(env, obj) { - profile_->SetDownloadDelegate(this); -} - -DownloadCallbackProxy::~DownloadCallbackProxy() { - profile_->SetDownloadDelegate(nullptr); -} - -bool DownloadCallbackProxy::InterceptDownload( - const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - int64_t content_length) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> jstring_url( - ConvertUTF8ToJavaString(env, url.spec())); - ScopedJavaLocalRef<jstring> jstring_user_agent( - ConvertUTF8ToJavaString(env, user_agent)); - ScopedJavaLocalRef<jstring> jstring_content_disposition( - ConvertUTF8ToJavaString(env, content_disposition)); - ScopedJavaLocalRef<jstring> jstring_mime_type( - ConvertUTF8ToJavaString(env, mime_type)); - TRACE_EVENT0("weblayer", "Java_DownloadCallbackProxy_interceptDownload"); - return Java_DownloadCallbackProxy_interceptDownload( - env, java_delegate_, jstring_url, jstring_user_agent, - jstring_content_disposition, jstring_mime_type, content_length); -} - -void DownloadCallbackProxy::AllowDownload( - Tab* tab, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - AllowDownloadCallback callback) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> jstring_url( - ConvertUTF8ToJavaString(env, url.spec())); - ScopedJavaLocalRef<jstring> jstring_method( - ConvertUTF8ToJavaString(env, request_method)); - ScopedJavaLocalRef<jstring> jstring_request_initator; - if (request_initiator) - jstring_request_initator = - ConvertUTF8ToJavaString(env, request_initiator->Serialize()); - // Make copy on the heap so we can pass the pointer through JNI. This will be - // deleted when it's run. - intptr_t callback_id = reinterpret_cast<intptr_t>( - new AllowDownloadCallback(std::move(callback))); - Java_DownloadCallbackProxy_allowDownload( - env, java_delegate_, static_cast<TabImpl*>(tab)->GetJavaTab(), - jstring_url, jstring_method, jstring_request_initator, callback_id); -} - -void DownloadCallbackProxy::DownloadStarted(Download* download) { - DownloadImpl* download_impl = static_cast<DownloadImpl*>(download); - JNIEnv* env = AttachCurrentThread(); - Java_DownloadCallbackProxy_createDownload( - env, java_delegate_, reinterpret_cast<jlong>(download_impl), - download_impl->GetNotificationId(), download_impl->IsTransient(), - url::GURLAndroid::FromNativeGURL(env, download_impl->GetSourceUrl())); - Java_DownloadCallbackProxy_downloadStarted(env, java_delegate_, - download_impl->java_download()); -} - -void DownloadCallbackProxy::DownloadProgressChanged(Download* download) { - DownloadImpl* download_impl = static_cast<DownloadImpl*>(download); - Java_DownloadCallbackProxy_downloadProgressChanged( - AttachCurrentThread(), java_delegate_, download_impl->java_download()); -} - -void DownloadCallbackProxy::DownloadCompleted(Download* download) { - DownloadImpl* download_impl = static_cast<DownloadImpl*>(download); - Java_DownloadCallbackProxy_downloadCompleted( - AttachCurrentThread(), java_delegate_, download_impl->java_download()); -} - -void DownloadCallbackProxy::DownloadFailed(Download* download) { - DownloadImpl* download_impl = static_cast<DownloadImpl*>(download); - Java_DownloadCallbackProxy_downloadFailed( - AttachCurrentThread(), java_delegate_, download_impl->java_download()); -} - -static jlong JNI_DownloadCallbackProxy_CreateDownloadCallbackProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong profile) { - return reinterpret_cast<jlong>(new DownloadCallbackProxy( - env, proxy, reinterpret_cast<ProfileImpl*>(profile))); -} - -static void JNI_DownloadCallbackProxy_DeleteDownloadCallbackProxy(JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<DownloadCallbackProxy*>(proxy); -} - -static void JNI_DownloadCallbackProxy_AllowDownload(JNIEnv* env, - jlong callback_id, - jboolean allow) { - std::unique_ptr<AllowDownloadCallback> cb( - reinterpret_cast<AllowDownloadCallback*>(callback_id)); - std::move(*cb).Run(allow); -} - -} // namespace weblayer
diff --git a/weblayer/browser/download_callback_proxy.h b/weblayer/browser/download_callback_proxy.h deleted file mode 100644 index 28ff839..0000000 --- a/weblayer/browser/download_callback_proxy.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_DOWNLOAD_CALLBACK_PROXY_H_ -#define WEBLAYER_BROWSER_DOWNLOAD_CALLBACK_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "weblayer/public/download_delegate.h" - -namespace weblayer { - -class Profile; - -// Forwards DownloadDelegate calls to the java-side DownloadCallbackProxy. -class DownloadCallbackProxy : public DownloadDelegate { - public: - DownloadCallbackProxy(JNIEnv* env, jobject obj, Profile* profile); - - DownloadCallbackProxy(const DownloadCallbackProxy&) = delete; - DownloadCallbackProxy& operator=(const DownloadCallbackProxy&) = delete; - - ~DownloadCallbackProxy() override; - - // DownloadDelegate: - bool InterceptDownload(const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - int64_t content_length) override; - void AllowDownload(Tab* tab, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - AllowDownloadCallback callback) override; - void DownloadStarted(Download* download) override; - void DownloadProgressChanged(Download* download) override; - void DownloadCompleted(Download* download) override; - void DownloadFailed(Download* download) override; - - private: - raw_ptr<Profile> profile_; - base::android::ScopedJavaGlobalRef<jobject> java_delegate_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_DOWNLOAD_CALLBACK_PROXY_H_
diff --git a/weblayer/browser/download_impl.cc b/weblayer/browser/download_impl.cc deleted file mode 100644 index ff388a1..0000000 --- a/weblayer/browser/download_impl.cc +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/download_impl.h" - -#include "base/files/file_path.h" -#include "base/functional/bind.h" -#include "base/memory/ptr_util.h" -#include "build/build_config.h" -#include "components/download/public/common/download_item.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/jni_string.h" -#include "ui/gfx/android/java_bitmap.h" -#include "weblayer/browser/java/jni/DownloadImpl_jni.h" -#endif - -namespace weblayer { - -DownloadImpl::~DownloadImpl() { -#if BUILDFLAG(IS_ANDROID) - if (java_download_) { - Java_DownloadImpl_onNativeDestroyed(base::android::AttachCurrentThread(), - java_download_); - } -#endif -} - -#if BUILDFLAG(IS_ANDROID) -void DownloadImpl::SetJavaDownload( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& java_download) { - java_download_.Reset(env, java_download); -} - -base::android::ScopedJavaLocalRef<jstring> DownloadImpl::GetLocationImpl( - JNIEnv* env) { - return base::android::ScopedJavaLocalRef<jstring>( - base::android::ConvertUTF8ToJavaString(env, GetLocation().value())); -} - -base::android::ScopedJavaLocalRef<jstring> -DownloadImpl::GetFileNameToReportToUserImpl(JNIEnv* env) { - return base::android::ScopedJavaLocalRef<jstring>( - base::android::ConvertUTF16ToJavaString(env, - GetFileNameToReportToUser())); -} - -base::android::ScopedJavaLocalRef<jstring> DownloadImpl::GetMimeTypeImpl( - JNIEnv* env) { - return base::android::ScopedJavaLocalRef<jstring>( - base::android::ConvertUTF8ToJavaString(env, GetMimeType())); -} - -base::android::ScopedJavaLocalRef<jobject> DownloadImpl::GetLargeIconImpl( - JNIEnv* env) { - base::android::ScopedJavaLocalRef<jobject> j_icon; - const SkBitmap* icon = GetLargeIcon(); - - if (icon && !icon->drawsNothing()) - j_icon = gfx::ConvertToJavaBitmap(*icon); - - return j_icon; -} -#endif - -DownloadImpl::DownloadImpl() = default; - -bool DownloadImpl::HasBeenAddedToUi() { -#if BUILDFLAG(IS_ANDROID) - return static_cast<bool>(java_download_); -#else - // Since there is no UI outside of Android, we'll assume true. - return true; -#endif -} - -} // namespace weblayer
diff --git a/weblayer/browser/download_impl.h b/weblayer/browser/download_impl.h deleted file mode 100644 index 6874c115..0000000 --- a/weblayer/browser/download_impl.h +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_DOWNLOAD_IMPL_H_ -#define WEBLAYER_BROWSER_DOWNLOAD_IMPL_H_ - -#include "base/memory/weak_ptr.h" -#include "base/supports_user_data.h" -#include "build/build_config.h" -#include "url/gurl.h" -#include "weblayer/public/download.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/scoped_java_ref.h" -#endif - -class SkBitmap; - -namespace weblayer { - -// Base class for downloads that should be represented in the UI. -class DownloadImpl : public Download, public base::SupportsUserData::Data { - public: - ~DownloadImpl() override; - DownloadImpl(const DownloadImpl&) = delete; - DownloadImpl& operator=(const DownloadImpl&) = delete; - -#if BUILDFLAG(IS_ANDROID) - void SetJavaDownload( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& java_download); - int GetStateImpl(JNIEnv* env) { return static_cast<int>(GetState()); } - jlong GetTotalBytesImpl(JNIEnv* env) { return GetTotalBytes(); } - jlong GetReceivedBytesImpl(JNIEnv* env) { return GetReceivedBytes(); } - void PauseImpl(JNIEnv* env) { Pause(); } - void ResumeImpl(JNIEnv* env) { Resume(); } - void CancelImpl(JNIEnv* env) { Cancel(); } - void OnFinishedImpl(JNIEnv* env, jboolean activated) { - OnFinished(activated); - } - base::android::ScopedJavaLocalRef<jstring> GetLocationImpl(JNIEnv* env); - base::android::ScopedJavaLocalRef<jstring> GetFileNameToReportToUserImpl( - JNIEnv* env); - base::android::ScopedJavaLocalRef<jstring> GetMimeTypeImpl(JNIEnv* env); - int GetErrorImpl(JNIEnv* env) { return static_cast<int>(GetError()); } - base::android::ScopedJavaLocalRef<jobject> GetLargeIconImpl(JNIEnv* env); - - base::android::ScopedJavaGlobalRef<jobject> java_download() { - return java_download_; - } -#endif - - // Returns an ID suitable for use as an Android notification ID. This must be - // unique across all DownloadImpls. - virtual int GetNotificationId() = 0; - - // A transient download is not persisted to disk, which affects its UI - // treatment. - virtual bool IsTransient() = 0; - - // Returns the originating URL for this download. - virtual GURL GetSourceUrl() = 0; - - // Gets the icon to display. If the return value is null or draws nothing, no - // icon will be displayed. - virtual const SkBitmap* GetLargeIcon() = 0; - - // Called when the UI is gone. |activated| is true if the UI was activated, or - // false if it was simply dismissed. - virtual void OnFinished(bool activated) = 0; - - // Returns whether this download has been added to the UI via - // DownloadDelegate::OnDownloadStarted. - bool HasBeenAddedToUi(); - - protected: - DownloadImpl(); - - private: -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> java_download_; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_DOWNLOAD_IMPL_H_
diff --git a/weblayer/browser/download_manager_delegate_impl.cc b/weblayer/browser/download_manager_delegate_impl.cc deleted file mode 100644 index 5db47ad..0000000 --- a/weblayer/browser/download_manager_delegate_impl.cc +++ /dev/null
@@ -1,298 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/download_manager_delegate_impl.h" - -#include "base/files/file_util.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/thread_pool.h" -#include "build/build_config.h" -#include "components/download/public/common/download_item.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/download_item_utils.h" -#include "content/public/browser/download_manager.h" -#include "net/base/filename_util.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/download_manager_delegate_impl.h" -#include "weblayer/browser/persistent_download.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/download_delegate.h" - -namespace weblayer { - -namespace { - -void GenerateFilename( - const GURL& url, - const std::string& content_disposition, - const std::string& suggested_filename, - const std::string& mime_type, - const base::FilePath& suggested_directory, - base::OnceCallback<void(const base::FilePath&)> callback) { - base::FilePath generated_name = - net::GenerateFileName(url, content_disposition, std::string(), - suggested_filename, mime_type, "download"); - - if (!base::PathExists(suggested_directory)) - base::CreateDirectory(suggested_directory); - - base::FilePath suggested_path(suggested_directory.Append(generated_name)); - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), suggested_path)); -} - -} // namespace - -const char kDownloadNextIDPref[] = "weblayer_download_next_id"; - -DownloadManagerDelegateImpl::DownloadManagerDelegateImpl( - content::DownloadManager* download_manager) - : download_manager_(download_manager) { - download_manager_->AddObserver(this); - - // WebLayer doesn't use a history DB as the in-progress database maintained by - // the download component is enough. However the download code still depends - // this notification. TODO(jam): update download code to handle this. - download_manager_->PostInitialization( - content::DownloadManager::DOWNLOAD_INITIALIZATION_DEPENDENCY_HISTORY_DB); -} - -DownloadManagerDelegateImpl::~DownloadManagerDelegateImpl() { - download_manager_->RemoveObserver(this); - // Match the AddObserver calls added in OnDownloadCreated to avoid UaF. - download::SimpleDownloadManager::DownloadVector downloads; - download_manager_->GetAllDownloads(&downloads); - for (auto* download : downloads) - download->RemoveObserver(this); -} - -void DownloadManagerDelegateImpl::GetNextId( - content::DownloadIdCallback callback) { - // Need to return a unique id, even across crashes, to avoid notification - // intents with different data (e.g. notification GUID) getting dup'd. This is - // also persisted in the on-disk download database to support resumption. - auto* local_state = BrowserProcess::GetInstance()->GetLocalState(); - std::move(callback).Run(local_state->GetInteger(kDownloadNextIDPref)); -} - -bool DownloadManagerDelegateImpl::DetermineDownloadTarget( - download::DownloadItem* item, - content::DownloadTargetCallback* callback) { - if (!item->GetForcedFilePath().empty()) { - std::move(*callback).Run( - item->GetForcedFilePath(), - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - download::DownloadItem::InsecureDownloadStatus::UNKNOWN, - item->GetForcedFilePath(), base::FilePath(), - std::string() /*mime_type*/, download::DOWNLOAD_INTERRUPT_REASON_NONE); - return true; - } - - auto filename_determined_callback = base::BindOnce( - &DownloadManagerDelegateImpl::OnDownloadPathGenerated, - weak_ptr_factory_.GetWeakPtr(), item->GetId(), std::move(*callback)); - - auto* browser_context = content::DownloadItemUtils::GetBrowserContext(item); - base::FilePath default_download_path; - GetSaveDir(browser_context, nullptr, &default_download_path); - - base::ThreadPool::PostTask( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN, - base::TaskPriority::USER_VISIBLE}, - base::BindOnce( - GenerateFilename, item->GetURL(), item->GetContentDisposition(), - item->GetSuggestedFilename(), item->GetMimeType(), - default_download_path, std::move(filename_determined_callback))); - return true; -} - -bool DownloadManagerDelegateImpl::InterceptDownloadIfApplicable( - const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - const std::string& request_origin, - int64_t content_length, - bool is_transient, - content::WebContents* web_contents) { - // Don't intercept transient downloads (such as Background Fetches). - if (is_transient) - return false; - - // If there's no DownloadDelegate, the download is simply dropped. - auto* delegate = GetDelegate(web_contents); - if (!delegate) - return true; - - return delegate->InterceptDownload(url, user_agent, content_disposition, - mime_type, content_length); -} - -void DownloadManagerDelegateImpl::GetSaveDir( - content::BrowserContext* browser_context, - base::FilePath* website_save_dir, - base::FilePath* download_save_dir) { - auto* browser_context_impl = - static_cast<BrowserContextImpl*>(browser_context); - auto* profile = browser_context_impl->profile_impl(); - if (!profile->download_directory().empty()) - *download_save_dir = profile->download_directory(); -} - -void DownloadManagerDelegateImpl::CheckDownloadAllowed( - const content::WebContents::Getter& web_contents_getter, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - bool from_download_cross_origin_redirect, - bool content_initiated, - content::CheckDownloadAllowedCallback check_download_allowed_cb) { - auto* web_contents = web_contents_getter.Run(); - // If there's no DownloadDelegate, the download is simply dropped. - auto* delegate = GetDelegate(web_contents); - auto* tab = TabImpl::FromWebContents(web_contents); - if (!delegate || !tab) { - std::move(check_download_allowed_cb).Run(false); - return; - } - - delegate->AllowDownload(tab, url, request_method, request_initiator, - std::move(check_download_allowed_cb)); -} - -void DownloadManagerDelegateImpl::OnDownloadCreated( - content::DownloadManager* manager, - download::DownloadItem* item) { - auto* local_state = BrowserProcess::GetInstance()->GetLocalState(); - int next_id = local_state->GetInteger(kDownloadNextIDPref); - if (item->GetId() >= static_cast<uint32_t>(next_id)) { - next_id = item->GetId(); - // Reset the counter when it gets close to max value of unsigned 32 bit - // integer since that's what the download system persists. - if (++next_id == (std::numeric_limits<uint32_t>::max() / 2) - 1) - next_id = 0; - local_state->SetInteger(kDownloadNextIDPref, next_id); - } - - if (item->IsTransient()) - return; - - // As per the documentation in DownloadItem, transient items should not - // be shown in the UI. (Note that they may be surface by other means, - // such as through the BackgroundFetch system.) - item->AddObserver(this); - // Create a PersistentDownload which will be owned by |item|. - PersistentDownload::Create(item); - - if (item->GetLastReason() == download::DOWNLOAD_INTERRUPT_REASON_CRASH && - item->CanResume() && - // Don't automatically resume downloads which were previously paused. - !item->IsPaused()) { - PersistentDownload::Get(item)->Resume(); - } - - auto* delegate = GetDelegate(item); - if (delegate) - delegate->DownloadStarted(PersistentDownload::Get(item)); -} - -void DownloadManagerDelegateImpl::OnDownloadDropped( - content::DownloadManager* manager) { - if (download_dropped_callback_) - download_dropped_callback_.Run(); -} - -void DownloadManagerDelegateImpl::OnManagerInitialized() { - auto* browser_context_impl = - static_cast<BrowserContextImpl*>(download_manager_->GetBrowserContext()); - auto* profile = browser_context_impl->profile_impl(); - profile->DownloadsInitialized(); -} - -void DownloadManagerDelegateImpl::OnDownloadUpdated( - download::DownloadItem* item) { - // If this is the first navigation in a tab it should be closed. Wait until - // the target path is determined or the download is canceled to check. - if (!item->GetTargetFilePath().empty() || - item->GetState() == download::DownloadItem::CANCELLED) { - content::WebContents* web_contents = - content::DownloadItemUtils::GetWebContents(item); - if (web_contents && web_contents->GetController().IsInitialNavigation()) - web_contents->Close(); - } - - auto* delegate = GetDelegate(item); - if (item->GetState() == download::DownloadItem::COMPLETE || - item->GetState() == download::DownloadItem::CANCELLED || - item->GetState() == download::DownloadItem::INTERRUPTED) { - // Stop observing now to ensure we only send one complete/fail notification. - item->RemoveObserver(this); - - if (item->GetState() == download::DownloadItem::COMPLETE) - delegate->DownloadCompleted(PersistentDownload::Get(item)); - else - delegate->DownloadFailed(PersistentDownload::Get(item)); - - // Needs to happen asynchronously to avoid nested observer calls. - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce(&DownloadManagerDelegateImpl::RemoveItem, - weak_ptr_factory_.GetWeakPtr(), item->GetGuid())); - return; - } - - if (delegate) - delegate->DownloadProgressChanged(PersistentDownload::Get(item)); -} - -void DownloadManagerDelegateImpl::OnDownloadPathGenerated( - uint32_t download_id, - content::DownloadTargetCallback callback, - const base::FilePath& suggested_path) { - std::move(callback).Run( - suggested_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - download::DownloadItem::InsecureDownloadStatus::UNKNOWN, - suggested_path.AddExtension(FILE_PATH_LITERAL(".crdownload")), - base::FilePath(), std::string() /*mime_type*/, - download::DOWNLOAD_INTERRUPT_REASON_NONE); -} - -void DownloadManagerDelegateImpl::RemoveItem(const std::string& guid) { - auto* item = download_manager_->GetDownloadByGuid(guid); - if (item) - item->Remove(); -} - -DownloadDelegate* DownloadManagerDelegateImpl::GetDelegate( - content::WebContents* web_contents) { - if (!web_contents) - return nullptr; - - return GetDelegate(web_contents->GetBrowserContext()); -} - -DownloadDelegate* DownloadManagerDelegateImpl::GetDelegate( - content::BrowserContext* browser_context) { - auto* profile = ProfileImpl::FromBrowserContext(browser_context); - if (!profile) - return nullptr; - - return profile->download_delegate(); -} - -DownloadDelegate* DownloadManagerDelegateImpl::GetDelegate( - download::DownloadItem* item) { - auto* browser_context = content::DownloadItemUtils::GetBrowserContext(item); - return GetDelegate(browser_context); -} - -} // namespace weblayer
diff --git a/weblayer/browser/download_manager_delegate_impl.h b/weblayer/browser/download_manager_delegate_impl.h deleted file mode 100644 index 12afc5a..0000000 --- a/weblayer/browser/download_manager_delegate_impl.h +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_DOWNLOAD_MANAGER_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_DOWNLOAD_MANAGER_DELEGATE_IMPL_H_ - -#include "base/functional/callback_forward.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "components/download/public/common/download_item.h" -#include "content/public/browser/download_manager.h" -#include "content/public/browser/download_manager_delegate.h" - -namespace weblayer { -class DownloadDelegate; - -extern const char kDownloadNextIDPref[]; - -class DownloadManagerDelegateImpl : public content::DownloadManagerDelegate, - public content::DownloadManager::Observer, - public download::DownloadItem::Observer { - public: - explicit DownloadManagerDelegateImpl( - content::DownloadManager* download_manager); - - DownloadManagerDelegateImpl(const DownloadManagerDelegateImpl&) = delete; - DownloadManagerDelegateImpl& operator=(const DownloadManagerDelegateImpl&) = - delete; - - ~DownloadManagerDelegateImpl() override; - - void set_download_dropped_closure_for_testing( - const base::RepeatingClosure& callback) { - download_dropped_callback_ = callback; - } - - private: - // content::DownloadManagerDelegate implementation: - void GetNextId(content::DownloadIdCallback callback) override; - bool DetermineDownloadTarget( - download::DownloadItem* item, - content::DownloadTargetCallback* callback) override; - bool InterceptDownloadIfApplicable( - const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - const std::string& request_origin, - int64_t content_length, - bool is_transient, - content::WebContents* web_contents) override; - void GetSaveDir(content::BrowserContext* browser_context, - base::FilePath* website_save_dir, - base::FilePath* download_save_dir) override; - void CheckDownloadAllowed( - const content::WebContents::Getter& web_contents_getter, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - bool from_download_cross_origin_redirect, - bool content_initiated, - content::CheckDownloadAllowedCallback check_download_allowed_cb) override; - - // content::DownloadManager::Observer implementation: - void OnDownloadCreated(content::DownloadManager* manager, - download::DownloadItem* item) override; - void OnDownloadDropped(content::DownloadManager* manager) override; - void OnManagerInitialized() override; - - // download::DownloadItem::Observer implementation: - void OnDownloadUpdated(download::DownloadItem* item) override; - - void OnDownloadPathGenerated(uint32_t download_id, - content::DownloadTargetCallback callback, - const base::FilePath& suggested_path); - void RemoveItem(const std::string& guid); - - // Helper methods to get a DownloadDelegate. - DownloadDelegate* GetDelegate(content::WebContents* web_contents); - DownloadDelegate* GetDelegate(content::BrowserContext* browser_context); - DownloadDelegate* GetDelegate(download::DownloadItem* item); - - raw_ptr<content::DownloadManager> download_manager_; - base::RepeatingClosure download_dropped_callback_; - base::WeakPtrFactory<DownloadManagerDelegateImpl> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_DOWNLOAD_MANAGER_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/error_page_callback_proxy.cc b/weblayer/browser/error_page_callback_proxy.cc deleted file mode 100644 index f3bba1a..0000000 --- a/weblayer/browser/error_page_callback_proxy.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/error_page_callback_proxy.h" - -#include "base/android/jni_string.h" -#include "url/gurl.h" -#include "weblayer/browser/java/jni/ErrorPageCallbackProxy_jni.h" -#include "weblayer/browser/navigation_impl.h" -#include "weblayer/public/error_page.h" -#include "weblayer/public/tab.h" - -using base::android::AttachCurrentThread; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -ErrorPageCallbackProxy::ErrorPageCallbackProxy(JNIEnv* env, - jobject obj, - Tab* tab) - : tab_(tab), java_impl_(env, obj) { - tab_->SetErrorPageDelegate(this); -} - -ErrorPageCallbackProxy::~ErrorPageCallbackProxy() { - tab_->SetErrorPageDelegate(nullptr); -} - -bool ErrorPageCallbackProxy::OnBackToSafety() { - JNIEnv* env = AttachCurrentThread(); - return Java_ErrorPageCallbackProxy_onBackToSafety(env, java_impl_); -} - -std::unique_ptr<ErrorPage> ErrorPageCallbackProxy::GetErrorPageContent( - Navigation* navigation) { - JNIEnv* env = AttachCurrentThread(); - auto error_string = Java_ErrorPageCallbackProxy_getErrorPageContent( - env, java_impl_, - static_cast<NavigationImpl*>(navigation)->java_navigation()); - if (!error_string) - return nullptr; - auto error_page = std::make_unique<ErrorPage>(); - error_page->html = ConvertJavaStringToUTF8(env, error_string); - return error_page; -} - -static jlong JNI_ErrorPageCallbackProxy_CreateErrorPageCallbackProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong tab) { - return reinterpret_cast<jlong>( - new ErrorPageCallbackProxy(env, proxy, reinterpret_cast<Tab*>(tab))); -} - -static void JNI_ErrorPageCallbackProxy_DeleteErrorPageCallbackProxy( - JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<ErrorPageCallbackProxy*>(proxy); -} - -} // namespace weblayer
diff --git a/weblayer/browser/error_page_callback_proxy.h b/weblayer/browser/error_page_callback_proxy.h deleted file mode 100644 index c5593be..0000000 --- a/weblayer/browser/error_page_callback_proxy.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ERROR_PAGE_CALLBACK_PROXY_H_ -#define WEBLAYER_BROWSER_ERROR_PAGE_CALLBACK_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/memory/raw_ptr.h" -#include "weblayer/public/error_page_delegate.h" - -namespace weblayer { - -class Tab; - -// ErrorPageCallbackProxy forwards all ErrorPageDelegate functions to the Java -// side. There is one ErrorPageCallbackProxy per Tab. -class ErrorPageCallbackProxy : public ErrorPageDelegate { - public: - ErrorPageCallbackProxy(JNIEnv* env, jobject obj, Tab* tab); - - ErrorPageCallbackProxy(const ErrorPageCallbackProxy&) = delete; - ErrorPageCallbackProxy& operator=(const ErrorPageCallbackProxy&) = delete; - - ~ErrorPageCallbackProxy() override; - - // ErrorPageDelegate: - bool OnBackToSafety() override; - std::unique_ptr<ErrorPage> GetErrorPageContent( - Navigation* navigation) override; - - private: - raw_ptr<Tab> tab_; - base::android::ScopedJavaGlobalRef<jobject> java_impl_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ERROR_PAGE_CALLBACK_PROXY_H_
diff --git a/weblayer/browser/errorpage_browsertest.cc b/weblayer/browser/errorpage_browsertest.cc deleted file mode 100644 index 58ad3f4de..0000000 --- a/weblayer/browser/errorpage_browsertest.cc +++ /dev/null
@@ -1,200 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/raw_ptr.h" -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/embedder_support/switches.h" -#include "components/error_page/content/browser/net_error_auto_reloader.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/url_loader_interceptor.h" -#include "net/test/url_request/url_request_failed_job.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/strings/grit/components_strings.h" -#include "ui/base/l10n/l10n_util.h" -#endif - -namespace weblayer { - -using ErrorPageBrowserTest = WebLayerBrowserTest; - -IN_PROC_BROWSER_TEST_F(ErrorPageBrowserTest, NameNotResolved) { - GURL error_page_url = - net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED); - - NavigateAndWaitForFailure(error_page_url, shell()); - - // Currently, interstitials for error pages are displayed only on Android. -#if BUILDFLAG(IS_ANDROID) - std::u16string expected_title = - l10n_util::GetStringUTF16(IDS_ANDROID_ERROR_PAGE_WEBPAGE_NOT_AVAILABLE); - EXPECT_EQ(expected_title, GetTitle(shell())); -#endif -} - -// Verifies that navigating to a URL that returns a 404 with an empty body -// results in the navigation failing. -IN_PROC_BROWSER_TEST_F(ErrorPageBrowserTest, 404WithEmptyBody) { - EXPECT_TRUE(embedded_test_server()->Start()); - - GURL error_page_url = embedded_test_server()->GetURL("/empty404.html"); - - NavigateAndWaitForFailure(error_page_url, shell()); -} - -class ErrorPageReloadBrowserTest : public ErrorPageBrowserTest { - public: - ErrorPageReloadBrowserTest() = default; - - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(embedder_support::kEnableAutoReload); - ErrorPageBrowserTest::SetUpCommandLine(command_line); - } - - // Helper to perform navigations, whether successful or intercepted for - // simulated failure. Note that this asynchronously initiates the navigation - // and then waits only for the *navigation* to finish; this is in contrast to - // common test utilities which wait for loading to finish. It matters because - // most of NetErrorAutoReloader's interesting behavior is triggered at - // navigation completion and tests may want to observe the immediate side - // effects, such as the scheduling of an auto-reload timer. - // - // Return true if the navigation was successful, or false if it failed. - [[nodiscard]] bool Navigate(const GURL& url, - bool disable_network_error_auto_reload = false) { - content::TestNavigationManager navigation(web_contents(), url); - NavigationController::NavigateParams params; - auto* navigation_controller = shell()->tab()->GetNavigationController(); - std::unique_ptr<DisableAutoReload> disable_auto_reload; - if (disable_network_error_auto_reload) - disable_auto_reload = - std::make_unique<DisableAutoReload>(navigation_controller); - navigation_controller->Navigate(url, params); - EXPECT_TRUE(navigation.WaitForNavigationFinished()); - return navigation.was_successful(); - } - - // Returns the time-delay of the currently scheduled auto-reload task, if one - // is scheduled. If no auto-reload is scheduled, this returns null. - absl::optional<base::TimeDelta> GetCurrentAutoReloadDelay() { - auto* auto_reloader = - error_page::NetErrorAutoReloader::FromWebContents(web_contents()); - if (!auto_reloader) - return absl::nullopt; - const absl::optional<base::OneShotTimer>& timer = - auto_reloader->next_reload_timer_for_testing(); - if (!timer) - return absl::nullopt; - return timer->GetCurrentDelay(); - } - - content::WebContents* web_contents() { - return static_cast<TabImpl*>(shell()->tab())->web_contents(); - } - - private: - class DisableAutoReload : public NavigationObserver { - public: - explicit DisableAutoReload(NavigationController* controller) - : controller_(controller) { - controller_->AddObserver(this); - } - ~DisableAutoReload() override { controller_->RemoveObserver(this); } - - // NavigationObserver implementation: - void NavigationStarted(Navigation* navigation) override { - navigation->DisableNetworkErrorAutoReload(); - } - - private: - raw_ptr<NavigationController> controller_; - }; -}; - -IN_PROC_BROWSER_TEST_F(ErrorPageReloadBrowserTest, ReloadOnNetworkChanged) { - ASSERT_TRUE(embedded_test_server()->Start()); - // Ensure that the NetErrorAutoReloader believes it's online, otherwise it - // does not attempt auto-reload on error pages. - error_page::NetErrorAutoReloader::CreateForWebContents(web_contents()); - auto* reloader = - error_page::NetErrorAutoReloader::FromWebContents(web_contents()); - reloader->DisableConnectionChangeObservationForTesting(); - reloader->OnConnectionChanged(network::mojom::ConnectionType::CONNECTION_4G); - - GURL url = embedded_test_server()->GetURL("/error_page"); - // We send net::ERR_NETWORK_CHANGED on the first load, and the reload should - // get a net::OK response. - bool first_try = true; - content::URLLoaderInterceptor interceptor(base::BindLambdaForTesting( - [&url, &first_try](content::URLLoaderInterceptor::RequestParams* params) { - if (params->url_request.url == url) { - if (first_try) { - first_try = false; - params->client->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_NETWORK_CHANGED)); - } else { - content::URLLoaderInterceptor::WriteResponse( - "weblayer/test/data/simple_page.html", params->client.get()); - } - return true; - } - return false; - })); - - NavigateAndWaitForCompletion(url, shell()); -} - -// By default auto reload is enabled. -IN_PROC_BROWSER_TEST_F(ErrorPageReloadBrowserTest, AutoReloadDefault) { - ASSERT_TRUE(embedded_test_server()->Start()); - // Ensure that the NetErrorAutoReloader believes it's online, otherwise it - // does not attempt auto-reload on error pages. - error_page::NetErrorAutoReloader::CreateForWebContents(web_contents()); - auto* reloader = - error_page::NetErrorAutoReloader::FromWebContents(web_contents()); - reloader->DisableConnectionChangeObservationForTesting(); - reloader->OnConnectionChanged(network::mojom::ConnectionType::CONNECTION_4G); - - GURL url = embedded_test_server()->GetURL("/error_page"); - content::URLLoaderInterceptor interceptor(base::BindLambdaForTesting( - [&url](content::URLLoaderInterceptor::RequestParams* params) { - if (params->url_request.url == url) { - params->client->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_NETWORK_CHANGED)); - return true; - } - return false; - })); - - EXPECT_FALSE(Navigate(url)); - EXPECT_EQ(error_page::NetErrorAutoReloader::GetNextReloadDelayForTesting(0), - GetCurrentAutoReloadDelay()); -} - -IN_PROC_BROWSER_TEST_F(ErrorPageReloadBrowserTest, AutoReloadDisabled) { - ASSERT_TRUE(embedded_test_server()->Start()); - GURL url = embedded_test_server()->GetURL("/error_page"); - content::URLLoaderInterceptor interceptor(base::BindLambdaForTesting( - [&url](content::URLLoaderInterceptor::RequestParams* params) { - if (params->url_request.url == url) { - params->client->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_NETWORK_CHANGED)); - return true; - } - return false; - })); - - EXPECT_FALSE(Navigate(url, true)); - EXPECT_EQ(absl::nullopt, GetCurrentAutoReloadDelay()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_backend_wrapper.cc b/weblayer/browser/favicon/favicon_backend_wrapper.cc deleted file mode 100644 index 717dbbc..0000000 --- a/weblayer/browser/favicon/favicon_backend_wrapper.cc +++ /dev/null
@@ -1,204 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_backend_wrapper.h" - -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/task/sequenced_task_runner.h" -#include "components/favicon/core/favicon_backend.h" -#include "components/favicon/core/favicon_database.h" - -namespace weblayer { - -// Removing out of date entries can be costly. To avoid blocking the thread -// this code runs on, the work is potentially throttled. Specifically at -// most |kMaxNumberOfEntriesToRemoveAtATime| are removed during a single call. -// If |kMaxNumberOfEntriesToRemoveAtATime| are removed, then there may be more -// entries that can be removed, so the timer is restarted with a shorter time -// out (|kTimeDeltaForRunningExpireWithRemainingWork|). -constexpr base::TimeDelta kTimeDeltaForRunningExpireNoRemainingWork = - base::Hours(1); -constexpr int kMaxNumberOfEntriesToRemoveAtATime = 100; - -FaviconBackendWrapper::FaviconBackendWrapper( - scoped_refptr<base::SequencedTaskRunner> task_runner) - : base::RefCountedDeleteOnSequence<FaviconBackendWrapper>(task_runner), - task_runner_(task_runner) {} - -void FaviconBackendWrapper::Init(const base::FilePath& db_path) { - db_path_ = db_path; - favicon_backend_ = favicon::FaviconBackend::Create(db_path, this); - if (!favicon_backend_) { - LOG(WARNING) << "Could not initialize the favicon database."; - - // The favicon db is not critical. On failure initializing try deleting - // the file and repeating. Note that FaviconDatabase already tries to - // initialize twice. - base::DeleteFile(db_path); - - favicon_backend_ = favicon::FaviconBackend::Create(db_path, this); - if (!favicon_backend_) { - LOG(WARNING) << "Could not initialize db second time, giving up."; - return; - } - } - - expire_timer_.Start(FROM_HERE, kTimeDeltaForRunningExpireWithRemainingWork, - this, &FaviconBackendWrapper::OnExpireTimerFired); -} - -void FaviconBackendWrapper::Shutdown() { - // Ensures there isn't a reference to this in the task runner (by way of the - // task the timer posts). - commit_timer_.Stop(); - expire_timer_.Stop(); -} - -void FaviconBackendWrapper::DeleteAndRecreateDatabase() { - Shutdown(); - favicon_backend_.reset(); - base::DeleteFile(db_path_); - Init(db_path_); -} - -std::vector<favicon_base::FaviconRawBitmapResult> -FaviconBackendWrapper::GetFaviconsForUrl( - const GURL& page_url, - const favicon_base::IconTypeSet& icon_types, - const std::vector<int>& desired_sizes) { - if (!favicon_backend_) - return {}; - return favicon_backend_->GetFaviconsForUrl(page_url, icon_types, - desired_sizes, - /* fallback_to_host */ false); -} - -favicon_base::FaviconRawBitmapResult -FaviconBackendWrapper::GetLargestFaviconForUrl( - const GURL& page_url, - const std::vector<favicon_base::IconTypeSet>& icon_types_list, - int minimum_size_in_pixels) { - if (!favicon_backend_) - return {}; - return favicon_backend_->GetLargestFaviconForUrl(page_url, icon_types_list, - minimum_size_in_pixels); -} - -void FaviconBackendWrapper::SetFaviconsOutOfDateForPage(const GURL& page_url) { - if (favicon_backend_ && - favicon_backend_->SetFaviconsOutOfDateForPage(page_url)) { - ScheduleCommit(); - } -} - -void FaviconBackendWrapper::SetFavicons(const base::flat_set<GURL>& page_urls, - favicon_base::IconType icon_type, - const GURL& icon_url, - const std::vector<SkBitmap>& bitmaps) { - if (favicon_backend_ && - favicon_backend_ - ->SetFavicons(page_urls, icon_type, icon_url, bitmaps, - favicon::FaviconBitmapType::ON_VISIT) - .did_change_database()) { - ScheduleCommit(); - } -} - -void FaviconBackendWrapper::CloneFaviconMappingsForPages( - const GURL& page_url_to_read, - const favicon_base::IconTypeSet& icon_types, - const base::flat_set<GURL>& page_urls_to_write) { - if (!favicon_backend_) - return; - - std::set<GURL> changed_urls = favicon_backend_->CloneFaviconMappingsForPages( - {page_url_to_read}, icon_types, page_urls_to_write); - if (!changed_urls.empty()) - ScheduleCommit(); -} - -std::vector<favicon_base::FaviconRawBitmapResult> -FaviconBackendWrapper::GetFavicon(const GURL& icon_url, - favicon_base::IconType icon_type, - const std::vector<int>& desired_sizes) { - return UpdateFaviconMappingsAndFetch({}, icon_url, icon_type, desired_sizes); -} - -std::vector<favicon_base::FaviconRawBitmapResult> -FaviconBackendWrapper::UpdateFaviconMappingsAndFetch( - const base::flat_set<GURL>& page_urls, - const GURL& icon_url, - favicon_base::IconType icon_type, - const std::vector<int>& desired_sizes) { - if (!favicon_backend_) - return {}; - auto result = favicon_backend_->UpdateFaviconMappingsAndFetch( - page_urls, icon_url, icon_type, desired_sizes); - if (!result.updated_page_urls.empty()) - ScheduleCommit(); - return result.bitmap_results; -} - -void FaviconBackendWrapper::DeleteFaviconMappings( - const base::flat_set<GURL>& page_urls, - favicon_base::IconType icon_type) { - if (!favicon_backend_) - return; - - auto deleted_page_urls = - favicon_backend_->DeleteFaviconMappings(page_urls, icon_type); - if (!deleted_page_urls.empty()) - ScheduleCommit(); -} - -std::vector<GURL> FaviconBackendWrapper::GetCachedRecentRedirectsForPage( - const GURL& page_url) { - // By only returning |page_url| this code won't set the favicon on redirects. - // If that becomes necessary, we would need this class to know about - // redirects. Chrome does this by way of HistoryService remembering redirects - // for recent pages. See |HistoryBackend::recent_redirects_|. - return {page_url}; -} - -FaviconBackendWrapper::~FaviconBackendWrapper() = default; - -void FaviconBackendWrapper::ScheduleCommit() { - if (!commit_timer_.IsRunning()) { - // 10 seconds matches that of HistoryBackend. - commit_timer_.Start(FROM_HERE, base::Seconds(10), this, - &FaviconBackendWrapper::Commit); - } -} - -void FaviconBackendWrapper::Commit() { - if (favicon_backend_) - favicon_backend_->Commit(); -} - -void FaviconBackendWrapper::OnExpireTimerFired() { - if (!favicon_backend_) - return; - - // See comments above |kTimeDeltaForRunningExpireNoRemainingWork| for a - // description of this logic. - favicon::FaviconDatabase* db = favicon_backend_->db(); - auto icon_ids = db->GetFaviconsLastUpdatedBefore( - base::Time::Now() - kTimeDeltaWhenEntriesAreRemoved, - kMaxNumberOfEntriesToRemoveAtATime); - for (favicon_base::FaviconID icon_id : icon_ids) { - db->DeleteFavicon(icon_id); - db->DeleteIconMappingsForFaviconId(icon_id); - } - if (!icon_ids.empty()) - Commit(); - const base::TimeDelta delta = - icon_ids.size() == kMaxNumberOfEntriesToRemoveAtATime - ? kTimeDeltaForRunningExpireWithRemainingWork - : kTimeDeltaForRunningExpireNoRemainingWork; - expire_timer_.Start(FROM_HERE, delta, this, - &FaviconBackendWrapper::OnExpireTimerFired); -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_backend_wrapper.h b/weblayer/browser/favicon/favicon_backend_wrapper.h deleted file mode 100644 index 62d8517..0000000 --- a/weblayer/browser/favicon/favicon_backend_wrapper.h +++ /dev/null
@@ -1,125 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_FAVICON_BACKEND_WRAPPER_H_ -#define WEBLAYER_BROWSER_FAVICON_FAVICON_BACKEND_WRAPPER_H_ - -#include <memory> -#include <vector> - -#include "base/files/file_path.h" -#include "base/memory/ref_counted.h" -#include "base/memory/ref_counted_delete_on_sequence.h" -#include "base/timer/timer.h" -#include "components/favicon/core/favicon_backend_delegate.h" -#include "components/favicon_base/favicon_types.h" - -class GURL; - -namespace base { -class FilePath; -class SequencedTaskRunner; -} // namespace base - -namespace favicon { -class FaviconBackend; -} - -namespace weblayer { - -// FaviconBackendWrapper runs on a background task-runner and owns the database -// side of favicons. This class largely delegates to favicon::FaviconBackend. -class FaviconBackendWrapper - : public base::RefCountedDeleteOnSequence<FaviconBackendWrapper>, - public favicon::FaviconBackendDelegate { - public: - explicit FaviconBackendWrapper( - scoped_refptr<base::SequencedTaskRunner> task_runner); - FaviconBackendWrapper(const FaviconBackendWrapper&) = delete; - FaviconBackendWrapper& operator=(const FaviconBackendWrapper&) = delete; - - void Init(const base::FilePath& db_path); - - void Shutdown(); - - void DeleteAndRecreateDatabase(); - - // All of these functions are called by the FaviconServiceImpl. They call - // through to |favicon_backend_|. - std::vector<favicon_base::FaviconRawBitmapResult> GetFaviconsForUrl( - const GURL& page_url, - const favicon_base::IconTypeSet& icon_types, - const std::vector<int>& desired_sizes); - favicon_base::FaviconRawBitmapResult GetLargestFaviconForUrl( - const GURL& page_url, - const std::vector<favicon_base::IconTypeSet>& icon_types_list, - int minimum_size_in_pixels); - void SetFaviconsOutOfDateForPage(const GURL& page_url); - void SetFavicons(const base::flat_set<GURL>& page_urls, - favicon_base::IconType icon_type, - const GURL& icon_url, - const std::vector<SkBitmap>& bitmaps); - void CloneFaviconMappingsForPages( - const GURL& page_url_to_read, - const favicon_base::IconTypeSet& icon_types, - const base::flat_set<GURL>& page_urls_to_write); - std::vector<favicon_base::FaviconRawBitmapResult> GetFavicon( - const GURL& icon_url, - favicon_base::IconType icon_type, - const std::vector<int>& desired_sizes); - std::vector<favicon_base::FaviconRawBitmapResult> - UpdateFaviconMappingsAndFetch(const base::flat_set<GURL>& page_urls, - const GURL& icon_url, - favicon_base::IconType icon_type, - const std::vector<int>& desired_sizes); - void DeleteFaviconMappings(const base::flat_set<GURL>& page_urls, - favicon_base::IconType icon_type); - - // favicon::FaviconBackendDelegate: - std::vector<GURL> GetCachedRecentRedirectsForPage( - const GURL& page_url) override; - - private: - friend class base::RefCountedDeleteOnSequence<FaviconBackendWrapper>; - friend class base::DeleteHelper<FaviconBackendWrapper>; - friend class FaviconBackendWrapperTest; - - ~FaviconBackendWrapper() override; - - void ScheduleCommit(); - void Commit(); - - // Called to expire (remove) out of date icons and restart the timer. - void OnExpireTimerFired(); - - scoped_refptr<base::SequencedTaskRunner> task_runner_; - - // Timer used to delay commits for a short amount of time. This done to - // batch commits. - base::OneShotTimer commit_timer_; - - // The real implementation of the backend. If there is a problem - // initializing the database this will be null. - std::unique_ptr<favicon::FaviconBackend> favicon_backend_; - - // Timer used to remove items from the database that are likely no longer - // needed. - base::OneShotTimer expire_timer_; - - base::FilePath db_path_; -}; - -// These values are here only for tests. - -// Amount of time before favicons are removed. That is, any favicons downloaded -// before this amount of time are removed. -constexpr base::TimeDelta kTimeDeltaWhenEntriesAreRemoved = base::Days(30); - -// See comment near kMaxNumberOfEntriesToRemoveAtATime for details on this. -constexpr base::TimeDelta kTimeDeltaForRunningExpireWithRemainingWork = - base::Minutes(2); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_FAVICON_BACKEND_WRAPPER_H_
diff --git a/weblayer/browser/favicon/favicon_backend_wrapper_unittest.cc b/weblayer/browser/favicon/favicon_backend_wrapper_unittest.cc deleted file mode 100644 index e18e130..0000000 --- a/weblayer/browser/favicon/favicon_backend_wrapper_unittest.cc +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_backend_wrapper.h" - -#include <vector> - -#include "base/files/file_path.h" -#include "base/files/scoped_temp_dir.h" -#include "base/memory/ref_counted_memory.h" -#include "base/task/single_thread_task_runner.h" -#include "base/test/task_environment.h" -#include "base/time/time.h" -#include "components/favicon/core/favicon_backend.h" -#include "components/favicon/core/favicon_database.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace weblayer { -namespace { - -// Blobs for adding favicons. -const unsigned char kBlob1[] = - "12346102356120394751634516591348710478123649165419234519234512349134"; - -} // namespace - -class FaviconBackendWrapperTest : public testing::Test { - protected: - favicon::FaviconBackend* backend() { - return wrapper_->favicon_backend_.get(); - } - - // testing::Test: - void SetUp() override { - // Get a temporary directory for the test DB files. - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - db_path_ = temp_dir_.GetPath().AppendASCII("test_db"); - } - - void TearDown() override { - wrapper_ = nullptr; - testing::Test::TearDown(); - } - - base::test::SingleThreadTaskEnvironment task_environment_{ - base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - base::ScopedTempDir temp_dir_; - base::FilePath db_path_; - scoped_refptr<FaviconBackendWrapper> wrapper_; -}; - -TEST_F(FaviconBackendWrapperTest, BasicExpire) { - wrapper_ = base::MakeRefCounted<FaviconBackendWrapper>( - base::SingleThreadTaskRunner::GetCurrentDefault()); - wrapper_->Init(db_path_); - ASSERT_TRUE(backend()); - auto* db = backend()->db(); - - std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); - scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); - GURL url("http://google.com"); - const base::Time time1 = base::Time::Now(); - favicon_base::FaviconID favicon_id1 = - db->AddFavicon(url, favicon_base::IconType::kTouchIcon, favicon, - favicon::FaviconBitmapType::ON_VISIT, time1, gfx::Size()); - ASSERT_NE(0, favicon_id1); - favicon::IconMappingID icon_mapping_id1 = - db->AddIconMapping(url, favicon_id1); - ASSERT_NE(0, icon_mapping_id1); - - // Fast forward past first expire running. - task_environment_.FastForwardBy(kTimeDeltaForRunningExpireWithRemainingWork * - 2); - // The icon should still be there. - EXPECT_TRUE(db->GetFaviconHeader(favicon_id1, nullptr, nullptr)); - EXPECT_TRUE(db->HasMappingFor(favicon_id1)); - - // Fast forward such that the icon is removed. - task_environment_.FastForwardBy(kTimeDeltaWhenEntriesAreRemoved); - EXPECT_FALSE(db->GetFaviconHeader(favicon_id1, nullptr, nullptr)); - EXPECT_FALSE(db->HasMappingFor(favicon_id1)); -} - -TEST_F(FaviconBackendWrapperTest, ExpireWithOneRemaining) { - wrapper_ = base::MakeRefCounted<FaviconBackendWrapper>( - base::SingleThreadTaskRunner::GetCurrentDefault()); - wrapper_->Init(db_path_); - ASSERT_TRUE(backend()); - auto* db = backend()->db(); - - // Add two entries. The second is more recent then the first. - std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); - scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); - GURL url("http://google.com"); - const base::Time time1 = base::Time::Now(); - favicon_base::FaviconID favicon_id1 = - db->AddFavicon(url, favicon_base::IconType::kTouchIcon, favicon, - favicon::FaviconBitmapType::ON_VISIT, time1, gfx::Size()); - ASSERT_NE(0, favicon_id1); - favicon::IconMappingID icon_mapping_id1 = - db->AddIconMapping(url, favicon_id1); - ASSERT_NE(0, icon_mapping_id1); - const base::Time time2 = time1 + kTimeDeltaWhenEntriesAreRemoved / 2; - favicon_base::FaviconID favicon_id2 = - db->AddFavicon(url, favicon_base::IconType::kTouchIcon, favicon, - favicon::FaviconBitmapType::ON_VISIT, time2, gfx::Size()); - ASSERT_NE(0, favicon_id2); - favicon::IconMappingID icon_mapping_id2 = - db->AddIconMapping(url, favicon_id2); - ASSERT_NE(0, icon_mapping_id2); - - // Fast forward such the first entry is expired and should be removed, but - // not the second. - task_environment_.FastForwardBy(kTimeDeltaWhenEntriesAreRemoved + - base::Days(1)); - EXPECT_FALSE(db->GetFaviconHeader(favicon_id1, nullptr, nullptr)); - EXPECT_FALSE(db->HasMappingFor(favicon_id1)); - EXPECT_TRUE(db->GetFaviconHeader(favicon_id2, nullptr, nullptr)); - EXPECT_TRUE(db->HasMappingFor(favicon_id2)); - - // Fast forward enough such that second is removed. - task_environment_.FastForwardBy(kTimeDeltaWhenEntriesAreRemoved + - base::Days(1)); - EXPECT_FALSE(db->GetFaviconHeader(favicon_id2, nullptr, nullptr)); - EXPECT_FALSE(db->HasMappingFor(favicon_id2)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_callback_proxy.cc b/weblayer/browser/favicon/favicon_callback_proxy.cc deleted file mode 100644 index a730c91..0000000 --- a/weblayer/browser/favicon/favicon_callback_proxy.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_callback_proxy.h" - -#include "base/android/jni_string.h" -#include "ui/gfx/android/java_bitmap.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/image/image_skia_rep.h" -#include "url/gurl.h" -#include "weblayer/browser/java/jni/FaviconCallbackProxy_jni.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/favicon_fetcher.h" - -namespace weblayer { - -FaviconCallbackProxy::FaviconCallbackProxy(JNIEnv* env, jobject obj, Tab* tab) - : java_proxy_(env, obj), - favicon_fetcher_(tab->CreateFaviconFetcher(this)) {} - -FaviconCallbackProxy::~FaviconCallbackProxy() = default; - -void FaviconCallbackProxy::OnFaviconChanged(const gfx::Image& image) { - SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).GetBitmap(); - JNIEnv* env = base::android::AttachCurrentThread(); - Java_FaviconCallbackProxy_onFaviconChanged( - env, java_proxy_, - favicon.empty() ? nullptr : gfx::ConvertToJavaBitmap(favicon)); -} - -static jlong JNI_FaviconCallbackProxy_CreateFaviconCallbackProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong tab) { - return reinterpret_cast<jlong>( - new FaviconCallbackProxy(env, proxy, reinterpret_cast<TabImpl*>(tab))); -} - -static void JNI_FaviconCallbackProxy_DeleteFaviconCallbackProxy(JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<FaviconCallbackProxy*>(proxy); -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_callback_proxy.h b/weblayer/browser/favicon/favicon_callback_proxy.h deleted file mode 100644 index 28ad210..0000000 --- a/weblayer/browser/favicon/favicon_callback_proxy.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_FAVICON_CALLBACK_PROXY_H_ -#define WEBLAYER_BROWSER_FAVICON_FAVICON_CALLBACK_PROXY_H_ - -#include <memory> - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "weblayer/public/favicon_fetcher_delegate.h" - -namespace weblayer { - -class FaviconFetcher; -class Tab; - -// FullscreenCallbackProxy forwards all FullscreenDelegate functions to the -// Java side. There is at most one FullscreenCallbackProxy per Tab. -class FaviconCallbackProxy : public FaviconFetcherDelegate { - public: - FaviconCallbackProxy(JNIEnv* env, jobject obj, Tab* tab); - FaviconCallbackProxy(const FaviconCallbackProxy&) = delete; - FaviconCallbackProxy& operator=(const FaviconCallbackProxy&) = delete; - ~FaviconCallbackProxy() override; - - // FaviconFetcherDelegate: - void OnFaviconChanged(const gfx::Image& image) override; - - private: - base::android::ScopedJavaGlobalRef<jobject> java_proxy_; - std::unique_ptr<FaviconFetcher> favicon_fetcher_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_FAVICON_CALLBACK_PROXY_H_
diff --git a/weblayer/browser/favicon/favicon_fetcher_browsertest.cc b/weblayer/browser/favicon/favicon_fetcher_browsertest.cc deleted file mode 100644 index 5f4919f..0000000 --- a/weblayer/browser/favicon/favicon_fetcher_browsertest.cc +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_fetcher_impl.h" - -#include "base/run_loop.h" -#include "build/build_config.h" -#include "components/favicon/content/content_favicon_driver.h" -#include "ui/gfx/image/image.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/favicon/favicon_fetcher_impl.h" -#include "weblayer/browser/favicon/favicon_service_impl.h" -#include "weblayer/browser/favicon/favicon_service_impl_factory.h" -#include "weblayer/browser/favicon/favicon_service_impl_observer.h" -#include "weblayer/browser/favicon/test_favicon_fetcher_delegate.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/browser.h" -#include "weblayer/public/favicon_fetcher_delegate.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { -namespace { - -// FaviconServiceImplObserver used to wait for download to fail. -class TestFaviconServiceImplObserver : public FaviconServiceImplObserver { - public: - void Wait() { - ASSERT_EQ(nullptr, run_loop_.get()); - run_loop_ = std::make_unique<base::RunLoop>(); - run_loop_->Run(); - run_loop_.reset(); - } - - // FaviconServiceImplObserver: - void OnUnableToDownloadFavicon() override { - if (run_loop_) - run_loop_->Quit(); - } - - private: - std::unique_ptr<base::RunLoop> run_loop_; -}; - -} // namespace - -using FaviconFetcherBrowserTest = WebLayerBrowserTest; - -IN_PROC_BROWSER_TEST_F(FaviconFetcherBrowserTest, Basic) { - ASSERT_TRUE(embedded_test_server()->Start()); - TestFaviconFetcherDelegate fetcher_delegate; - auto fetcher = shell()->tab()->CreateFaviconFetcher(&fetcher_delegate); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL( - "/simple_page_with_favicon_and_before_unload.html"), - shell()); - fetcher_delegate.WaitForFavicon(); - EXPECT_FALSE(fetcher_delegate.last_image().IsEmpty()); - EXPECT_EQ(fetcher_delegate.last_image(), fetcher->GetFavicon()); - EXPECT_EQ(1, fetcher_delegate.on_favicon_changed_call_count()); - fetcher_delegate.ClearLastImage(); - - const GURL url2 = - embedded_test_server()->GetURL("/simple_page_with_favicon.html"); - shell()->tab()->GetNavigationController()->Navigate(url2); - // Favicon doesn't change immediately on navigation. - EXPECT_FALSE(fetcher->GetFavicon().IsEmpty()); - // Favicon does change once start is received. - TestNavigationObserver test_observer( - url2, TestNavigationObserver::NavigationEvent::kStart, shell()); - test_observer.Wait(); - EXPECT_TRUE(fetcher_delegate.last_image().IsEmpty()); - - fetcher_delegate.WaitForNonemptyFavicon(); - EXPECT_FALSE(fetcher_delegate.last_image().IsEmpty()); - EXPECT_EQ(fetcher_delegate.last_image(), fetcher->GetFavicon()); - // OnFaviconChanged() is called twice, once with an empty image (because of - // the navigation), the second with the real image. - EXPECT_EQ(2, fetcher_delegate.on_favicon_changed_call_count()); -} - -IN_PROC_BROWSER_TEST_F(FaviconFetcherBrowserTest, NavigateToPageWithNoFavicon) { - ASSERT_TRUE(embedded_test_server()->Start()); - TestFaviconFetcherDelegate fetcher_delegate; - auto fetcher = shell()->tab()->CreateFaviconFetcher(&fetcher_delegate); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page_with_favicon.html"), - shell()); - fetcher_delegate.WaitForFavicon(); - fetcher_delegate.ClearLastImage(); - - TestFaviconServiceImplObserver test_observer; - FaviconServiceImplFactory::GetForBrowserContext( - static_cast<TabImpl*>(shell()->tab())->profile()->GetBrowserContext()) - ->set_observer(&test_observer); - - const GURL url2 = embedded_test_server()->GetURL("/simple_page.html"); - shell()->tab()->GetNavigationController()->Navigate(url2); - EXPECT_TRUE(fetcher_delegate.last_image().IsEmpty()); - // The delegate should be notified of the empty image once. - test_observer.Wait(); - EXPECT_TRUE(fetcher_delegate.last_image().IsEmpty()); - EXPECT_EQ(1, fetcher_delegate.on_favicon_changed_call_count()); -} - -IN_PROC_BROWSER_TEST_F(FaviconFetcherBrowserTest, - ContentFaviconDriverLifetime) { - ASSERT_TRUE(embedded_test_server()->Start()); - content::WebContents* web_contents = - static_cast<TabImpl*>(shell()->tab())->web_contents(); - - // Drivers are immediately created for every tab. - auto* favicon_driver = - favicon::ContentFaviconDriver::FromWebContents(web_contents); - EXPECT_NE(nullptr, favicon_driver); - - // Request a fetcher, which should trigger creating ContentFaviconDriver. - TestFaviconFetcherDelegate fetcher_delegate; - auto fetcher = shell()->tab()->CreateFaviconFetcher(&fetcher_delegate); - // Check that the driver has not changed. - EXPECT_EQ(favicon_driver, - favicon::ContentFaviconDriver::FromWebContents(web_contents)); - - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page_with_favicon.html"), - shell()); - fetcher_delegate.WaitForFavicon(); - EXPECT_FALSE(fetcher_delegate.last_image().IsEmpty()); -} - -// This test creates a Browser and Tab, which doesn't work well with Java when -// driven from native code. -#if !BUILDFLAG(IS_ANDROID) -IN_PROC_BROWSER_TEST_F(FaviconFetcherBrowserTest, OffTheRecord) { - auto otr_profile = Profile::Create(std::string(), true); - ProfileImpl* otr_profile_impl = static_cast<ProfileImpl*>(otr_profile.get()); - EXPECT_TRUE(otr_profile_impl->GetBrowserContext()->IsOffTheRecord()); - auto otr_browser = Browser::Create(otr_profile.get(), nullptr); - Tab* tab = otr_browser->CreateTab(); - - // There is no FaviconService for off the record profiles. FaviconService - // writes to disk, which is not appropriate for off the record mode. - EXPECT_EQ(nullptr, FaviconServiceImplFactory::GetForBrowserContext( - otr_profile_impl->GetBrowserContext())); - ASSERT_TRUE(embedded_test_server()->Start()); - TestFaviconFetcherDelegate fetcher_delegate; - auto fetcher = tab->CreateFaviconFetcher(&fetcher_delegate); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page_with_favicon.html"), tab); - fetcher_delegate.WaitForFavicon(); - EXPECT_FALSE(fetcher_delegate.last_image().IsEmpty()); - EXPECT_EQ(fetcher_delegate.last_image(), fetcher->GetFavicon()); - EXPECT_EQ(1, fetcher_delegate.on_favicon_changed_call_count()); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_fetcher_impl.cc b/weblayer/browser/favicon/favicon_fetcher_impl.cc deleted file mode 100644 index d002ba9..0000000 --- a/weblayer/browser/favicon/favicon_fetcher_impl.cc +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_fetcher_impl.h" - -#include "ui/gfx/image/image.h" -#include "weblayer/browser/favicon/favicon_tab_helper.h" -#include "weblayer/public/favicon_fetcher_delegate.h" - -#include "base/logging.h" - -namespace weblayer { - -FaviconFetcherImpl::FaviconFetcherImpl(content::WebContents* web_contents, - FaviconFetcherDelegate* delegate) - : web_contents_(web_contents), - observer_subscription_(FaviconTabHelper::FromWebContents(web_contents) - ->RegisterFaviconFetcherDelegate(delegate)) {} - -FaviconFetcherImpl::~FaviconFetcherImpl() = default; - -gfx::Image FaviconFetcherImpl::GetFavicon() { - return FaviconTabHelper::FromWebContents(web_contents_)->favicon(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_fetcher_impl.h b/weblayer/browser/favicon/favicon_fetcher_impl.h deleted file mode 100644 index 522a4d5..0000000 --- a/weblayer/browser/favicon/favicon_fetcher_impl.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_FAVICON_FETCHER_IMPL_H_ -#define WEBLAYER_BROWSER_FAVICON_FAVICON_FETCHER_IMPL_H_ - -#include <memory> - -#include "base/memory/raw_ptr.h" -#include "weblayer/browser/favicon/favicon_tab_helper.h" -#include "weblayer/public/favicon_fetcher.h" - -namespace content { -class WebContents; -} - -namespace weblayer { - -class FaviconFetcherDelegate; - -// FaviconFetcher implementation that largely delegates to FaviconTabHelper -// for the real implementation. -class FaviconFetcherImpl : public FaviconFetcher { - public: - FaviconFetcherImpl(content::WebContents* web_contents, - FaviconFetcherDelegate* delegate); - FaviconFetcherImpl(const FaviconFetcherImpl&) = delete; - FaviconFetcherImpl& operator=(const FaviconFetcherImpl&) = delete; - ~FaviconFetcherImpl() override; - - // FaviconFetcher: - gfx::Image GetFavicon() override; - - private: - raw_ptr<content::WebContents> web_contents_; - std::unique_ptr<FaviconTabHelper::ObserverSubscription> - observer_subscription_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_FAVICON_FETCHER_IMPL_H_
diff --git a/weblayer/browser/favicon/favicon_service_impl.cc b/weblayer/browser/favicon/favicon_service_impl.cc deleted file mode 100644 index 2e1959dc..0000000 --- a/weblayer/browser/favicon/favicon_service_impl.cc +++ /dev/null
@@ -1,264 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_service_impl.h" - -#include <stddef.h> - -#include <vector> - -#include "base/files/file_path.h" -#include "base/functional/bind.h" -#include "base/hash/hash.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" -#include "build/build_config.h" -#include "components/favicon_base/favicon_util.h" -#include "components/favicon_base/select_favicon_frames.h" -#include "content/public/common/url_constants.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/gfx/favicon_size.h" -#include "url/gurl.h" -#include "weblayer/browser/favicon/favicon_backend_wrapper.h" -#include "weblayer/browser/favicon/favicon_service_impl_observer.h" - -namespace weblayer { -namespace { - -bool CanAddUrl(const GURL& url) { - if (!url.is_valid()) - return false; - - if (url.SchemeIs(url::kJavaScriptScheme) || url.SchemeIs(url::kAboutScheme) || - url.SchemeIs(url::kContentScheme) || - url.SchemeIs(content::kChromeDevToolsScheme) || - url.SchemeIs(content::kChromeUIScheme) || - url.SchemeIs(content::kViewSourceScheme)) { - return false; - } - - return true; -} - -// Returns the IconTypeSet for the current platform. This matches the set -// of favicon types that are requested for the platform (see -// FaviconDriverImpl). -favicon_base::IconTypeSet GetIconTypeSet() { -#if BUILDFLAG(IS_ANDROID) - return {favicon_base::IconType::kFavicon, favicon_base::IconType::kTouchIcon, - favicon_base::IconType::kTouchPrecomposedIcon, - favicon_base::IconType::kWebManifestIcon}; -#else - return {favicon_base::IconType::kFavicon}; -#endif -} - -int GetDesiredFaviconSizeInDips() { -#if BUILDFLAG(IS_ANDROID) - // This is treatest as the largest available icon. - return 0; -#else - return gfx::kFaviconSize; -#endif -} - -void OnGotFaviconsForPageUrl( - int desired_size_in_dip, - base::OnceCallback<void(gfx::Image)> callback, - std::vector<favicon_base::FaviconRawBitmapResult> results) { - favicon_base::FaviconImageResult image_result; - image_result.image = favicon_base::SelectFaviconFramesFromPNGs( - results, favicon_base::GetFaviconScales(), desired_size_in_dip); - favicon_base::SetFaviconColorSpace(&image_result.image); - std::move(callback).Run(image_result.image); -} - -} // namespace - -FaviconServiceImpl::FaviconServiceImpl() = default; - -FaviconServiceImpl::~FaviconServiceImpl() { - backend_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::Shutdown, std::move(backend_))); -} - -void FaviconServiceImpl::Init(const base::FilePath& db_path) { - if (!backend_task_runner_) { - // BLOCK_SHUTDOWN matches that of HistoryService. It's done in hopes of - // preventing database corruption. - backend_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner( - {base::MayBlock(), base::WithBaseSyncPrimitives(), - base::TaskPriority::USER_BLOCKING, - base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); - } - - backend_ = base::MakeRefCounted<FaviconBackendWrapper>(backend_task_runner_); - - backend_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::Init, backend_, db_path)); -} - -void FaviconServiceImpl::DeleteAndRecreateDatabase(base::OnceClosure callback) { - backend_task_runner_->PostTaskAndReply( - FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::DeleteAndRecreateDatabase, - backend_), - std::move(callback)); -} - -base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageUrl( - const GURL& page_url, - base::OnceCallback<void(gfx::Image)> callback, - base::CancelableTaskTracker* tracker) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // The arguments supplied to this function should return an image matching - // that returned by FaviconFetcher. - return tracker->PostTaskAndReplyWithResult( - backend_task_runner_.get(), FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::GetFaviconsForUrl, backend_, - page_url, GetIconTypeSet(), - GetDesiredFaviconSizesInPixels()), - base::BindOnce(&OnGotFaviconsForPageUrl, GetDesiredFaviconSizeInDips(), - std::move(callback))); -} - -base::CancelableTaskTracker::TaskId -FaviconServiceImpl::GetLargestRawFaviconForPageURL( - const GURL& page_url, - const std::vector<favicon_base::IconTypeSet>& icon_types, - int minimum_size_in_pixels, - favicon_base::FaviconRawBitmapCallback callback, - base::CancelableTaskTracker* tracker) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return tracker->PostTaskAndReplyWithResult( - backend_task_runner_.get(), FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::GetLargestFaviconForUrl, backend_, - page_url, icon_types, minimum_size_in_pixels), - std::move(callback)); -} - -base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageURL( - const GURL& page_url, - const favicon_base::IconTypeSet& icon_types, - int desired_size_in_dip, - favicon_base::FaviconResultsCallback callback, - base::CancelableTaskTracker* tracker) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return tracker->PostTaskAndReplyWithResult( - backend_task_runner_.get(), FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::GetFaviconsForUrl, backend_, - page_url, icon_types, - GetPixelSizesForFaviconScales(desired_size_in_dip)), - std::move(callback)); -} - -void FaviconServiceImpl::SetFaviconOutOfDateForPage(const GURL& page_url) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - backend_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::SetFaviconsOutOfDateForPage, - backend_, page_url)); -} - -void FaviconServiceImpl::SetFavicons(const base::flat_set<GURL>& page_urls, - const GURL& icon_url, - favicon_base::IconType icon_type, - const gfx::Image& image) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::flat_set<GURL> page_urls_to_save; - page_urls_to_save.reserve(page_urls.capacity()); - for (const GURL& page_url : page_urls) { - if (CanAddUrl(page_url)) - page_urls_to_save.insert(page_url); - } - - if (page_urls_to_save.empty()) - return; - - backend_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&FaviconBackendWrapper::SetFavicons, backend_, - page_urls_to_save, icon_type, icon_url, - ExtractSkBitmapsToStore(image))); -} - -void FaviconServiceImpl::CloneFaviconMappingsForPages( - const GURL& page_url_to_read, - const favicon_base::IconTypeSet& icon_types, - const base::flat_set<GURL>& page_urls_to_write) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - backend_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::CloneFaviconMappingsForPages, - backend_, page_url_to_read, icon_types, - page_urls_to_write)); -} - -base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFavicon( - const GURL& icon_url, - favicon_base::IconType icon_type, - int desired_size_in_dip, - favicon_base::FaviconResultsCallback callback, - base::CancelableTaskTracker* tracker) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return tracker->PostTaskAndReplyWithResult( - backend_task_runner_.get(), FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::GetFavicon, backend_, icon_url, - icon_type, - GetPixelSizesForFaviconScales(desired_size_in_dip)), - std::move(callback)); -} - -base::CancelableTaskTracker::TaskId -FaviconServiceImpl::UpdateFaviconMappingsAndFetch( - const base::flat_set<GURL>& page_urls, - const GURL& icon_url, - favicon_base::IconType icon_type, - int desired_size_in_dip, - favicon_base::FaviconResultsCallback callback, - base::CancelableTaskTracker* tracker) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return tracker->PostTaskAndReplyWithResult( - backend_task_runner_.get(), FROM_HERE, - base::BindOnce(&FaviconBackendWrapper::UpdateFaviconMappingsAndFetch, - backend_, page_urls, icon_url, icon_type, - GetPixelSizesForFaviconScales(desired_size_in_dip)), - std::move(callback)); -} - -void FaviconServiceImpl::DeleteFaviconMappings( - const base::flat_set<GURL>& page_urls, - favicon_base::IconType icon_type) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - backend_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&FaviconBackendWrapper::DeleteFaviconMappings, - backend_, page_urls, icon_type)); -} - -void FaviconServiceImpl::UnableToDownloadFavicon(const GURL& icon_url) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - missing_favicon_urls_.insert(base::FastHash(icon_url.spec())); - if (observer_) - observer_->OnUnableToDownloadFavicon(); -} - -void FaviconServiceImpl::ClearUnableToDownloadFavicons() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - missing_favicon_urls_.clear(); -} - -bool FaviconServiceImpl::WasUnableToDownloadFavicon( - const GURL& icon_url) const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - MissingFaviconUrlHash url_hash = base::FastHash(icon_url.spec()); - return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end(); -} - -// static -std::vector<int> FaviconServiceImpl::GetDesiredFaviconSizesInPixels() { - return GetPixelSizesForFaviconScales(GetDesiredFaviconSizeInDips()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_service_impl.h b/weblayer/browser/favicon/favicon_service_impl.h deleted file mode 100644 index 7611112..0000000 --- a/weblayer/browser/favicon/favicon_service_impl.h +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_H_ -#define WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_H_ - -#include <unordered_set> - -#include "base/memory/raw_ptr.h" -#include "base/memory/ref_counted.h" -#include "base/sequence_checker.h" -#include "base/task/sequenced_task_runner.h" -#include "components/favicon/core/core_favicon_service.h" - -namespace base { -class FilePath; -} - -namespace weblayer { - -class FaviconBackendWrapper; -class FaviconServiceImplObserver; - -// FaviconServiceImpl provides the front end (ui side) access to the favicon -// database. Most functions are processed async on the backend task-runner. -class FaviconServiceImpl : public favicon::CoreFaviconService { - public: - FaviconServiceImpl(); - FaviconServiceImpl(const FaviconServiceImpl&) = delete; - FaviconServiceImpl& operator=(const FaviconServiceImpl&) = delete; - ~FaviconServiceImpl() override; - - void Init(const base::FilePath& db_path); - - void set_observer(FaviconServiceImplObserver* observer) { - observer_ = observer; - } - - // Deletes the database and recreates it, notifying |callback| when done. - void DeleteAndRecreateDatabase(base::OnceClosure callback); - - // Requests the favicon image for a url (page). The returned image matches - // that returned from FaviconFetcher. - base::CancelableTaskTracker::TaskId GetFaviconForPageUrl( - const GURL& page_url, - base::OnceCallback<void(gfx::Image)> callback, - base::CancelableTaskTracker* tracker); - base::CancelableTaskTracker::TaskId GetLargestRawFaviconForPageURL( - const GURL& page_url, - const std::vector<favicon_base::IconTypeSet>& icon_types, - int minimum_size_in_pixels, - favicon_base::FaviconRawBitmapCallback callback, - base::CancelableTaskTracker* tracker); - - // favicon::CoreFaviconService: - base::CancelableTaskTracker::TaskId GetFaviconForPageURL( - const GURL& page_url, - const favicon_base::IconTypeSet& icon_types, - int desired_size_in_dip, - favicon_base::FaviconResultsCallback callback, - base::CancelableTaskTracker* tracker) override; - void SetFaviconOutOfDateForPage(const GURL& page_url) override; - void SetFavicons(const base::flat_set<GURL>& page_urls, - const GURL& icon_url, - favicon_base::IconType icon_type, - const gfx::Image& image) override; - void CloneFaviconMappingsForPages( - const GURL& page_url_to_read, - const favicon_base::IconTypeSet& icon_types, - const base::flat_set<GURL>& page_urls_to_write) override; - base::CancelableTaskTracker::TaskId GetFavicon( - const GURL& icon_url, - favicon_base::IconType icon_type, - int desired_size_in_dip, - favicon_base::FaviconResultsCallback callback, - base::CancelableTaskTracker* tracker) override; - base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch( - const base::flat_set<GURL>& page_urls, - const GURL& icon_url, - favicon_base::IconType icon_type, - int desired_size_in_dip, - favicon_base::FaviconResultsCallback callback, - base::CancelableTaskTracker* tracker) override; - void DeleteFaviconMappings(const base::flat_set<GURL>& page_urls, - favicon_base::IconType icon_type) override; - void UnableToDownloadFavicon(const GURL& icon_url) override; - void ClearUnableToDownloadFavicons() override; - bool WasUnableToDownloadFavicon(const GURL& icon_url) const override; - - private: - using MissingFaviconUrlHash = size_t; - SEQUENCE_CHECKER(sequence_checker_); - - // Returns the desired favicon sizes for the current platform. - static std::vector<int> GetDesiredFaviconSizesInPixels(); - - // The TaskRunner to which FaviconServiceBackend tasks are posted. Nullptr - // once Cleanup() is called. - scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; - - scoped_refptr<FaviconBackendWrapper> backend_; - - // Hashes of the favicon urls that were unable to be downloaded. - std::unordered_set<MissingFaviconUrlHash> missing_favicon_urls_; - - // This is only used in tests, where only a single observer is necessary. - raw_ptr<FaviconServiceImplObserver> observer_ = nullptr; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_H_
diff --git a/weblayer/browser/favicon/favicon_service_impl_factory.cc b/weblayer/browser/favicon/favicon_service_impl_factory.cc deleted file mode 100644 index 35b243de..0000000 --- a/weblayer/browser/favicon/favicon_service_impl_factory.cc +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_service_impl_factory.h" - -#include "base/files/file_path.h" -#include "base/no_destructor.h" -#include "components/favicon/content/large_favicon_provider_getter.h" -#include "components/favicon/core/core_favicon_service.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/favicon/favicon_service_impl.h" - -namespace weblayer { - -// static -FaviconServiceImpl* FaviconServiceImplFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - if (!browser_context->IsOffTheRecord()) { - return static_cast<FaviconServiceImpl*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); - } - return nullptr; -} - -// static -FaviconServiceImplFactory* FaviconServiceImplFactory::GetInstance() { - static base::NoDestructor<FaviconServiceImplFactory> factory; - return factory.get(); -} - -FaviconServiceImplFactory::FaviconServiceImplFactory() - : BrowserContextKeyedServiceFactory( - "FaviconServiceImpl", - BrowserContextDependencyManager::GetInstance()) {} - -FaviconServiceImplFactory::~FaviconServiceImplFactory() = default; - -KeyedService* FaviconServiceImplFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - DCHECK(!context->IsOffTheRecord()); - std::unique_ptr<FaviconServiceImpl> service = - std::make_unique<FaviconServiceImpl>(); - service->Init(context->GetPath().AppendASCII("Favicons")); - return service.release(); -} - -bool FaviconServiceImplFactory::ServiceIsNULLWhileTesting() const { - return true; -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_service_impl_factory.h b/weblayer/browser/favicon/favicon_service_impl_factory.h deleted file mode 100644 index dd4e6fcf..0000000 --- a/weblayer/browser/favicon/favicon_service_impl_factory.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_FACTORY_H_ -#define WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -class FaviconServiceImpl; - -// BrowserContextKeyedServiceFactory for getting the FaviconServiceImpl. -class FaviconServiceImplFactory : public BrowserContextKeyedServiceFactory { - public: - FaviconServiceImplFactory(const FaviconServiceImplFactory&) = delete; - FaviconServiceImplFactory& operator=(const FaviconServiceImplFactory&) = - delete; - - // Off the record profiles do not have a FaviconServiceImpl. - static FaviconServiceImpl* GetForBrowserContext( - content::BrowserContext* browser_context); - - // Returns the FaviconServiceFactory singleton. - static FaviconServiceImplFactory* GetInstance(); - - private: - friend class base::NoDestructor<FaviconServiceImplFactory>; - - FaviconServiceImplFactory(); - ~FaviconServiceImplFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - bool ServiceIsNULLWhileTesting() const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_FACTORY_H_
diff --git a/weblayer/browser/favicon/favicon_service_impl_observer.h b/weblayer/browser/favicon/favicon_service_impl_observer.h deleted file mode 100644 index 995be259..0000000 --- a/weblayer/browser/favicon/favicon_service_impl_observer.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_OBSERVER_H_ -#define WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_OBSERVER_H_ - -namespace weblayer { - -class FaviconServiceImplObserver { - public: - // Called from FaviconServiceImpl::UnableToDownloadFavicon. - virtual void OnUnableToDownloadFavicon() {} - - protected: - virtual ~FaviconServiceImplObserver() = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_FAVICON_SERVICE_IMPL_OBSERVER_H_
diff --git a/weblayer/browser/favicon/favicon_tab_helper.cc b/weblayer/browser/favicon/favicon_tab_helper.cc deleted file mode 100644 index 455dab6..0000000 --- a/weblayer/browser/favicon/favicon_tab_helper.cc +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/favicon_tab_helper.h" - -#include "components/favicon/content/content_favicon_driver.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/favicon/favicon_service_impl.h" -#include "weblayer/browser/favicon/favicon_service_impl_factory.h" -#include "weblayer/public/favicon_fetcher_delegate.h" - -namespace weblayer { -namespace { - -bool IsSquareImage(const gfx::Image& image) { - return !image.IsEmpty() && image.Width() == image.Height(); -} - -// Returns true if |image_a| is better than |image_b|. A value of false means -// |image_a| is not better than |image_b|. Either image may be empty, if both -// are empty false is returned. -bool IsImageBetterThan(const gfx::Image& image_a, const gfx::Image& image_b) { - // Any image is better than an empty image. - if (!image_a.IsEmpty() && image_b.IsEmpty()) - return true; - - // Prefer square favicons as they will scale much better. - if (IsSquareImage(image_a) && !IsSquareImage(image_b)) - return true; - - return image_a.Width() > image_b.Width(); -} - -} // namespace - -FaviconTabHelper::ObserverSubscription::ObserverSubscription( - FaviconTabHelper* helper, - FaviconFetcherDelegate* delegate) - : helper_(helper), delegate_(delegate) { - helper_->AddDelegate(delegate_); -} - -FaviconTabHelper::ObserverSubscription::~ObserverSubscription() { - helper_->RemoveDelegate(delegate_); -} - -FaviconTabHelper::~FaviconTabHelper() { - // All of the ObserverSubscriptions should have been destroyed before this. - DCHECK_EQ(0, observer_count_); -} - -std::unique_ptr<FaviconTabHelper::ObserverSubscription> -FaviconTabHelper::RegisterFaviconFetcherDelegate( - FaviconFetcherDelegate* delegate) { - // WrapUnique as constructor is private. - return base::WrapUnique(new ObserverSubscription(this, delegate)); -} - -FaviconTabHelper::FaviconTabHelper(content::WebContents* contents) - : content::WebContentsUserData<FaviconTabHelper>(*contents), - WebContentsObserver(contents) {} - -void FaviconTabHelper::AddDelegate(FaviconFetcherDelegate* delegate) { - delegates_.AddObserver(delegate); - if (++observer_count_ == 1) { - FaviconServiceImpl* favicon_service = - FaviconServiceImplFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); - favicon::ContentFaviconDriver::CreateForWebContents(web_contents(), - favicon_service); - favicon::ContentFaviconDriver::FromWebContents(web_contents()) - ->AddObserver(this); - } -} - -void FaviconTabHelper::RemoveDelegate(FaviconFetcherDelegate* delegate) { - delegates_.RemoveObserver(delegate); - --observer_count_; - DCHECK_GE(observer_count_, 0); - if (observer_count_ == 0) { - favicon::ContentFaviconDriver::FromWebContents(web_contents()) - ->RemoveObserver(this); - // ContentFaviconDriver downloads images, if there are no observers there - // is no need to keep it around. This triggers deleting it. - web_contents()->SetUserData(favicon::ContentFaviconDriver::UserDataKey(), - nullptr); - favicon_ = gfx::Image(); - } -} - -void FaviconTabHelper::OnFaviconUpdated( - favicon::FaviconDriver* favicon_driver, - NotificationIconType notification_icon_type, - const GURL& icon_url, - bool icon_url_changed, - const gfx::Image& image) { - if (!IsImageBetterThan(image, favicon_)) - return; - - favicon_ = image; - for (FaviconFetcherDelegate& delegate : delegates_) - delegate.OnFaviconChanged(favicon_); -} - -void FaviconTabHelper::PrimaryPageChanged(content::Page& page) { - if (page.GetMainDocument().IsErrorDocument() || favicon_.IsEmpty()) { - return; - } - - favicon_ = gfx::Image(); - for (FaviconFetcherDelegate& delegate : delegates_) - delegate.OnFaviconChanged(favicon_); -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(FaviconTabHelper); - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/favicon_tab_helper.h b/weblayer/browser/favicon/favicon_tab_helper.h deleted file mode 100644 index 38bb3e8..0000000 --- a/weblayer/browser/favicon/favicon_tab_helper.h +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_FAVICON_TAB_HELPER_H_ -#define WEBLAYER_BROWSER_FAVICON_FAVICON_TAB_HELPER_H_ - -#include <memory> - -#include "base/memory/raw_ptr.h" -#include "base/observer_list.h" -#include "components/favicon/core/favicon_driver_observer.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "ui/gfx/image/image.h" - -namespace weblayer { - -class FaviconFetcherDelegate; - -// FaviconTabHelper is responsible for creating favicon::ContentFaviconDriver -// when necessary. FaviconTabHelper is used by FaviconFetcherImpl and notifies -// FaviconFetcherDelegate when the favicon changes. -class FaviconTabHelper : public content::WebContentsUserData<FaviconTabHelper>, - public content::WebContentsObserver, - public favicon::FaviconDriverObserver { - public: - // Used to track calls to RegisterFaviconFetcherDelegate(). When destroyed - // the FaviconFetcherDelegate is removed. - class ObserverSubscription { - public: - ObserverSubscription(const ObserverSubscription&) = delete; - ObserverSubscription& operator=(const ObserverSubscription&) = delete; - ~ObserverSubscription(); - - private: - friend class FaviconTabHelper; - - ObserverSubscription(FaviconTabHelper* helper, - FaviconFetcherDelegate* delegate); - - raw_ptr<FaviconTabHelper> helper_; - raw_ptr<FaviconFetcherDelegate> delegate_; - }; - - FaviconTabHelper(const FaviconTabHelper&) = delete; - FaviconTabHelper& operator=(const FaviconTabHelper&) = delete; - ~FaviconTabHelper() override; - - // Called when FaviconFetcherImpl is created. This ensures the necessary - // wiring is in place and notifies |delegate| when the favicon changes. - std::unique_ptr<ObserverSubscription> RegisterFaviconFetcherDelegate( - FaviconFetcherDelegate* delegate); - - // Returns the favicon for the current navigation. - const gfx::Image& favicon() const { return favicon_; } - - private: - friend class content::WebContentsUserData<FaviconTabHelper>; - - explicit FaviconTabHelper(content::WebContents* contents); - - void AddDelegate(FaviconFetcherDelegate* delegate); - void RemoveDelegate(FaviconFetcherDelegate* delegate); - - // favicon::FaviconDriverObserver: - void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, - NotificationIconType notification_icon_type, - const GURL& icon_url, - bool icon_url_changed, - const gfx::Image& image) override; - - // content::WebContentsObserver: - void PrimaryPageChanged(content::Page& page) override; - - raw_ptr<content::WebContents> web_contents_; - // Number of observers attached. - int observer_count_ = 0; - base::ObserverList<FaviconFetcherDelegate> delegates_; - gfx::Image favicon_; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_FAVICON_TAB_HELPER_H_
diff --git a/weblayer/browser/favicon/test_favicon_fetcher_delegate.cc b/weblayer/browser/favicon/test_favicon_fetcher_delegate.cc deleted file mode 100644 index 847e9ca..0000000 --- a/weblayer/browser/favicon/test_favicon_fetcher_delegate.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/favicon/test_favicon_fetcher_delegate.h" - -#include "base/run_loop.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace weblayer { - -TestFaviconFetcherDelegate::TestFaviconFetcherDelegate() = default; - -TestFaviconFetcherDelegate::~TestFaviconFetcherDelegate() = default; - -void TestFaviconFetcherDelegate::WaitForFavicon() { - ASSERT_EQ(nullptr, run_loop_.get()); - waiting_for_nonempty_image_ = false; - run_loop_ = std::make_unique<base::RunLoop>(); - run_loop_->Run(); - run_loop_.reset(); -} - -void TestFaviconFetcherDelegate::WaitForNonemptyFavicon() { - if (!last_image_.IsEmpty()) - return; - - run_loop_ = std::make_unique<base::RunLoop>(); - waiting_for_nonempty_image_ = true; - run_loop_->Run(); - run_loop_.reset(); -} - -void TestFaviconFetcherDelegate::ClearLastImage() { - last_image_ = gfx::Image(); - on_favicon_changed_call_count_ = 0; -} - -void TestFaviconFetcherDelegate::OnFaviconChanged(const gfx::Image& image) { - last_image_ = image; - ++on_favicon_changed_call_count_; - if (run_loop_ && (!waiting_for_nonempty_image_ || !image.IsEmpty())) - run_loop_->Quit(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/favicon/test_favicon_fetcher_delegate.h b/weblayer/browser/favicon/test_favicon_fetcher_delegate.h deleted file mode 100644 index a47b31d..0000000 --- a/weblayer/browser/favicon/test_favicon_fetcher_delegate.h +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FAVICON_TEST_FAVICON_FETCHER_DELEGATE_H_ -#define WEBLAYER_BROWSER_FAVICON_TEST_FAVICON_FETCHER_DELEGATE_H_ - -#include <memory> - -#include "ui/gfx/image/image.h" -#include "weblayer/public/favicon_fetcher_delegate.h" - -namespace base { -class RunLoop; -} - -namespace weblayer { - -// Records calls to OnFaviconChanged(). -class TestFaviconFetcherDelegate : public FaviconFetcherDelegate { - public: - TestFaviconFetcherDelegate(); - TestFaviconFetcherDelegate(const TestFaviconFetcherDelegate&) = delete; - TestFaviconFetcherDelegate& operator=(const TestFaviconFetcherDelegate&) = - delete; - ~TestFaviconFetcherDelegate() override; - - // Waits for OnFaviconChanged() to be called. - void WaitForFavicon(); - - // Waits for a non-empty favicon. This returns immediately if a non-empty - // image was supplied to OnFaviconChanged() and ClearLastImage() hasn't been - // called. - void WaitForNonemptyFavicon(); - - void ClearLastImage(); - - const gfx::Image& last_image() const { return last_image_; } - int on_favicon_changed_call_count() const { - return on_favicon_changed_call_count_; - } - - // FaviconFetcherDelegate: - void OnFaviconChanged(const gfx::Image& image) override; - - private: - std::unique_ptr<base::RunLoop> run_loop_; - gfx::Image last_image_; - bool waiting_for_nonempty_image_ = false; - int on_favicon_changed_call_count_ = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FAVICON_TEST_FAVICON_FETCHER_DELEGATE_H_
diff --git a/weblayer/browser/feature_list_creator.cc b/weblayer/browser/feature_list_creator.cc deleted file mode 100644 index c353807..0000000 --- a/weblayer/browser/feature_list_creator.cc +++ /dev/null
@@ -1,125 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/feature_list_creator.h" - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "build/build_config.h" -#include "components/metrics/metrics_state_manager.h" -#include "components/prefs/pref_service.h" -#include "components/variations/service/variations_service.h" -#include "components/variations/variations_crash_keys.h" -#include "components/variations/variations_switches.h" -#include "content/public/browser/network_service_instance.h" -#include "content/public/common/content_switch_dependent_feature_overrides.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "weblayer/browser/system_network_context_manager.h" -#include "weblayer/browser/weblayer_variations_service_client.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" -#endif - -#if BUILDFLAG(IS_ANDROID) -namespace switches { -const char kDisableBackgroundNetworking[] = "disable-background-networking"; -} // namespace switches -#endif - -namespace weblayer { -namespace { - -FeatureListCreator* feature_list_creator_instance = nullptr; - -} // namespace - -FeatureListCreator::FeatureListCreator(PrefService* local_state) - : local_state_(local_state) { - DCHECK(local_state_); - DCHECK(!feature_list_creator_instance); - feature_list_creator_instance = this; -} - -FeatureListCreator::~FeatureListCreator() { - feature_list_creator_instance = nullptr; -} - -// static -FeatureListCreator* FeatureListCreator::GetInstance() { - DCHECK(feature_list_creator_instance); - return feature_list_creator_instance; -} - -void FeatureListCreator::SetSystemNetworkContextManager( - SystemNetworkContextManager* system_network_context_manager) { - system_network_context_manager_ = system_network_context_manager; -} - -void FeatureListCreator::CreateFeatureListAndFieldTrials() { -#if BUILDFLAG(IS_ANDROID) - WebLayerMetricsServiceClient::GetInstance()->Initialize(local_state_); -#endif - SetUpFieldTrials(); -} - -void FeatureListCreator::PerformPreMainMessageLoopStartup() { -#if BUILDFLAG(IS_ANDROID) - // It is expected this is called after SetUpFieldTrials(). - DCHECK(variations_service_); - variations_service_->PerformPreMainMessageLoopStartup(); -#endif -} - -void FeatureListCreator::OnBrowserCreated() { - if (has_browser_created_) { - return; - } - - has_browser_created_ = true; - // It is expected this is called after SetUpFieldTrials(). - DCHECK(variations_service_); - - // This function is called any time a Browser is started. - // OnAppEnterForeground() really need only be called once, and because our - // notion of a browser doesn't really map to the Application as a whole, - // call this function once. - variations_service_->OnAppEnterForeground(); -} - -void FeatureListCreator::SetUpFieldTrials() { -#if BUILDFLAG(IS_ANDROID) - // The FieldTrialList should have been instantiated in - // AndroidMetricsServiceClient::Initialize(). - DCHECK(base::FieldTrialList::GetInstance()); - DCHECK(system_network_context_manager_); - - auto* metrics_client = WebLayerMetricsServiceClient::GetInstance(); - variations_service_ = variations::VariationsService::Create( - std::make_unique<WebLayerVariationsServiceClient>( - system_network_context_manager_), - local_state_, metrics_client->metrics_state_manager(), - switches::kDisableBackgroundNetworking, variations::UIStringOverrider(), - base::BindOnce(&content::GetNetworkConnectionTracker)); - variations_service_->OverridePlatform( - variations::Study::PLATFORM_ANDROID_WEBLAYER, "android_weblayer"); - - std::vector<std::string> variation_ids; - auto feature_list = std::make_unique<base::FeatureList>(); - - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - variations_service_->SetUpFieldTrials( - variation_ids, - command_line->GetSwitchValueASCII( - variations::switches::kForceVariationIds), - content::GetSwitchDependentFeatureOverrides(*command_line), - std::move(feature_list), &weblayer_field_trials_); - variations::InitCrashKeys(); -#else - // TODO(weblayer-dev): Support variations on desktop. -#endif -} - -} // namespace weblayer
diff --git a/weblayer/browser/feature_list_creator.h b/weblayer/browser/feature_list_creator.h deleted file mode 100644 index 8ed788a5..0000000 --- a/weblayer/browser/feature_list_creator.h +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FEATURE_LIST_CREATOR_H_ -#define WEBLAYER_BROWSER_FEATURE_LIST_CREATOR_H_ - -#include <memory> - -#include "base/memory/raw_ptr.h" -#include "weblayer/browser/weblayer_field_trials.h" - -class PrefService; - -namespace variations { -class VariationsService; -} - -namespace weblayer { -class SystemNetworkContextManager; - -// Used by WebLayer to set up field trials based on the stored variations -// seed data. Once created this object must exist for the lifetime of the -// process as it contains the FieldTrialList that can be queried for the state -// of experiments. -class FeatureListCreator { - public: - explicit FeatureListCreator(PrefService* local_state); - FeatureListCreator(const FeatureListCreator&) = delete; - FeatureListCreator& operator=(const FeatureListCreator&) = delete; - ~FeatureListCreator(); - - // Return the single instance of FeatureListCreator. This does *not* trigger - // creation. - static FeatureListCreator* GetInstance(); - - void SetSystemNetworkContextManager( - SystemNetworkContextManager* system_network_context_manager); - - // Must be called after SetSharedURLLoaderFactory. - void CreateFeatureListAndFieldTrials(); - - // Called from content::BrowserMainParts::PreMainMessageLoopRun() to perform - // initialization necessary prior to running the main message loop. - void PerformPreMainMessageLoopStartup(); - - // Calls through to the VariationService. - void OnBrowserCreated(); - - variations::VariationsService* variations_service() const { - return variations_service_.get(); - } - - private: - void SetUpFieldTrials(); - - // Owned by BrowserProcess. - raw_ptr<PrefService> local_state_; - - raw_ptr<SystemNetworkContextManager> - system_network_context_manager_; // NOT OWNED. - - std::unique_ptr<variations::VariationsService> variations_service_; - - WebLayerFieldTrials weblayer_field_trials_; - - // Set to true the first time OnBrowserCreated() is called. - bool has_browser_created_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FEATURE_LIST_CREATOR_H_
diff --git a/weblayer/browser/file_select_helper.cc b/weblayer/browser/file_select_helper.cc deleted file mode 100644 index c7fd8dc0..0000000 --- a/weblayer/browser/file_select_helper.cc +++ /dev/null
@@ -1,182 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/file_select_helper.h" - -#include <string> - -#include "build/build_config.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "ui/shell_dialogs/select_file_policy.h" -#include "ui/shell_dialogs/selected_file_info.h" - -#if BUILDFLAG(IS_ANDROID) -#include "ui/android/view_android.h" -#else -#include "ui/aura/window.h" -#endif - -namespace weblayer { -using blink::mojom::FileChooserFileInfo; -using blink::mojom::FileChooserFileInfoPtr; -using blink::mojom::FileChooserParams; -using blink::mojom::FileChooserParamsPtr; - -// static -void FileSelectHelper::RunFileChooser( - content::RenderFrameHost* render_frame_host, - scoped_refptr<content::FileSelectListener> listener, - const FileChooserParams& params) { - // TODO: Should we handle text/json+contacts accept type? - - // FileSelectHelper will keep itself alive until it sends the result - // message. - scoped_refptr<FileSelectHelper> file_select_helper(new FileSelectHelper()); - file_select_helper->RunFileChooser(render_frame_host, std::move(listener), - params.Clone()); -} - -FileSelectHelper::FileSelectHelper() = default; - -FileSelectHelper::~FileSelectHelper() { - // There may be pending file dialogs, we need to tell them that we've gone - // away so they don't try and call back to us. - if (select_file_dialog_) - select_file_dialog_->ListenerDestroyed(); -} - -void FileSelectHelper::RunFileChooser( - content::RenderFrameHost* render_frame_host, - scoped_refptr<content::FileSelectListener> listener, - FileChooserParamsPtr params) { - DCHECK(!web_contents_); - DCHECK(listener); - DCHECK(!listener_); - DCHECK(!select_file_dialog_); - - listener_ = std::move(listener); - web_contents_ = content::WebContents::FromRenderFrameHost(render_frame_host) - ->GetWeakPtr(); - - select_file_dialog_ = ui::SelectFileDialog::Create(this, nullptr); - - dialog_mode_ = params->mode; - switch (params->mode) { - case FileChooserParams::Mode::kOpen: - dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; - break; - case FileChooserParams::Mode::kOpenMultiple: - dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; - break; - case FileChooserParams::Mode::kUploadFolder: - // For now we don't support inputs with webkitdirectory in weblayer. - dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; - break; - case FileChooserParams::Mode::kSave: - dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE; - break; - default: - // Prevent warning. - dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; - NOTREACHED(); - } - - gfx::NativeWindow owning_window; -#if BUILDFLAG(IS_ANDROID) - owning_window = web_contents_->GetNativeView()->GetWindowAndroid(); -#else - owning_window = web_contents_->GetNativeView()->GetToplevelWindow(); -#endif - -#if BUILDFLAG(IS_ANDROID) - // Android needs the original MIME types and an additional capture value. - std::pair<std::vector<std::u16string>, bool> accept_types = - std::make_pair(params->accept_types, params->use_media_capture); -#endif - - // Many of these params are not used in the Android SelectFileDialog - // implementation, so we can safely pass empty values. - select_file_dialog_->SelectFile(dialog_type_, std::u16string(), - base::FilePath(), nullptr, 0, - base::FilePath::StringType(), owning_window, -#if BUILDFLAG(IS_ANDROID) - &accept_types); -#else - nullptr); -#endif - - // Because this class returns notifications to the RenderViewHost, it is - // difficult for callers to know how long to keep a reference to this - // instance. We AddRef() here to keep the instance alive after we return - // to the caller, until the last callback is received from the file dialog. - // At that point, we must call RunFileChooserEnd(). - AddRef(); -} - -void FileSelectHelper::RunFileChooserEnd() { - if (listener_) - listener_->FileSelectionCanceled(); - - select_file_dialog_->ListenerDestroyed(); - select_file_dialog_.reset(); - Release(); -} - -void FileSelectHelper::FileSelected(const base::FilePath& path, - int index, - void* params) { - FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params); -} - -void FileSelectHelper::FileSelectedWithExtraInfo( - const ui::SelectedFileInfo& file, - int index, - void* params) { - ConvertToFileChooserFileInfoList({file}); -} - -void FileSelectHelper::MultiFilesSelected( - const std::vector<base::FilePath>& files, - void* params) { - std::vector<ui::SelectedFileInfo> selected_files = - ui::FilePathListToSelectedFileInfoList(files); - - MultiFilesSelectedWithExtraInfo(selected_files, params); -} - -void FileSelectHelper::MultiFilesSelectedWithExtraInfo( - const std::vector<ui::SelectedFileInfo>& files, - void* params) { - ConvertToFileChooserFileInfoList(files); -} - -void FileSelectHelper::FileSelectionCanceled(void* params) { - RunFileChooserEnd(); -} - -void FileSelectHelper::ConvertToFileChooserFileInfoList( - const std::vector<ui::SelectedFileInfo>& files) { - if (!web_contents_) { - RunFileChooserEnd(); - return; - } - - std::vector<FileChooserFileInfoPtr> chooser_files; - for (const auto& file : files) { - chooser_files.push_back( - FileChooserFileInfo::NewNativeFile(blink::mojom::NativeFileInfo::New( - file.local_path, - base::FilePath(file.display_name).AsUTF16Unsafe()))); - } - - listener_->FileSelected(std::move(chooser_files), base::FilePath(), - dialog_mode_); - listener_ = nullptr; - - // No members should be accessed from here on. - RunFileChooserEnd(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/file_select_helper.h b/weblayer/browser/file_select_helper.h deleted file mode 100644 index 37d3fef..0000000 --- a/weblayer/browser/file_select_helper.h +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FILE_SELECT_HELPER_H_ -#define WEBLAYER_BROWSER_FILE_SELECT_HELPER_H_ - -#include <memory> -#include <vector> - -#include "base/memory/weak_ptr.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/file_select_listener.h" -#include "ui/shell_dialogs/select_file_dialog.h" - -namespace content { -class FileSelectListener; -class RenderFrameHost; -class WebContents; -} // namespace content - -namespace ui { -struct SelectedFileInfo; -} - -namespace weblayer { - -// This class handles file-selection requests coming from renderer processes. -// It implements both the initialisation and listener functions for -// file-selection dialogs. -// -// Since FileSelectHelper listens to observations of a widget, it needs to live -// on and be destroyed on the UI thread. References to FileSelectHelper may be -// passed on to other threads. -class FileSelectHelper : public base::RefCountedThreadSafe< - FileSelectHelper, - content::BrowserThread::DeleteOnUIThread>, - public ui::SelectFileDialog::Listener { - public: - FileSelectHelper(const FileSelectHelper&) = delete; - FileSelectHelper& operator=(const FileSelectHelper&) = delete; - - // Show the file chooser dialog. - static void RunFileChooser( - content::RenderFrameHost* render_frame_host, - scoped_refptr<content::FileSelectListener> listener, - const blink::mojom::FileChooserParams& params); - - private: - friend class base::RefCountedThreadSafe<FileSelectHelper>; - friend class base::DeleteHelper<FileSelectHelper>; - friend struct content::BrowserThread::DeleteOnThread< - content::BrowserThread::UI>; - - FileSelectHelper(); - ~FileSelectHelper() override; - - void RunFileChooser(content::RenderFrameHost* render_frame_host, - scoped_refptr<content::FileSelectListener> listener, - blink::mojom::FileChooserParamsPtr params); - - // Cleans up and releases this instance. This must be called after the last - // callback is received from the file chooser dialog. - void RunFileChooserEnd(); - - // SelectFileDialog::Listener overrides. - void FileSelected(const base::FilePath& path, - int index, - void* params) override; - void FileSelectedWithExtraInfo(const ui::SelectedFileInfo& file, - int index, - void* params) override; - void MultiFilesSelected(const std::vector<base::FilePath>& files, - void* params) override; - void MultiFilesSelectedWithExtraInfo( - const std::vector<ui::SelectedFileInfo>& files, - void* params) override; - void FileSelectionCanceled(void* params) override; - - // This method is called after the user has chosen the file(s) in the UI in - // order to process and filter the list before returning the final result to - // the caller. - void ConvertToFileChooserFileInfoList( - const std::vector<ui::SelectedFileInfo>& files); - - // A weak pointer to the WebContents of the RenderFrameHost, for life checks. - base::WeakPtr<content::WebContents> web_contents_; - - // |listener_| receives the result of the FileSelectHelper. - scoped_refptr<content::FileSelectListener> listener_; - - // Dialog box used for choosing files to upload from file form fields. - scoped_refptr<ui::SelectFileDialog> select_file_dialog_; - - // The type of file dialog last shown. - ui::SelectFileDialog::Type dialog_type_ = - ui::SelectFileDialog::SELECT_OPEN_FILE; - - // The mode of file dialog last shown. - blink::mojom::FileChooserParams::Mode dialog_mode_ = - blink::mojom::FileChooserParams::Mode::kOpen; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FILE_SELECT_HELPER_H_
diff --git a/weblayer/browser/fullscreen_browsertest.cc b/weblayer/browser/fullscreen_browsertest.cc deleted file mode 100644 index 9aca8bd4..0000000 --- a/weblayer/browser/fullscreen_browsertest.cc +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/functional/callback.h" -#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/browser.h" -#include "weblayer/public/fullscreen_delegate.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -using FullscreenBrowserTest = WebLayerBrowserTest; - -class FullscreenDelegateImpl : public FullscreenDelegate { - public: - bool got_enter() const { return got_enter_; } - bool got_exit() const { return got_exit_; } - - void ResetState() { got_enter_ = got_exit_ = false; } - - // FullscreenDelegate: - void EnterFullscreen(base::OnceClosure exit_closure) override { - got_enter_ = true; - } - void ExitFullscreen() override { got_exit_ = true; } - - private: - bool got_enter_ = false; - bool got_exit_ = false; -}; - -IN_PROC_BROWSER_TEST_F(FullscreenBrowserTest, EnterFromBackgroundTab) { - EXPECT_TRUE(embedded_test_server()->Start()); - - TabImpl* tab1 = static_cast<TabImpl*>(shell()->tab()); - Browser* browser = tab1->GetBrowser(); - TabImpl* tab2 = static_cast<TabImpl*>(browser->CreateTab()); - EXPECT_NE(tab2, browser->GetActiveTab()); - FullscreenDelegateImpl fullscreen_delegate; - tab2->SetFullscreenDelegate(&fullscreen_delegate); - - // As `tab2` is in the background, the delegate should not be notified. - static_cast<content::WebContentsDelegate*>(tab2)->EnterFullscreenModeForTab( - nullptr, blink::mojom::FullscreenOptions()); - EXPECT_TRUE(static_cast<content::WebContentsDelegate*>(tab2) - ->IsFullscreenForTabOrPending(nullptr)); - EXPECT_FALSE(fullscreen_delegate.got_enter()); - - // Making the tab active should trigger the going fullscreen. - browser->SetActiveTab(tab2); - EXPECT_TRUE(static_cast<content::WebContentsDelegate*>(tab2) - ->IsFullscreenForTabOrPending(nullptr)); - EXPECT_TRUE(fullscreen_delegate.got_enter()); - - tab2->SetFullscreenDelegate(nullptr); -} - -IN_PROC_BROWSER_TEST_F(FullscreenBrowserTest, NoExitForBackgroundTab) { - EXPECT_TRUE(embedded_test_server()->Start()); - - Browser* browser = shell()->tab()->GetBrowser(); - TabImpl* tab = static_cast<TabImpl*>(browser->CreateTab()); - EXPECT_NE(tab, browser->GetActiveTab()); - FullscreenDelegateImpl fullscreen_delegate; - tab->SetFullscreenDelegate(&fullscreen_delegate); - - // As `tab` is in the background, the delegate should not be notified. - static_cast<content::WebContentsDelegate*>(tab)->EnterFullscreenModeForTab( - nullptr, blink::mojom::FullscreenOptions()); - EXPECT_TRUE(static_cast<content::WebContentsDelegate*>(tab) - ->IsFullscreenForTabOrPending(nullptr)); - EXPECT_FALSE(fullscreen_delegate.got_enter()); - EXPECT_TRUE(static_cast<content::WebContentsDelegate*>(tab) - ->IsFullscreenForTabOrPending(nullptr)); - EXPECT_FALSE(fullscreen_delegate.got_enter()); - EXPECT_FALSE(fullscreen_delegate.got_exit()); - fullscreen_delegate.ResetState(); - - // Simulate exiting. As the delegate wasn't told about the enter, it should - // not be told about the exit. - static_cast<content::WebContentsDelegate*>(tab)->ExitFullscreenModeForTab( - nullptr); - EXPECT_FALSE(static_cast<content::WebContentsDelegate*>(tab) - ->IsFullscreenForTabOrPending(nullptr)); - EXPECT_FALSE(fullscreen_delegate.got_enter()); - EXPECT_FALSE(fullscreen_delegate.got_exit()); - - tab->SetFullscreenDelegate(nullptr); -} - -IN_PROC_BROWSER_TEST_F(FullscreenBrowserTest, DelegateNotCalledMoreThanOnce) { - EXPECT_TRUE(embedded_test_server()->Start()); - - // The tab needs to be made active as fullscreen requests for inactive tabs - // are ignored. - TabImpl* tab = static_cast<TabImpl*>(shell()->tab()); - tab->GetBrowser()->SetActiveTab(tab); - - FullscreenDelegateImpl fullscreen_delegate; - tab->SetFullscreenDelegate(&fullscreen_delegate); - static_cast<content::WebContentsDelegate*>(tab)->EnterFullscreenModeForTab( - nullptr, blink::mojom::FullscreenOptions()); - EXPECT_TRUE(static_cast<content::WebContentsDelegate*>(tab) - ->IsFullscreenForTabOrPending(nullptr)); - EXPECT_TRUE(fullscreen_delegate.got_enter()); - EXPECT_FALSE(fullscreen_delegate.got_exit()); - fullscreen_delegate.ResetState(); - - // Simulate another enter. As the tab is already fullscreen the delegate - // should not be notified again. - static_cast<content::WebContentsDelegate*>(tab)->EnterFullscreenModeForTab( - nullptr, blink::mojom::FullscreenOptions()); - EXPECT_TRUE(static_cast<content::WebContentsDelegate*>(tab) - ->IsFullscreenForTabOrPending(nullptr)); - EXPECT_FALSE(fullscreen_delegate.got_enter()); - EXPECT_FALSE(fullscreen_delegate.got_exit()); - - tab->SetFullscreenDelegate(nullptr); -} - -} // namespace weblayer
diff --git a/weblayer/browser/fullscreen_callback_proxy.cc b/weblayer/browser/fullscreen_callback_proxy.cc deleted file mode 100644 index c75fd2e..0000000 --- a/weblayer/browser/fullscreen_callback_proxy.cc +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/fullscreen_callback_proxy.h" - -#include "base/android/jni_string.h" -#include "base/trace_event/trace_event.h" -#include "url/gurl.h" -#include "weblayer/browser/java/jni/FullscreenCallbackProxy_jni.h" -#include "weblayer/browser/tab_impl.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertUTF8ToJavaString; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -FullscreenCallbackProxy::FullscreenCallbackProxy(JNIEnv* env, - jobject obj, - Tab* tab) - : tab_(tab), java_delegate_(env, obj) { - tab_->SetFullscreenDelegate(this); -} - -FullscreenCallbackProxy::~FullscreenCallbackProxy() { - tab_->SetFullscreenDelegate(nullptr); -} - -void FullscreenCallbackProxy::EnterFullscreen(base::OnceClosure exit_closure) { - exit_fullscreen_closure_ = std::move(exit_closure); - TRACE_EVENT0("weblayer", "Java_FullscreenCallbackProxy_enterFullscreen"); - Java_FullscreenCallbackProxy_enterFullscreen(AttachCurrentThread(), - java_delegate_); -} - -void FullscreenCallbackProxy::ExitFullscreen() { - TRACE_EVENT0("weblayer", "Java_FullscreenCallbackProxy_exitFullscreen"); - // If the web contents initiated the fullscreen exit, the closure will still - // be valid, so clean it up now. - exit_fullscreen_closure_.Reset(); - Java_FullscreenCallbackProxy_exitFullscreen(AttachCurrentThread(), - java_delegate_); -} - -void FullscreenCallbackProxy::DoExitFullscreen(JNIEnv* env) { - if (exit_fullscreen_closure_) - std::move(exit_fullscreen_closure_).Run(); -} - -static jlong JNI_FullscreenCallbackProxy_CreateFullscreenCallbackProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong tab) { - return reinterpret_cast<jlong>( - new FullscreenCallbackProxy(env, proxy, reinterpret_cast<TabImpl*>(tab))); -} - -static void JNI_FullscreenCallbackProxy_DeleteFullscreenCallbackProxy( - JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<FullscreenCallbackProxy*>(proxy); -} - -} // namespace weblayer
diff --git a/weblayer/browser/fullscreen_callback_proxy.h b/weblayer/browser/fullscreen_callback_proxy.h deleted file mode 100644 index 7a39690..0000000 --- a/weblayer/browser/fullscreen_callback_proxy.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_FULLSCREEN_CALLBACK_PROXY_H_ -#define WEBLAYER_BROWSER_FULLSCREEN_CALLBACK_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "weblayer/public/fullscreen_delegate.h" - -namespace weblayer { - -class Tab; - -// FullscreenCallbackProxy forwards all FullscreenDelegate functions to the -// Java side. There is at most one FullscreenCallbackProxy per -// Tab. -class FullscreenCallbackProxy : public FullscreenDelegate { - public: - FullscreenCallbackProxy(JNIEnv* env, jobject obj, Tab* tab); - - FullscreenCallbackProxy(const FullscreenCallbackProxy&) = delete; - FullscreenCallbackProxy& operator=(const FullscreenCallbackProxy&) = delete; - - ~FullscreenCallbackProxy() override; - - // FullscreenDelegate: - void EnterFullscreen(base::OnceClosure exit_closure) override; - void ExitFullscreen() override; - - // Called from the Java side to exit fullscreen. - void DoExitFullscreen(JNIEnv* env); - - private: - raw_ptr<Tab> tab_; - base::android::ScopedJavaGlobalRef<jobject> java_delegate_; - base::OnceClosure exit_fullscreen_closure_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_FULLSCREEN_CALLBACK_PROXY_H_
diff --git a/weblayer/browser/google_account_access_token_fetcher_proxy.cc b/weblayer/browser/google_account_access_token_fetcher_proxy.cc deleted file mode 100644 index c4eda70..0000000 --- a/weblayer/browser/google_account_access_token_fetcher_proxy.cc +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/google_account_access_token_fetcher_proxy.h" - -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "weblayer/browser/java/jni/GoogleAccountAccessTokenFetcherProxy_jni.h" -#include "weblayer/browser/profile_impl.h" - -namespace weblayer { - -GoogleAccountAccessTokenFetcherProxy::GoogleAccountAccessTokenFetcherProxy( - JNIEnv* env, - jobject obj, - Profile* profile) - : java_delegate_(env, obj), profile_(profile) { - profile_->SetGoogleAccountAccessTokenFetchDelegate(this); -} - -GoogleAccountAccessTokenFetcherProxy::~GoogleAccountAccessTokenFetcherProxy() { - profile_->SetGoogleAccountAccessTokenFetchDelegate(nullptr); -} - -void GoogleAccountAccessTokenFetcherProxy::FetchAccessToken( - const std::set<std::string>& scopes, - OnTokenFetchedCallback callback) { - JNIEnv* env = base::android::AttachCurrentThread(); - std::vector<std::string> scopes_as_vector(scopes.begin(), scopes.end()); - - // Copy |callback| on the heap to pass the pointer through JNI. This callback - // will be deleted when it's run. - jlong callback_id = - reinterpret_cast<jlong>(new OnTokenFetchedCallback(std::move(callback))); - - Java_GoogleAccountAccessTokenFetcherProxy_fetchAccessToken( - env, java_delegate_, - base::android::ToJavaArrayOfStrings(env, scopes_as_vector), - reinterpret_cast<jlong>(callback_id)); -} - -void GoogleAccountAccessTokenFetcherProxy::OnAccessTokenIdentifiedAsInvalid( - const std::set<std::string>& scopes, - const std::string& token) { - JNIEnv* env = base::android::AttachCurrentThread(); - std::vector<std::string> scopes_as_vector(scopes.begin(), scopes.end()); - - Java_GoogleAccountAccessTokenFetcherProxy_onAccessTokenIdentifiedAsInvalid( - env, java_delegate_, - base::android::ToJavaArrayOfStrings(env, scopes_as_vector), - base::android::ConvertUTF8ToJavaString(env, token)); -} - -static jlong -JNI_GoogleAccountAccessTokenFetcherProxy_CreateGoogleAccountAccessTokenFetcherProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong profile) { - return reinterpret_cast<jlong>(new GoogleAccountAccessTokenFetcherProxy( - env, proxy, reinterpret_cast<ProfileImpl*>(profile))); -} - -static void -JNI_GoogleAccountAccessTokenFetcherProxy_DeleteGoogleAccountAccessTokenFetcherProxy( - JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<GoogleAccountAccessTokenFetcherProxy*>(proxy); -} - -static void JNI_GoogleAccountAccessTokenFetcherProxy_RunOnTokenFetchedCallback( - JNIEnv* env, - jlong callback_id, - const base::android::JavaParamRef<jstring>& token) { - std::unique_ptr<OnTokenFetchedCallback> cb( - reinterpret_cast<OnTokenFetchedCallback*>(callback_id)); - std::move(*cb).Run(base::android::ConvertJavaStringToUTF8(env, token)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/google_account_access_token_fetcher_proxy.h b/weblayer/browser/google_account_access_token_fetcher_proxy.h deleted file mode 100644 index 3777a9d..0000000 --- a/weblayer/browser/google_account_access_token_fetcher_proxy.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_GOOGLE_ACCOUNT_ACCESS_TOKEN_FETCHER_PROXY_H_ -#define WEBLAYER_BROWSER_GOOGLE_ACCOUNT_ACCESS_TOKEN_FETCHER_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "weblayer/public/google_account_access_token_fetch_delegate.h" - -namespace weblayer { - -class Profile; - -// Forwards GoogleAccountAccessTokenFetchDelegate calls to the java-side -// GoogleAccountAccessTokenFetcherProxy. -class GoogleAccountAccessTokenFetcherProxy - : public GoogleAccountAccessTokenFetchDelegate { - public: - GoogleAccountAccessTokenFetcherProxy(JNIEnv* env, - jobject obj, - Profile* profile); - ~GoogleAccountAccessTokenFetcherProxy() override; - - GoogleAccountAccessTokenFetcherProxy( - const GoogleAccountAccessTokenFetcherProxy&) = delete; - GoogleAccountAccessTokenFetcherProxy& operator=( - const GoogleAccountAccessTokenFetcherProxy&) = delete; - - // GoogleAccountAccessTokenFetchDelegate: - void FetchAccessToken(const std::set<std::string>& scopes, - OnTokenFetchedCallback callback) override; - void OnAccessTokenIdentifiedAsInvalid(const std::set<std::string>& scopes, - const std::string& token) override; - - private: - base::android::ScopedJavaGlobalRef<jobject> java_delegate_; - raw_ptr<Profile> profile_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_GOOGLE_ACCOUNT_ACCESS_TOKEN_FETCHER_PROXY_H_
diff --git a/weblayer/browser/google_accounts_browsertest.cc b/weblayer/browser/google_accounts_browsertest.cc deleted file mode 100644 index 85a65ca..0000000 --- a/weblayer/browser/google_accounts_browsertest.cc +++ /dev/null
@@ -1,231 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/escape.h" -#include "base/strings/strcat.h" -#include "components/signin/core/browser/signin_header_helper.h" -#include "google_apis/gaia/gaia_switches.h" -#include "google_apis/gaia/gaia_urls.h" -#include "net/base/url_util.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/default_handlers.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/signin_url_loader_throttle.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/google_accounts_delegate.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { -namespace { -constexpr char kGaiaDomain[] = "fakegaia.com"; -constexpr char kGoogleAccountsPath[] = "/manageaccounts"; -constexpr char kGoogleAccountsRedirectPath[] = "/manageaccounts-redirect"; -} // namespace - -class GoogleAccountsBrowserTest : public WebLayerBrowserTest, - public GoogleAccountsDelegate { - public: - // WebLayerBrowserTest: - void SetUpOnMainThread() override { - host_resolver()->AddRule("*", "127.0.0.1"); - shell()->tab()->SetGoogleAccountsDelegate(this); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - https_server_.RegisterRequestHandler(base::BindRepeating( - &GoogleAccountsBrowserTest::HandleGoogleAccountsRequest, - base::Unretained(this))); - net::test_server::RegisterDefaultHandlers(&https_server_); - ASSERT_TRUE(https_server_.Start()); - command_line->AppendSwitchASCII(switches::kGaiaUrl, GetGaiaURL("/").spec()); - command_line->AppendSwitch("ignore-certificate-errors"); - } - - // GoogleAccountsDelegate: - void OnGoogleAccountsRequest( - const signin::ManageAccountsParams& params) override { - params_ = params; - if (run_loop_) - run_loop_->Quit(); - } - - std::string GetGaiaId() override { return ""; } - - const signin::ManageAccountsParams& WaitForGoogleAccounts() { - if (!params_) { - run_loop_ = std::make_unique<base::RunLoop>(); - run_loop_->Run(); - } - EXPECT_TRUE(params_.has_value()); - return params_.value(); - } - - GURL GetGaiaURL(const std::string& path) { - return https_server_.GetURL(kGaiaDomain, path); - } - - GURL GetNonGaiaURL(const std::string& path) { - return https_server_.GetURL(path); - } - - bool HasReceivedGoogleAccountsResponse() { return params_.has_value(); } - - std::string GetBody() { - return ExecuteScript(shell(), "document.body.innerText", true).GetString(); - } - - protected: - std::string response_header_; - - private: - std::unique_ptr<net::test_server::HttpResponse> HandleGoogleAccountsRequest( - const net::test_server::HttpRequest& request) { - std::string path = request.GetURL().path(); - if (path != kSignOutPath && path != kGoogleAccountsPath && - path != kGoogleAccountsRedirectPath) { - return nullptr; - } - - auto http_response = - std::make_unique<net::test_server::BasicHttpResponse>(); - if (path == kGoogleAccountsRedirectPath) { - http_response->set_code(net::HTTP_MOVED_PERMANENTLY); - http_response->AddCustomHeader( - "Location", - base::UnescapeBinaryURLComponent(request.GetURL().query_piece())); - } else { - http_response->set_code(net::HTTP_OK); - } - - if (base::Contains(request.headers, signin::kChromeConnectedHeader)) { - http_response->AddCustomHeader(signin::kChromeManageAccountsHeader, - response_header_); - } - http_response->set_content(""); - return http_response; - } - - net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS}; - absl::optional<signin::ManageAccountsParams> params_; - std::unique_ptr<base::RunLoop> run_loop_; -}; - -IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, Basic) { - response_header_ = - "action=ADDSESSION,email=foo@bar.com," - "continue_url=https://blah.com,is_same_tab=true"; - NavigateAndWaitForCompletion(GetGaiaURL(kGoogleAccountsPath), shell()); - const signin::ManageAccountsParams& params = WaitForGoogleAccounts(); - EXPECT_EQ(params.service_type, signin::GAIA_SERVICE_TYPE_ADDSESSION); - EXPECT_EQ(params.email, "foo@bar.com"); - EXPECT_EQ(params.continue_url, "https://blah.com"); - EXPECT_TRUE(params.is_same_tab); -} - -IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, NonGaiaUrl) { - response_header_ = "action=ADDSESSION"; - NavigateAndWaitForCompletion(GetNonGaiaURL(kGoogleAccountsPath), shell()); - - // Navigate again to make sure the manage accounts response would have been - // received. - NavigateAndWaitForCompletion(GetNonGaiaURL("/echo"), shell()); - EXPECT_FALSE(HasReceivedGoogleAccountsResponse()); -} - -IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, RedirectFromGaiaURL) { - response_header_ = "action=SIGNUP"; - - GURL final_url = GetGaiaURL(kGoogleAccountsPath); - TestNavigationObserver test_observer( - final_url, TestNavigationObserver::NavigationEvent::kCompletion, - shell()->tab()); - shell()->tab()->GetNavigationController()->Navigate(GetNonGaiaURL( - base::StrCat({kGoogleAccountsRedirectPath, "?", final_url.spec()}))); - test_observer.Wait(); - - const signin::ManageAccountsParams& params = WaitForGoogleAccounts(); - EXPECT_EQ(params.service_type, signin::GAIA_SERVICE_TYPE_SIGNUP); -} - -IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, RedirectToGaiaURL) { - response_header_ = "action=SIGNUP"; - - GURL final_url = GetNonGaiaURL(kGoogleAccountsPath); - TestNavigationObserver test_observer( - final_url, TestNavigationObserver::NavigationEvent::kCompletion, - shell()->tab()); - shell()->tab()->GetNavigationController()->Navigate(GetGaiaURL( - base::StrCat({kGoogleAccountsRedirectPath, "?", final_url.spec()}))); - test_observer.Wait(); - - const signin::ManageAccountsParams& params = WaitForGoogleAccounts(); - EXPECT_EQ(params.service_type, signin::GAIA_SERVICE_TYPE_SIGNUP); -} - -IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, AddsQueryParamsToSignoutURL) { - response_header_ = "action=SIGNUP"; - - // Sign out URL on the GAIA domain will get a query param added to it. - GURL sign_out_url = GetGaiaURL(kSignOutPath); - GURL sign_out_url_with_params = - net::AppendQueryParameter(sign_out_url, "manage", "true"); - { - TestNavigationObserver test_observer( - sign_out_url_with_params, - TestNavigationObserver::NavigationEvent::kCompletion, shell()->tab()); - shell()->tab()->GetNavigationController()->Navigate(sign_out_url); - test_observer.Wait(); - } - - // Other URLs will not have query param added. - NavigateAndWaitForCompletion(GetGaiaURL(kGoogleAccountsPath), shell()); - NavigateAndWaitForCompletion(GetNonGaiaURL(kSignOutPath), shell()); - - // Redirecting to sign out URL will also add params. - { - TestNavigationObserver test_observer( - sign_out_url_with_params, - TestNavigationObserver::NavigationEvent::kCompletion, shell()->tab()); - shell()->tab()->GetNavigationController()->Navigate( - GetNonGaiaURL("/server-redirect?" + sign_out_url.spec())); - test_observer.Wait(); - } -} - -IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, AddsRequestHeaderToGaiaURLs) { - const std::string path = - base::StrCat({"/echoheader?", signin::kChromeConnectedHeader}); - NavigateAndWaitForCompletion(GetGaiaURL(path), shell()); - EXPECT_EQ(GetBody(), - "source=WebLayer,mode=3,enable_account_consistency=true," - "consistency_enabled_by_default=false"); - - // Non GAIA URL should not get the header. - NavigateAndWaitForCompletion(GetNonGaiaURL(path), shell()); - EXPECT_EQ(GetBody(), "None"); -} - -class IncognitoGoogleAccountsBrowserTest : public GoogleAccountsBrowserTest { - public: - IncognitoGoogleAccountsBrowserTest() { SetShellStartsInIncognitoMode(); } -}; - -IN_PROC_BROWSER_TEST_F(IncognitoGoogleAccountsBrowserTest, - HeaderAddedForIncognitoBrowser) { - const std::string path = - base::StrCat({"/echoheader?", signin::kChromeConnectedHeader}); - NavigateAndWaitForCompletion(GetGaiaURL(path), shell()); - EXPECT_EQ(GetBody(), - "source=WebLayer,mode=3,enable_account_consistency=true," - "consistency_enabled_by_default=false"); -} - -} // namespace weblayer
diff --git a/weblayer/browser/google_accounts_callback_proxy.cc b/weblayer/browser/google_accounts_callback_proxy.cc deleted file mode 100644 index f58922a4..0000000 --- a/weblayer/browser/google_accounts_callback_proxy.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/google_accounts_callback_proxy.h" - -#include "base/android/jni_string.h" -#include "components/signin/core/browser/signin_header_helper.h" -#include "weblayer/browser/java/jni/GoogleAccountsCallbackProxy_jni.h" -#include "weblayer/public/tab.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertUTF8ToJavaString; - -namespace weblayer { - -GoogleAccountsCallbackProxy::GoogleAccountsCallbackProxy(JNIEnv* env, - jobject obj, - Tab* tab) - : tab_(tab), java_impl_(env, obj) { - tab_->SetGoogleAccountsDelegate(this); -} - -GoogleAccountsCallbackProxy::~GoogleAccountsCallbackProxy() { - tab_->SetGoogleAccountsDelegate(nullptr); -} - -void GoogleAccountsCallbackProxy::OnGoogleAccountsRequest( - const signin::ManageAccountsParams& params) { - JNIEnv* env = AttachCurrentThread(); - Java_GoogleAccountsCallbackProxy_onGoogleAccountsRequest( - env, java_impl_, params.service_type, - ConvertUTF8ToJavaString(env, params.email), - ConvertUTF8ToJavaString(env, params.continue_url), params.is_same_tab); -} - -std::string GoogleAccountsCallbackProxy::GetGaiaId() { - return base::android::ConvertJavaStringToUTF8( - Java_GoogleAccountsCallbackProxy_getGaiaId(AttachCurrentThread(), - java_impl_)); -} - -static jlong JNI_GoogleAccountsCallbackProxy_CreateGoogleAccountsCallbackProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong tab) { - return reinterpret_cast<jlong>( - new GoogleAccountsCallbackProxy(env, proxy, reinterpret_cast<Tab*>(tab))); -} - -static void JNI_GoogleAccountsCallbackProxy_DeleteGoogleAccountsCallbackProxy( - JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<GoogleAccountsCallbackProxy*>(proxy); -} - -} // namespace weblayer
diff --git a/weblayer/browser/google_accounts_callback_proxy.h b/weblayer/browser/google_accounts_callback_proxy.h deleted file mode 100644 index 04872ee2..0000000 --- a/weblayer/browser/google_accounts_callback_proxy.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_GOOGLE_ACCOUNTS_CALLBACK_PROXY_H_ -#define WEBLAYER_BROWSER_GOOGLE_ACCOUNTS_CALLBACK_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/memory/raw_ptr.h" -#include "weblayer/public/google_accounts_delegate.h" - -namespace weblayer { - -class Tab; - -class GoogleAccountsCallbackProxy : public GoogleAccountsDelegate { - public: - GoogleAccountsCallbackProxy(JNIEnv* env, jobject obj, Tab* tab); - ~GoogleAccountsCallbackProxy() override; - - // GoogleAccountsDelegate: - void OnGoogleAccountsRequest( - const signin::ManageAccountsParams& params) override; - std::string GetGaiaId() override; - - private: - raw_ptr<Tab> tab_; - base::android::ScopedJavaGlobalRef<jobject> java_impl_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_GOOGLE_ACCOUNTS_CALLBACK_PROXY_H_
diff --git a/weblayer/browser/heavy_ad_service_factory.cc b/weblayer/browser/heavy_ad_service_factory.cc deleted file mode 100644 index 1ce2342..0000000 --- a/weblayer/browser/heavy_ad_service_factory.cc +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/heavy_ad_service_factory.h" - -#include "base/no_destructor.h" -#include "components/heavy_ad_intervention/heavy_ad_service.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "content/public/browser/browser_context.h" - -namespace weblayer { - -// static -heavy_ad_intervention::HeavyAdService* -HeavyAdServiceFactory::GetForBrowserContext(content::BrowserContext* context) { - return static_cast<heavy_ad_intervention::HeavyAdService*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -HeavyAdServiceFactory* HeavyAdServiceFactory::GetInstance() { - static base::NoDestructor<HeavyAdServiceFactory> factory; - return factory.get(); -} - -HeavyAdServiceFactory::HeavyAdServiceFactory() - : BrowserContextKeyedServiceFactory( - "HeavyAdService", - BrowserContextDependencyManager::GetInstance()) {} - -HeavyAdServiceFactory::~HeavyAdServiceFactory() = default; - -std::unique_ptr<KeyedService> -HeavyAdServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<heavy_ad_intervention::HeavyAdService>(); -} - -content::BrowserContext* HeavyAdServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/heavy_ad_service_factory.h b/weblayer/browser/heavy_ad_service_factory.h deleted file mode 100644 index b52f84a..0000000 --- a/weblayer/browser/heavy_ad_service_factory.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_HEAVY_AD_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_HEAVY_AD_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace content { -class BrowserContext; -} - -namespace heavy_ad_intervention { -class HeavyAdService; -} - -namespace weblayer { - -class HeavyAdServiceFactory : public BrowserContextKeyedServiceFactory { - public: - HeavyAdServiceFactory(const HeavyAdServiceFactory&) = delete; - HeavyAdServiceFactory& operator=(const HeavyAdServiceFactory&) = delete; - - // Gets the HeavyAdService instance for |context|. - static heavy_ad_intervention::HeavyAdService* GetForBrowserContext( - content::BrowserContext* context); - - static HeavyAdServiceFactory* GetInstance(); - - private: - friend class base::NoDestructor<HeavyAdServiceFactory>; - - HeavyAdServiceFactory(); - ~HeavyAdServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_HEAVY_AD_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/host_content_settings_map_factory.cc b/weblayer/browser/host_content_settings_map_factory.cc deleted file mode 100644 index d9e57d3..0000000 --- a/weblayer/browser/host_content_settings_map_factory.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/host_content_settings_map_factory.h" - -#include <utility> - -#include "base/feature_list.h" -#include "components/content_settings/core/browser/content_settings_pref_provider.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" - -namespace weblayer { - -HostContentSettingsMapFactory::HostContentSettingsMapFactory() - : RefcountedBrowserContextKeyedServiceFactory( - "HostContentSettingsMap", - BrowserContextDependencyManager::GetInstance()) {} - -HostContentSettingsMapFactory::~HostContentSettingsMapFactory() = default; - -// static -HostContentSettingsMap* HostContentSettingsMapFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - - return static_cast<HostContentSettingsMap*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true).get()); -} - -// static -HostContentSettingsMapFactory* HostContentSettingsMapFactory::GetInstance() { - return base::Singleton<HostContentSettingsMapFactory>::get(); -} - -scoped_refptr<RefcountedKeyedService> -HostContentSettingsMapFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - scoped_refptr<HostContentSettingsMap> settings_map = - base::MakeRefCounted<HostContentSettingsMap>( - user_prefs::UserPrefs::Get(context), context->IsOffTheRecord(), - /*store_last_modified=*/true, - /*restore_session=*/false, - /*should_record_metrics=*/!context->IsOffTheRecord()); - - return settings_map; -} - -content::BrowserContext* HostContentSettingsMapFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/host_content_settings_map_factory.h b/weblayer/browser/host_content_settings_map_factory.h deleted file mode 100644 index 437fe87..0000000 --- a/weblayer/browser/host_content_settings_map_factory.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_HOST_CONTENT_SETTINGS_MAP_FACTORY_H_ -#define WEBLAYER_BROWSER_HOST_CONTENT_SETTINGS_MAP_FACTORY_H_ - -#include "base/memory/ref_counted.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h" - -class HostContentSettingsMap; - -namespace weblayer { - -class HostContentSettingsMapFactory - : public RefcountedBrowserContextKeyedServiceFactory { - public: - HostContentSettingsMapFactory(const HostContentSettingsMapFactory&) = delete; - HostContentSettingsMapFactory& operator=( - const HostContentSettingsMapFactory&) = delete; - - static HostContentSettingsMap* GetForBrowserContext( - content::BrowserContext* browser_context); - - static HostContentSettingsMapFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<HostContentSettingsMapFactory>; - - HostContentSettingsMapFactory(); - ~HostContentSettingsMapFactory() override; - - // RefcountedBrowserContextKeyedServiceFactory methods: - scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_HOST_CONTENT_SETTINGS_MAP_FACTORY_H_
diff --git a/weblayer/browser/http_auth_handler_impl.cc b/weblayer/browser/http_auth_handler_impl.cc deleted file mode 100644 index c9c018c..0000000 --- a/weblayer/browser/http_auth_handler_impl.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/http_auth_handler_impl.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents.h" -#include "net/base/auth.h" -#include "url/android/gurl_android.h" -#include "weblayer/browser/java/jni/HttpAuthHandlerImpl_jni.h" -#include "weblayer/browser/tab_impl.h" - -namespace weblayer { - -HttpAuthHandlerImpl::HttpAuthHandlerImpl( - const net::AuthChallengeInfo& auth_info, - content::WebContents* web_contents, - bool first_auth_attempt, - LoginAuthRequiredCallback callback) - : callback_(std::move(callback)) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - url_ = auth_info.challenger.GetURL().Resolve(auth_info.path); - - auto* tab = TabImpl::FromWebContents(web_contents); - JNIEnv* env = base::android::AttachCurrentThread(); - java_impl_ = Java_HttpAuthHandlerImpl_create( - env, reinterpret_cast<intptr_t>(this), tab->GetJavaTab(), - url::GURLAndroid::FromNativeGURL(env, url_)); -} - -HttpAuthHandlerImpl::~HttpAuthHandlerImpl() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - CloseDialog(); - if (java_impl_) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_HttpAuthHandlerImpl_handlerDestroyed(env, java_impl_); - java_impl_ = nullptr; - } -} - -void HttpAuthHandlerImpl::CloseDialog() { - if (!java_impl_) - return; - - JNIEnv* env = base::android::AttachCurrentThread(); - Java_HttpAuthHandlerImpl_closeDialog(env, java_impl_); -} - -void HttpAuthHandlerImpl::Proceed( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& username, - const base::android::JavaParamRef<jstring>& password) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (callback_) { - std::move(callback_).Run(net::AuthCredentials( - base::android::ConvertJavaStringToUTF16(env, username), - base::android::ConvertJavaStringToUTF16(env, password))); - } - - CloseDialog(); -} - -void HttpAuthHandlerImpl::Cancel(JNIEnv* env) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (callback_) - std::move(callback_).Run(absl::nullopt); - - CloseDialog(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/http_auth_handler_impl.h b/weblayer/browser/http_auth_handler_impl.h deleted file mode 100644 index 7de2e98..0000000 --- a/weblayer/browser/http_auth_handler_impl.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_HTTP_AUTH_HANDLER_IMPL_H_ -#define WEBLAYER_BROWSER_HTTP_AUTH_HANDLER_IMPL_H_ - -#include "base/android/scoped_java_ref.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/browser/login_delegate.h" -#include "url/gurl.h" - -namespace weblayer { - -// Implements support for http auth. -class HttpAuthHandlerImpl : public content::LoginDelegate { - public: - HttpAuthHandlerImpl(const net::AuthChallengeInfo& auth_info, - content::WebContents* web_contents, - bool first_auth_attempt, - LoginAuthRequiredCallback callback); - ~HttpAuthHandlerImpl() override; - - void Proceed(JNIEnv* env, - const base::android::JavaParamRef<jstring>& username, - const base::android::JavaParamRef<jstring>& password); - void Cancel(JNIEnv* env); - - private: - void CloseDialog(); - - GURL url_; - LoginAuthRequiredCallback callback_; - base::android::ScopedJavaGlobalRef<jobject> java_impl_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_HTTP_AUTH_HANDLER_IMPL_H_
diff --git a/weblayer/browser/i18n_util.cc b/weblayer/browser/i18n_util.cc deleted file mode 100644 index 24efa37..0000000 --- a/weblayer/browser/i18n_util.cc +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/i18n_util.h" - -#include "base/i18n/rtl.h" -#include "base/no_destructor.h" -#include "base/task/thread_pool.h" -#include "build/build_config.h" -#include "net/http/http_util.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/locale_utils.h" -#include "ui/base/resource/resource_bundle.h" -#include "weblayer/browser/java/jni/LocaleChangedBroadcastReceiver_jni.h" -#endif - -namespace { - -base::RepeatingClosureList& GetLocaleChangeClosures() { - static base::NoDestructor<base::RepeatingClosureList> instance; - return *instance; -} - -} // namespace - -namespace weblayer { -namespace i18n { - -std::string GetApplicationLocale() { - // The locale is set in ContentMainDelegateImpl::InitializeResourceBundle(). - return base::i18n::GetConfiguredLocale(); -} - -std::string GetAcceptLangs() { -#if BUILDFLAG(IS_ANDROID) - std::string locale_list = base::android::GetDefaultLocaleListString(); -#else - std::string locale_list = GetApplicationLocale(); -#endif - return net::HttpUtil::ExpandLanguageList(locale_list); -} - -base::CallbackListSubscription RegisterLocaleChangeCallback( - base::RepeatingClosure locale_changed) { - return GetLocaleChangeClosures().Add(locale_changed); -} - -#if BUILDFLAG(IS_ANDROID) -static void JNI_LocaleChangedBroadcastReceiver_LocaleChanged(JNIEnv* env) { - base::ThreadPool::PostTaskAndReply( - FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, - base::BindOnce([]() { - // Passing an empty |pref_locale| means the Android system locale will - // be used (base::android::GetDefaultLocaleString()). - ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources( - {} /*pref_locale*/); - }), - base::BindOnce([]() { GetLocaleChangeClosures().Notify(); })); - // TODO(estade): need to update the ResourceBundle for non-Browser processes - // as well. -} -#endif - -} // namespace i18n -} // namespace weblayer
diff --git a/weblayer/browser/i18n_util.h b/weblayer/browser/i18n_util.h deleted file mode 100644 index dfabcf8..0000000 --- a/weblayer/browser/i18n_util.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_I18N_UTIL_H_ -#define WEBLAYER_BROWSER_I18N_UTIL_H_ - -#include <string> - -#include "base/callback_list.h" - -namespace weblayer { -namespace i18n { - -// Returns the currently-in-use ICU locale. This may be called on any thread. -std::string GetApplicationLocale(); - -// Returns a list of locales suitable for use in the ACCEPT-LANGUAGE header. -// This may be called on any thread. -std::string GetAcceptLangs(); - -base::CallbackListSubscription RegisterLocaleChangeCallback( - base::RepeatingClosure locale_changed); - -} // namespace i18n -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_I18N_UTIL_H_
diff --git a/weblayer/browser/infobar_container_android.cc b/weblayer/browser/infobar_container_android.cc deleted file mode 100644 index 3120380..0000000 --- a/weblayer/browser/infobar_container_android.cc +++ /dev/null
@@ -1,109 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/infobar_container_android.h" - -#include "base/android/jni_android.h" -#include "base/check.h" -#include "base/metrics/histogram_functions.h" -#include "components/infobars/android/infobar_android.h" -#include "components/infobars/content/content_infobar_manager.h" -#include "components/infobars/core/infobar.h" -#include "components/infobars/core/infobar_delegate.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/android/resource_mapper.h" -#include "weblayer/browser/java/jni/InfoBarContainer_jni.h" - -using base::android::JavaParamRef; - -namespace weblayer { - -// InfoBarContainerAndroid ---------------------------------------------------- - -InfoBarContainerAndroid::InfoBarContainerAndroid(JNIEnv* env, jobject obj) - : infobars::InfoBarContainer(NULL), - weak_java_infobar_container_(env, obj) {} - -InfoBarContainerAndroid::~InfoBarContainerAndroid() { - RemoveAllInfoBarsForDestruction(); -} - -void InfoBarContainerAndroid::SetWebContents( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - const JavaParamRef<jobject>& web_contents) { - infobars::ContentInfoBarManager* infobar_manager = - web_contents - ? infobars::ContentInfoBarManager::FromWebContents( - content::WebContents::FromJavaWebContents(web_contents)) - : nullptr; - ChangeInfoBarManager(infobar_manager); -} - -void InfoBarContainerAndroid::Destroy(JNIEnv* env, - const JavaParamRef<jobject>& obj) { - delete this; -} - -// Creates the Java equivalent of |android_bar| and add it to the java -// container. -void InfoBarContainerAndroid::PlatformSpecificAddInfoBar( - infobars::InfoBar* infobar, - size_t position) { - DCHECK(infobar); - infobars::InfoBarAndroid* android_bar = - static_cast<infobars::InfoBarAndroid*>(infobar); - - if (android_bar->HasSetJavaInfoBar()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); - - if (Java_InfoBarContainer_hasInfoBars( - env, weak_java_infobar_container_.get(env))) { - base::UmaHistogramSparse("InfoBar.Shown.Hidden", - android_bar->delegate()->GetIdentifier()); - infobars::InfoBarDelegate::InfoBarIdentifier identifier = - static_cast<infobars::InfoBarDelegate::InfoBarIdentifier>( - Java_InfoBarContainer_getTopInfoBarIdentifier( - env, weak_java_infobar_container_.get(env))); - if (identifier != infobars::InfoBarDelegate::InfoBarIdentifier::INVALID) { - base::UmaHistogramSparse("InfoBar.Shown.Hiding", identifier); - } - } else { - base::UmaHistogramSparse("InfoBar.Shown.Visible", - android_bar->delegate()->GetIdentifier()); - } - - base::android::ScopedJavaLocalRef<jobject> java_infobar = - android_bar->CreateRenderInfoBar( - env, base::BindRepeating(&MapToJavaDrawableId)); - android_bar->SetJavaInfoBar(java_infobar); - Java_InfoBarContainer_addInfoBar(env, weak_java_infobar_container_.get(env), - java_infobar); -} - -void InfoBarContainerAndroid::PlatformSpecificReplaceInfoBar( - infobars::InfoBar* old_infobar, - infobars::InfoBar* new_infobar) { - static_cast<infobars::InfoBarAndroid*>(new_infobar) - ->PassJavaInfoBar(static_cast<infobars::InfoBarAndroid*>(old_infobar)); -} - -void InfoBarContainerAndroid::PlatformSpecificRemoveInfoBar( - infobars::InfoBar* infobar) { - infobars::InfoBarAndroid* android_infobar = - static_cast<infobars::InfoBarAndroid*>(infobar); - android_infobar->CloseJavaInfoBar(); -} - -// Native JNI methods --------------------------------------------------------- - -static jlong JNI_InfoBarContainer_Init(JNIEnv* env, - const JavaParamRef<jobject>& obj) { - InfoBarContainerAndroid* infobar_container = - new InfoBarContainerAndroid(env, obj); - return reinterpret_cast<intptr_t>(infobar_container); -} - -} // namespace weblayer
diff --git a/weblayer/browser/infobar_container_android.h b/weblayer/browser/infobar_container_android.h deleted file mode 100644 index 98e37d3..0000000 --- a/weblayer/browser/infobar_container_android.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_INFOBAR_CONTAINER_ANDROID_H_ -#define WEBLAYER_BROWSER_INFOBAR_CONTAINER_ANDROID_H_ - -#include <stddef.h> - -#include "base/android/jni_weak_ref.h" -#include "base/android/scoped_java_ref.h" -#include "base/compiler_specific.h" -#include "components/infobars/core/infobar_container.h" - -namespace weblayer { - -class InfoBarContainerAndroid : public infobars::InfoBarContainer { - public: - InfoBarContainerAndroid(JNIEnv* env, jobject infobar_container); - - InfoBarContainerAndroid(const InfoBarContainerAndroid&) = delete; - InfoBarContainerAndroid& operator=(const InfoBarContainerAndroid&) = delete; - - void SetWebContents(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jobject>& web_contents); - void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - - JavaObjectWeakGlobalRef java_container() const { - return weak_java_infobar_container_; - } - - private: - ~InfoBarContainerAndroid() override; - - // InfobarContainer: - void PlatformSpecificAddInfoBar(infobars::InfoBar* infobar, - size_t position) override; - void PlatformSpecificRemoveInfoBar(infobars::InfoBar* infobar) override; - void PlatformSpecificReplaceInfoBar(infobars::InfoBar* old_infobar, - infobars::InfoBar* new_infobar) override; - - // We're owned by the java infobar, need to use a weak ref so it can destroy - // us. - JavaObjectWeakGlobalRef weak_java_infobar_container_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_INFOBAR_CONTAINER_ANDROID_H_
diff --git a/weblayer/browser/insecure_form_controller_client.cc b/weblayer/browser/insecure_form_controller_client.cc deleted file mode 100644 index 909ef9dc..0000000 --- a/weblayer/browser/insecure_form_controller_client.cc +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/insecure_form_controller_client.h" - -#include "components/security_interstitials/content/insecure_form_tab_storage.h" -#include "components/security_interstitials/content/settings_page_helper.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/i18n_util.h" - -namespace weblayer { - -// static -std::unique_ptr<security_interstitials::MetricsHelper> -InsecureFormControllerClient::GetMetricsHelper(const GURL& url) { - security_interstitials::MetricsHelper::ReportDetails settings; - settings.metric_prefix = "insecure_form"; - return std::make_unique<security_interstitials::MetricsHelper>(url, settings, - nullptr); -} - -// static -std::unique_ptr<security_interstitials::SettingsPageHelper> -InsecureFormControllerClient::GetSettingsPageHelper() { - // Return nullptr since there is no enhanced protection message in insecure - // form interstitials. - return nullptr; -} - -InsecureFormControllerClient::InsecureFormControllerClient( - content::WebContents* web_contents, - const GURL& form_target_url) - : SecurityInterstitialControllerClient( - web_contents, - GetMetricsHelper(form_target_url), - nullptr, /* prefs */ - i18n::GetApplicationLocale(), - GURL("about:blank") /* default_safe_page */, - GetSettingsPageHelper()), - web_contents_(web_contents) {} - -InsecureFormControllerClient::~InsecureFormControllerClient() = default; - -void InsecureFormControllerClient::GoBack() { - SecurityInterstitialControllerClient::GoBackAfterNavigationCommitted(); -} - -void InsecureFormControllerClient::Proceed() { - // Set the is_proceeding flag on the tab storage so reload doesn't trigger - // another interstitial. - security_interstitials::InsecureFormTabStorage* tab_storage = - security_interstitials::InsecureFormTabStorage::GetOrCreate( - web_contents_); - tab_storage->SetIsProceeding(true); - // We don't check for repost on the proceed reload since the interstitial - // explains this will submit the form. - web_contents_->GetController().Reload(content::ReloadType::NORMAL, false); -} - -} // namespace weblayer
diff --git a/weblayer/browser/insecure_form_controller_client.h b/weblayer/browser/insecure_form_controller_client.h deleted file mode 100644 index a415e34..0000000 --- a/weblayer/browser/insecure_form_controller_client.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_INSECURE_FORM_CONTROLLER_CLIENT_H_ -#define WEBLAYER_BROWSER_INSECURE_FORM_CONTROLLER_CLIENT_H_ - -#include "base/memory/raw_ptr.h" -#include "components/security_interstitials/content/security_interstitial_controller_client.h" -#include "components/security_interstitials/core/metrics_helper.h" - -namespace content { -class WebContents; -} - -namespace weblayer { - -// A stripped-down version of the class by the same name in -// //chrome/browser/ssl, which provides basic functionality for interacting with -// the insecure form interstitial. -class InsecureFormControllerClient - : public security_interstitials::SecurityInterstitialControllerClient { - public: - static std::unique_ptr<security_interstitials::MetricsHelper> - GetMetricsHelper(const GURL& url); - static std::unique_ptr<security_interstitials::SettingsPageHelper> - GetSettingsPageHelper(); - - InsecureFormControllerClient(content::WebContents* web_contents, - const GURL& form_target_url); - InsecureFormControllerClient(const InsecureFormControllerClient&) = delete; - InsecureFormControllerClient& operator=(const InsecureFormControllerClient&) = - delete; - ~InsecureFormControllerClient() override; - - // security_interstitials::SecurityInterstitialControllerClient: - void GoBack() override; - void Proceed() override; - - private: - raw_ptr<content::WebContents> web_contents_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_INSECURE_FORM_CONTROLLER_CLIENT_H_
diff --git a/weblayer/browser/java/AndroidManifest.xml b/weblayer/browser/java/AndroidManifest.xml deleted file mode 100644 index a039ba0..0000000 --- a/weblayer/browser/java/AndroidManifest.xml +++ /dev/null
@@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:dist="http://schemas.android.com/apk/distribution" - featureSplit="weblayer"> - - <dist:module dist:onDemand="false"> - <dist:fusing dist:include="true" /> - </dist:module> - - <application /> -</manifest>
diff --git a/weblayer/browser/java/AndroidManifest_monochrome.xml b/weblayer/browser/java/AndroidManifest_monochrome.xml deleted file mode 100644 index ed0af94..0000000 --- a/weblayer/browser/java/AndroidManifest_monochrome.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:dist="http://schemas.android.com/apk/distribution" - featureSplit="weblayer"> - <uses-split android:name="chrome" /> - - <dist:module dist:onDemand="false"> - <dist:fusing dist:include="true" /> - </dist:module> - - <application /> -</manifest>
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn deleted file mode 100644 index 7e19373..0000000 --- a/weblayer/browser/java/BUILD.gn +++ /dev/null
@@ -1,630 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") -import("//build/config/locales.gni") -import("//device/vr/buildflags/buildflags.gni") -import("//third_party/jni_zero/jni_zero.gni") -import("//tools/grit/grit_rule.gni") -import("//weblayer/variables.gni") - -android_resources("weblayer_resources") { - sources = [ - "res/drawable/weblayer_tab_indicator.xml", - "res/layout/weblayer_infobar_translate_compact_content.xml", - "res/values/colors.xml", - "res/values/dimens.xml", - "res/values/styles.xml", - ] - deps = [ - ":weblayer_strings_grd", - "//components/blocked_content/android:java_resources", - "//components/browser_ui/accessibility/android:java_resources", - "//components/browser_ui/contacts_picker/android:java_resources", - "//components/browser_ui/http_auth/android:java_resources", - "//components/browser_ui/media/android:java_resources", - "//components/browser_ui/settings/android:java_resources", - "//components/browser_ui/site_settings/android:java_resources", - "//components/browser_ui/strings/android:browser_ui_strings_grd", - "//components/browser_ui/theme/android:java_resources", - "//components/infobars/android:java_resources", - "//components/omnibox/browser:java_resources", - "//components/page_info/android:java_resources", - "//components/permissions/android:java_resources", - - # TODO(crbug.com/1137713): Determine why the creation of - # //components/subresource_filter Java resources caused //weblayer's BundlePackageTest - # to fail without this dep even in advance of //weblayer depending on the code that uses these - # resources. - "//components/subresource_filter/android:java_resources", - "//components/translate/content/android:java_resources", - "//third_party/android_deps:material_design_java", - "//weblayer:components_java_strings", - ] -} - -generate_product_config_srcjar("weblayer_product_config") { - java_package = weblayer_product_config_java_package -} - -java_cpp_template("resource_id_javagen") { - sources = [ "ResourceId.template" ] - inputs = [ - "//components/resources/android/blocked_content_resource_id.h", - "//components/resources/android/page_info_resource_id.h", - "//components/resources/android/permissions_resource_id.h", - "//components/resources/android/sms_resource_id.h", - "//components/resources/android/webxr_resource_id.h", - "$root_gen_dir/device/vr/buildflags/buildflags.h", - ] - - deps = [ "//device/vr/buildflags" ] -} - -java_strings_grd("weblayer_strings_grd") { - grd_file = "weblayer_strings.grd" - outputs = [ "values/weblayer_strings.xml" ] + - process_file_template( - android_bundle_locales_as_resources, - [ "values-{{source_name_part}}/weblayer_strings.xml" ]) -} - -java_cpp_enum("generated_enums") { - sources = [ - "//weblayer/public/download.h", - "//weblayer/public/navigation.h", - "//weblayer/public/new_tab_delegate.h", - "//weblayer/public/profile.h", - ] -} - -generate_jni("base_module_jni") { - sources = [ "org/chromium/weblayer_private/ApplicationInfoHelper.java" ] -} - -android_library("base_module_java") { - sources = [ - "org/chromium/weblayer_private/ApplicationInfoHelper.java", - "org/chromium/weblayer_private/ChildProcessServiceImpl.java", - ] - srcjar_deps = [ ":base_module_jni" ] - deps = [ - ":base_module_interfaces_java", - "$google_play_services_package:google_play_services_basement_java", - "//base:base_java", - "//base:jni_java", - "//base:process_launcher_java", - "//build/android:build_java", - "//components/embedder_support/android:application_java", - "//content/public/android:content_java", - ] - - # Needed for android.webkit.WebViewFactory - alternative_android_sdk_dep = - "//third_party/android_sdk:public_framework_system_java" -} - -android_library("java") { - sources = [ - "org/chromium/weblayer_private/AutocompleteSchemeClassifierImpl.java", - "org/chromium/weblayer_private/BrowserFragmentImpl.java", - "org/chromium/weblayer_private/BrowserImpl.java", - "org/chromium/weblayer_private/BrowserList.java", - "org/chromium/weblayer_private/BrowserListObserver.java", - "org/chromium/weblayer_private/BrowserViewController.java", - "org/chromium/weblayer_private/ContactsPickerAdapter.java", - "org/chromium/weblayer_private/ContentViewRenderView.java", - "org/chromium/weblayer_private/ContentViewWithAutofill.java", - "org/chromium/weblayer_private/CookieManagerImpl.java", - "org/chromium/weblayer_private/CrashReporterController.java", - "org/chromium/weblayer_private/DownloadCallbackProxy.java", - "org/chromium/weblayer_private/DownloadImpl.java", - "org/chromium/weblayer_private/ErrorPageCallbackProxy.java", - "org/chromium/weblayer_private/ExternalIntentInIncognitoCallbackProxy.java", - "org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java", - "org/chromium/weblayer_private/FaviconCallbackProxy.java", - "org/chromium/weblayer_private/FragmentAndroidPermissionDelegate.java", - "org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java", - "org/chromium/weblayer_private/FragmentWindowAndroid.java", - "org/chromium/weblayer_private/FullscreenCallbackProxy.java", - "org/chromium/weblayer_private/FullscreenToast.java", - "org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherProxy.java", - "org/chromium/weblayer_private/GoogleAccountsCallbackProxy.java", - "org/chromium/weblayer_private/HttpAuthHandlerImpl.java", - "org/chromium/weblayer_private/InfoBarContainer.java", - "org/chromium/weblayer_private/InfoBarContainerView.java", - "org/chromium/weblayer_private/InstalledAppProviderFactory.java", - "org/chromium/weblayer_private/IntentUtils.java", - "org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java", - "org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java", - "org/chromium/weblayer_private/MojoInterfaceRegistrar.java", - "org/chromium/weblayer_private/NavigationControllerImpl.java", - "org/chromium/weblayer_private/NavigationImpl.java", - "org/chromium/weblayer_private/NewTabCallbackProxy.java", - "org/chromium/weblayer_private/PageImpl.java", - "org/chromium/weblayer_private/PrerenderControllerImpl.java", - "org/chromium/weblayer_private/ProfileImpl.java", - "org/chromium/weblayer_private/ProfileManager.java", - "org/chromium/weblayer_private/RemoteFragmentImpl.java", - "org/chromium/weblayer_private/TabCallbackProxy.java", - "org/chromium/weblayer_private/TabImpl.java", - "org/chromium/weblayer_private/TranslateCompactInfoBar.java", - "org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java", - "org/chromium/weblayer_private/WebApkInstallSchedulerClient.java", - "org/chromium/weblayer_private/WebApkServiceConnection.java", - "org/chromium/weblayer_private/WebContentsGestureStateTracker.java", - "org/chromium/weblayer_private/WebLayerAccessibilityUtil.java", - "org/chromium/weblayer_private/WebLayerActionModeCallback.java", - "org/chromium/weblayer_private/WebLayerExceptionFilter.java", - "org/chromium/weblayer_private/WebLayerFactoryImpl.java", - "org/chromium/weblayer_private/WebLayerImpl.java", - "org/chromium/weblayer_private/WebLayerNotificationChannels.java", - "org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java", - "org/chromium/weblayer_private/WebLayerOriginVerificationScheduler.java", - "org/chromium/weblayer_private/WebLayerOriginVerifier.java", - "org/chromium/weblayer_private/WebLayerTabModalPresenter.java", - "org/chromium/weblayer_private/WebLayerVerificationResultStore.java", - "org/chromium/weblayer_private/WebShareServiceFactory.java", - "org/chromium/weblayer_private/WebappsHelper.java", - "org/chromium/weblayer_private/bluetooth/WebLayerBluetoothChooserAndroidDelegate.java", - "org/chromium/weblayer_private/bluetooth/WebLayerBluetoothScanningPromptAndroidDelegate.java", - "org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java", - "org/chromium/weblayer_private/media/MediaRouterClientImpl.java", - "org/chromium/weblayer_private/media/MediaSessionManager.java", - "org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java", - "org/chromium/weblayer_private/media/MediaStreamManager.java", - "org/chromium/weblayer_private/metrics/MetricsServiceClient.java", - "org/chromium/weblayer_private/metrics/UmaUtils.java", - "org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java", - "org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java", - "org/chromium/weblayer_private/permissions/PermissionRequestUtils.java", - "org/chromium/weblayer_private/resources/ResourceMapper.java", - "org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java", - "org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java", - ] - resources_package = "org.chromium.weblayer_private" - - deps = [ - ":base_module_interfaces_java", - ":base_module_java", - ":gms_bridge_java", - ":interfaces_java", - ":weblayer_resources", - "//base:base_java", - "//base:jni_java", - "//build/android:build_java", - "//cc:cc_java", - "//cc/mojom:mojom_java", - "//components/android_autofill/browser:java", - "//components/browser_ui/accessibility/android:lib_java", - "//components/browser_ui/banners/android:java", - "//components/browser_ui/bottomsheet/android:factory_java", - "//components/browser_ui/bottomsheet/android:java", - "//components/browser_ui/bottomsheet/android:manager_java", - "//components/browser_ui/bottomsheet/android/internal:java", - "//components/browser_ui/client_certificate/android:java", - "//components/browser_ui/contacts_picker/android:java", - "//components/browser_ui/display_cutout/android:java", - "//components/browser_ui/http_auth/android:java", - "//components/browser_ui/media/android:java", - "//components/browser_ui/modaldialog/android:java", - "//components/browser_ui/notifications/android:java", - "//components/browser_ui/photo_picker/android:java", - "//components/browser_ui/settings/android:java", - "//components/browser_ui/share/android:java", - "//components/browser_ui/site_settings/android:java", - "//components/browser_ui/sms/android:java", - "//components/browser_ui/styles/android:java", - "//components/browser_ui/util/android:java", - "//components/browser_ui/webshare/android:java", - "//components/browser_ui/widget/android:java", - "//components/component_updater/android:embedded_component_loader_java", - "//components/content_capture/android:java", - "//components/content_relationship_verification/android:java", - "//components/content_settings/android:content_settings_enums_java", - "//components/content_settings/android:java", - "//components/crash/android:handler_java", - "//components/crash/android:java", - "//components/download/internal/background_service:internal_java", - "//components/download/internal/common:internal_java", - "//components/download/network:network_java", - "//components/embedder_support/android:application_java", - "//components/embedder_support/android:content_view_java", - "//components/embedder_support/android:context_menu_java", - "//components/embedder_support/android:simple_factory_key_java", - "//components/embedder_support/android:util_java", - "//components/embedder_support/android:web_contents_delegate_java", - "//components/embedder_support/android/metrics:java", - "//components/external_intents/android:java", - "//components/favicon/android:java", - "//components/find_in_page/android:java", - "//components/image_fetcher:java", - "//components/infobars/android:infobar_android_enums_java", - "//components/infobars/android:java", - "//components/infobars/core:infobar_enums_java", - "//components/installedapp/android:java", - "//components/javascript_dialogs/android:java", - "//components/location/android:settings_java", - "//components/media_router/browser/android:cast_options_provider_java", - "//components/media_router/browser/android:java", - "//components/metrics:metrics_java", - "//components/minidump_uploader:minidump_uploader_java", - "//components/navigation_interception/android:navigation_interception_java", - "//components/omnibox/browser:scheme_classifier_java", - "//components/page_info/android:java", - "//components/payments/content/android:java", - "//components/payments/content/android:service_java", - "//components/payments/mojom:mojom_java", - "//components/permissions/android:java", - "//components/prefs/android:java", - "//components/safe_browsing/android:safe_browsing_java", - "//components/security_interstitials/content/android:java", - "//components/security_state/core:security_state_enums_java", - "//components/signin/core/browser:signin_enums_java", - "//components/spellcheck/browser/android:java", - "//components/translate/content/android:java", - "//components/translate/content/android:translate_android_enums_java", - "//components/translate/core/common:translate_infobar_event_enum_java", - "//components/url_formatter/android:url_formatter_java", - "//components/user_prefs/android:java", - "//components/variations/android:variations_java", - "//components/version_info/android:version_constants_java", - "//components/webapk/android/libs/client:java", - "//components/webapps/browser/android:java", - "//components/webapps/common/android:webapk_install_java", - "//components/webauthn/android:java", - "//components/webrtc/android:java", - "//content/public/android:content_java", - "//mojo/public/java:bindings_java", - "//mojo/public/java:system_java", - "//net/android:net_java", - "//services/data_decoder/public/cpp/android:safe_json_java", - "//services/network/public/mojom:cookies_mojom_java", - "//services/network/public/mojom:mojom_java", - "//services/network/public/mojom:url_loader_base_java", - "//services/service_manager/public/java:service_manager_java", - "//third_party/android_deps:material_design_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_appcompat_appcompat_resources_java", - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_media_media_java", - "//third_party/androidx:androidx_mediarouter_mediarouter_java", - "//third_party/androidx:androidx_preference_preference_java", - "//third_party/blink/public/mojom:android_mojo_bindings_java", - "//ui/accessibility:ax_base_java", - "//ui/android:ui_full_java", - "//ui/android:ui_java", - "//url:gurl_java", - ] - - if (enable_arcore) { - sources += [ - "org/chromium/weblayer_private/ArCompositorDelegateImpl.java", - "org/chromium/weblayer_private/ArCompositorDelegateProviderImpl.java", - "org/chromium/weblayer_private/ArCoreVersionUtils.java", - ] - deps += [ "//components/webxr/android:xr_java" ] - } - - srcjar_deps = [ - ":generated_enums", - ":jni", - ":resource_id_javagen", - ":weblayer_product_config", - ] - jar_excluded_patterns = [ "*/ProductConfig.class" ] - - # Needed for android.webkit.WebView(Delegate|Factory) - alternative_android_sdk_dep = - "//third_party/android_sdk:public_framework_system_java" -} - -java_group("upstream_java") { - deps = [ - ":gms_bridge_upstream_impl_java", - "//components/externalauth/android:google_delegate_public_impl_java", - ] -} - -android_resources("weblayer_test_resources") { - sources = [ - "res_test/layout/test_layout.xml", - "res_test/values/values.xml", - ] -} - -android_library("test_java") { - testonly = true - sources = [ - "org/chromium/weblayer_private/test/TestAutofillManagerWrapper.java", - "org/chromium/weblayer_private/test/TestContentCaptureConsumer.java", - "org/chromium/weblayer_private/test/TestInfoBar.java", - "org/chromium/weblayer_private/test/TestWebLayerImpl.java", - ] - srcjar_deps = [ - ":test_aidl", - ":test_jni", - ] - resources_package = "org.chromium.weblayer_private.test" - deps = [ - ":base_module_interfaces_java", - ":interfaces_java", - ":java", - ":test_interfaces_java", - ":weblayer_test_resources", - "//base:jni_java", - "//build/android:build_java", - "//components/android_autofill/browser:java", - "//components/android_autofill/browser/test_support:java", - "//components/browser_ui/accessibility/android:lib_java", - "//components/content_capture/android:java", - "//components/infobars/android:java", - "//components/location/android:location_java", - "//components/media_router/browser/android:java", - "//components/media_router/browser/android:test_support_java", - "//components/permissions/android:java", - "//components/webauthn/android:java", - "//components/webauthn/android:test_support_java", - "//content/public/android:content_java", - "//content/public/test/android:content_java_test_support", - "//net/android:net_java", - "//services/device/public/java:geolocation_java", - "//services/device/public/java:geolocation_java_test_support", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/blink/public/mojom:android_mojo_bindings_java", - "//ui/android:ui_full_java", - ] -} - -robolectric_library("junit_test_support") { - deps = [ - ":java", - "//base:base_java", - "//components/payments/content/android:java", - "//components/payments/content/android:junit_test_support", - "//components/payments/content/android:service_java", - "//components/payments/mojom:mojom_java", - "//content/public/android:content_java", - "//mojo/public/java:bindings_java", - "//mojo/public/java:system_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/blink/public/mojom:android_mojo_bindings_java", - "//third_party/mockito:mockito_java", - "//ui/android:ui_no_recycler_view_java", - "//url:gurl_java", - "//url:gurl_junit_test_support", - ] - sources = [ "org/chromium/weblayer_private/payments/test_support/WebLayerPaymentRequestBuilder.java" ] -} - -robolectric_binary("weblayer_junit_tests") { - testonly = true - sources = [ - "org/chromium/weblayer_private/WebLayerOriginVerifierTest.java", - "org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java", - ] - resources_package = "org.chromium.weblayer_private.test" - deps = [ - ":java", - ":junit_test_support", - "//base:base_java", - "//base:base_java_test_support", - "//base:base_junit_test_support", - "//base:jni_java", - "//components/content_relationship_verification:java", - "//components/content_relationship_verification/android:java", - "//components/content_relationship_verification/android:junit_test_support", - "//components/embedder_support/android:util_java", - "//components/payments/content/android:java", - "//components/payments/content/android:junit_test_support", - "//components/payments/content/android:service_java", - "//components/payments/mojom:mojom_java", - "//components/security_state/core:security_state_enums_java", - "//content/public/android:content_java", - "//content/public/test/android:content_java_test_support", - "//mojo/public/java:bindings_java", - "//mojo/public/java:system_java", - "//services/service_manager/public/java:service_manager_java", - "//third_party/androidx:androidx_test_core_java", - "//third_party/blink/public/mojom:android_mojo_bindings_java", - "//third_party/junit", - "//third_party/mockito:mockito_java", - "//ui/android:ui_no_recycler_view_java", - ] - shared_libraries = [ "//url:libgurl_robolectric($robolectric_toolchain)" ] -} - -generate_jni("test_jni") { - testonly = true - sources = [ - "org/chromium/weblayer_private/test/TestInfoBar.java", - "org/chromium/weblayer_private/test/TestWebLayerImpl.java", - ] -} - -generate_jni("jni") { - sources = [ - "org/chromium/weblayer_private/AutocompleteSchemeClassifierImpl.java", - "org/chromium/weblayer_private/BrowserFragmentImpl.java", - "org/chromium/weblayer_private/BrowserImpl.java", - "org/chromium/weblayer_private/BrowserList.java", - "org/chromium/weblayer_private/ContentViewRenderView.java", - "org/chromium/weblayer_private/CookieManagerImpl.java", - "org/chromium/weblayer_private/DownloadCallbackProxy.java", - "org/chromium/weblayer_private/DownloadImpl.java", - "org/chromium/weblayer_private/ErrorPageCallbackProxy.java", - "org/chromium/weblayer_private/FaviconCallbackProxy.java", - "org/chromium/weblayer_private/FullscreenCallbackProxy.java", - "org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherProxy.java", - "org/chromium/weblayer_private/GoogleAccountsCallbackProxy.java", - "org/chromium/weblayer_private/HttpAuthHandlerImpl.java", - "org/chromium/weblayer_private/InfoBarContainer.java", - "org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java", - "org/chromium/weblayer_private/MojoInterfaceRegistrar.java", - "org/chromium/weblayer_private/NavigationControllerImpl.java", - "org/chromium/weblayer_private/NavigationImpl.java", - "org/chromium/weblayer_private/NewTabCallbackProxy.java", - "org/chromium/weblayer_private/PageImpl.java", - "org/chromium/weblayer_private/PrerenderControllerImpl.java", - "org/chromium/weblayer_private/ProfileImpl.java", - "org/chromium/weblayer_private/TabCallbackProxy.java", - "org/chromium/weblayer_private/TabImpl.java", - "org/chromium/weblayer_private/TranslateCompactInfoBar.java", - "org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java", - "org/chromium/weblayer_private/WebLayerExceptionFilter.java", - "org/chromium/weblayer_private/WebLayerFactoryImpl.java", - "org/chromium/weblayer_private/WebLayerImpl.java", - "org/chromium/weblayer_private/WebappsHelper.java", - "org/chromium/weblayer_private/bluetooth/WebLayerBluetoothChooserAndroidDelegate.java", - "org/chromium/weblayer_private/bluetooth/WebLayerBluetoothScanningPromptAndroidDelegate.java", - "org/chromium/weblayer_private/media/MediaRouterClientImpl.java", - "org/chromium/weblayer_private/media/MediaStreamManager.java", - "org/chromium/weblayer_private/metrics/MetricsServiceClient.java", - "org/chromium/weblayer_private/metrics/UmaUtils.java", - "org/chromium/weblayer_private/permissions/PermissionRequestUtils.java", - "org/chromium/weblayer_private/resources/ResourceMapper.java", - ] - - if (enable_arcore) { - sources += [ - "org/chromium/weblayer_private/ArCompositorDelegateProviderImpl.java", - "org/chromium/weblayer_private/ArCoreVersionUtils.java", - ] - } -} - -android_library("base_module_interfaces_java") { - sources = [ - "org/chromium/weblayer_private/interfaces/ObjectWrapper.java", - "org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java", - ] - - srcjar_deps = [ ":base_module_aidl" ] -} - -android_library("interfaces_java") { - sources = [ - "org/chromium/weblayer_private/interfaces/APICallException.java", - "org/chromium/weblayer_private/interfaces/ActionModeItemType.java", - "org/chromium/weblayer_private/interfaces/BrowserFragmentArgs.java", - "org/chromium/weblayer_private/interfaces/BrowsingDataType.java", - "org/chromium/weblayer_private/interfaces/CookieChangeCause.java", - "org/chromium/weblayer_private/interfaces/DarkModeStrategy.java", - "org/chromium/weblayer_private/interfaces/DownloadError.java", - "org/chromium/weblayer_private/interfaces/DownloadState.java", - "org/chromium/weblayer_private/interfaces/ExceptionType.java", - "org/chromium/weblayer_private/interfaces/ExternalIntentInIncognitoUserDecision.java", - "org/chromium/weblayer_private/interfaces/GoogleAccountServiceType.java", - "org/chromium/weblayer_private/interfaces/LoadError.java", - "org/chromium/weblayer_private/interfaces/NavigateParams.java", - "org/chromium/weblayer_private/interfaces/NavigationState.java", - "org/chromium/weblayer_private/interfaces/NewTabType.java", - "org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java", - "org/chromium/weblayer_private/interfaces/ScrollNotificationType.java", - "org/chromium/weblayer_private/interfaces/SettingType.java", - "org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java", - ] - - deps = [ - ":base_module_interfaces_java", - "//third_party/androidx:androidx_annotation_annotation_java", - ] - - srcjar_deps = [ ":aidl" ] -} - -android_library("test_interfaces_java") { - sources = - [ "org/chromium/weblayer_private/test_interfaces/AutofillEventType.java" ] - - deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ] -} - -# Separate target to allow for a dependency on GmsCore without pulling in all of -# java classes. It compiles the abstract class; implementations are compiled -# separately. -android_library("gms_bridge_java") { - sources = [ - "org/chromium/weblayer_private/GmsBridge.java", - "org/chromium/weblayer_private/GmsBridgeImpl.java", - ] - - deps = [ - "//base:base_java", - "//components/embedder_support/android/metrics:java", - "//third_party/androidx:androidx_annotation_annotation_java", - ] - - # The appropriate .class file will be loaded via a dependency to a library - # like :gms_bridge_upstream_impl_java below. - jar_excluded_patterns = [ "*/GmsBridgeImpl.class" ] -} - -# This target compiles the implementation of GmsBridge for public targets. -android_library("gms_bridge_upstream_impl_java") { - sources = [ "org/chromium/weblayer_private/GmsBridgeImpl.java" ] - deps = [ ":gms_bridge_java" ] -} - -android_aidl("base_module_aidl") { - import_include = [ "." ] - sources = [ - "org/chromium/weblayer_private/interfaces/IChildProcessService.aidl", - "org/chromium/weblayer_private/interfaces/IObjectWrapper.aidl", - ] -} - -android_aidl("aidl") { - import_include = [ "." ] - sources = [ - "org/chromium/weblayer_private/interfaces/IBooleanCallback.aidl", - "org/chromium/weblayer_private/interfaces/IBrowser.aidl", - "org/chromium/weblayer_private/interfaces/IBrowserClient.aidl", - "org/chromium/weblayer_private/interfaces/IClientDownload.aidl", - "org/chromium/weblayer_private/interfaces/IClientNavigation.aidl", - "org/chromium/weblayer_private/interfaces/IClientPage.aidl", - "org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl", - "org/chromium/weblayer_private/interfaces/ICookieChangedCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/ICookieManager.aidl", - "org/chromium/weblayer_private/interfaces/IDownload.aidl", - "org/chromium/weblayer_private/interfaces/IDownloadCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IErrorPageCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IExternalIntentInIncognitoCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IFaviconFetcher.aidl", - "org/chromium/weblayer_private/interfaces/IFaviconFetcherClient.aidl", - "org/chromium/weblayer_private/interfaces/IFindInPageCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IFullscreenCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IGoogleAccountAccessTokenFetcherClient.aidl", - "org/chromium/weblayer_private/interfaces/IGoogleAccountsCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IMediaCaptureCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IMediaRouteDialogFragment.aidl", - "org/chromium/weblayer_private/interfaces/INavigateParams.aidl", - "org/chromium/weblayer_private/interfaces/INavigation.aidl", - "org/chromium/weblayer_private/interfaces/INavigationController.aidl", - "org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl", - "org/chromium/weblayer_private/interfaces/IOpenUrlCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IPrerenderController.aidl", - "org/chromium/weblayer_private/interfaces/IProfile.aidl", - "org/chromium/weblayer_private/interfaces/IProfileClient.aidl", - "org/chromium/weblayer_private/interfaces/IRemoteFragment.aidl", - "org/chromium/weblayer_private/interfaces/IRemoteFragmentClient.aidl", - "org/chromium/weblayer_private/interfaces/IStringCallback.aidl", - "org/chromium/weblayer_private/interfaces/ITab.aidl", - "org/chromium/weblayer_private/interfaces/ITabClient.aidl", - "org/chromium/weblayer_private/interfaces/IUserIdentityCallbackClient.aidl", - "org/chromium/weblayer_private/interfaces/IWebLayer.aidl", - "org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl", - "org/chromium/weblayer_private/interfaces/IWebLayerFactory.aidl", - ] -} - -android_aidl("test_aidl") { - import_include = [ "." ] - testonly = true - sources = - [ "org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl" ] -}
diff --git a/weblayer/browser/java/DEPS b/weblayer/browser/java/DEPS deleted file mode 100644 index 5e16562..0000000 --- a/weblayer/browser/java/DEPS +++ /dev/null
@@ -1,31 +0,0 @@ -include_rules = [ - "+components/browser_ui/browser_ui/android", - "+components/browser_ui/http_auth", - "+components/browser_ui/util/android", - "+components/component_updater/android", - "+components/content_capture/android", - "+components/content_settings/android/java", - "+components/crash/android/java", - "+components/content_relationship_verification/android/java", - "+components/external_intents", - "+components/infobars/android", - "+components/location/android/java/src/org/chromium/components/location", - "+components/minidump_uploader", - "+components/page_info/android/java", - "+components/payments/content/android", - "+components/webapk/android/libs", - "+components/webauthn/android", - "+components/image_fetcher", - "+services/device/public/java/src/org/chromium/device/geolocation", - "+ui/accessibility", - - # WebLayerNotificationWrapperBuilder should be used for all notifications. - "-components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapperCompatBuilder.java", - "-components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapperStandardBuilder.java", -] -specific_include_rules = { - "WebLayerNotificationWrapperBuilder.java": [ - "+components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapperCompatBuilder.java", - "+components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapperStandardBuilder.java", - ] -}
diff --git a/weblayer/browser/java/ResourceId.template b/weblayer/browser/java/ResourceId.template deleted file mode 100644 index 785a6b8..0000000 --- a/weblayer/browser/java/ResourceId.template +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.resources; - -import org.chromium.weblayer_private.R; - -class ResourceId { - static int[] getResourceIdList() { - int[] resourceList = { -#define LINK_RESOURCE_ID(c_id,java_id) java_id, -#define DECLARE_RESOURCE_ID(c_id,java_id) java_id, -#include "components/resources/android/blocked_content_resource_id.h" -#include "components/resources/android/page_info_resource_id.h" -#include "components/resources/android/permissions_resource_id.h" -#include "components/resources/android/sms_resource_id.h" -#include "components/resources/android/webxr_resource_id.h" - }; - return resourceList; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ApplicationInfoHelper.java b/weblayer/browser/java/org/chromium/weblayer_private/ApplicationInfoHelper.java deleted file mode 100644 index bda079c..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ApplicationInfoHelper.java +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; - -import org.chromium.base.ContextUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; - -/** Exposes values of metadata tags to native code. */ -@JNINamespace("weblayer") -public class ApplicationInfoHelper { - private ApplicationInfoHelper() {} - - /** - * Returns the boolean value for a metadata tag in the application's manifest. - */ - @CalledByNative - public static boolean getMetadataAsBoolean(String metadataTag, boolean defaultValue) { - Context context = ContextUtils.getApplicationContext(); - try { - ApplicationInfo info = context.getPackageManager().getApplicationInfo( - context.getPackageName(), PackageManager.GET_META_DATA); - return info.metaData.getBoolean(metadataTag, defaultValue); - } catch (NameNotFoundException exception) { - return defaultValue; - } - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ArCompositorDelegateImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/ArCompositorDelegateImpl.java deleted file mode 100644 index 66cb026..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ArCompositorDelegateImpl.java +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.view.MotionEvent; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; - -import org.chromium.components.webxr.ArCompositorDelegate; -import org.chromium.content_public.browser.WebContents; - -/** - * Weblayer-specific implementation of ArCompositorDelegate interface. - */ -public class ArCompositorDelegateImpl implements ArCompositorDelegate { - private final BrowserImpl mBrowser; - - ArCompositorDelegateImpl(WebContents webContents) { - TabImpl tab = TabImpl.fromWebContents(webContents); - mBrowser = tab.getBrowser(); - } - - @Override - public void setOverlayImmersiveArMode(boolean enabled, boolean domSurfaceNeedsConfiguring) { - BrowserViewController controller = - mBrowser.getBrowserFragment().getPossiblyNullViewController(); - if (controller != null) { - controller.setSurfaceProperties(/*requiresAlphaChannel=*/enabled, - /*zOrderMediaOverlay=*/domSurfaceNeedsConfiguring); - } - } - - @Override - public void dispatchTouchEvent(MotionEvent ev) { - BrowserViewController controller = - mBrowser.getBrowserFragment().getPossiblyNullViewController(); - if (controller != null) { - controller.getContentView().dispatchTouchEvent(ev); - } - } - - @Override - @NonNull - public ViewGroup getArSurfaceParent() { - BrowserViewController controller = - mBrowser.getBrowserFragment().getPossiblyNullViewController(); - if (controller == null) return null; - return controller.getArViewHolder(); - } - - @Override - public boolean shouldToggleArSurfaceParentVisibility() { - return true; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ArCompositorDelegateProviderImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/ArCompositorDelegateProviderImpl.java deleted file mode 100644 index 112b5b0..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ArCompositorDelegateProviderImpl.java +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.components.webxr.ArCompositorDelegate; -import org.chromium.components.webxr.ArCompositorDelegateProvider; -import org.chromium.content_public.browser.WebContents; - -/** - * Weblayer-specific implementation of ArCompositorDelegateProvider interface. - */ -@JNINamespace("weblayer") -public class ArCompositorDelegateProviderImpl implements ArCompositorDelegateProvider { - @CalledByNative - public ArCompositorDelegateProviderImpl() {} - - @Override - public ArCompositorDelegate create(WebContents webContents) { - return new ArCompositorDelegateImpl(webContents); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java b/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java deleted file mode 100644 index f6cc76a..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.pm.PackageManager; -import android.os.Bundle; - -import org.chromium.base.PackageUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; - -@JNINamespace("weblayer") -class ArCoreVersionUtils { - // Corresponds to V1.32. Must be updated if the arcore version in - // //third_party/arcore-android-sdk-client is rolled. - private static final int MIN_APK_VERSION = 221020000; - - private static final String AR_CORE_PACKAGE = "com.google.ar.core"; - private static final String METADATA_KEY_MIN_APK_VERSION = "com.google.ar.core.min_apk_version"; - - @CalledByNative - public static boolean isEnabled() { - // If the appropriate metadata entries are not present in the app manifest, the feature - // should be disabled. - Bundle metaData = PackageUtils.getApplicationPackageInfo(PackageManager.GET_META_DATA) - .applicationInfo.metaData; - return metaData.containsKey(AR_CORE_PACKAGE) - && metaData.containsKey(METADATA_KEY_MIN_APK_VERSION) && isInstalledAndCompatible(); - } - - @CalledByNative - public static boolean isInstalledAndCompatible() { - return PackageUtils.getPackageVersion(AR_CORE_PACKAGE) >= MIN_APK_VERSION; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/AutocompleteSchemeClassifierImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/AutocompleteSchemeClassifierImpl.java deleted file mode 100644 index 77221f4..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/AutocompleteSchemeClassifierImpl.java +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.LifetimeAssert; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.omnibox.AutocompleteSchemeClassifier; - -/** - * Creates the c++ class that provides scheme classification logic for WebLayer - * Must call destroy() after using this object to delete the native object. - */ -@JNINamespace("weblayer") -public class AutocompleteSchemeClassifierImpl extends AutocompleteSchemeClassifier { - private final LifetimeAssert mLifetimeAssert = LifetimeAssert.create(this); - - public AutocompleteSchemeClassifierImpl() { - super(AutocompleteSchemeClassifierImplJni.get().createAutocompleteClassifier()); - } - - @Override - public void destroy() { - super.destroy(); - - AutocompleteSchemeClassifierImplJni.get().deleteAutocompleteClassifier( - super.getNativePtr()); - - // If mLifetimeAssert is GC'ed before this is called, it will throw an exception - // with a stack trace showing the stack during LifetimeAssert.create(). - LifetimeAssert.setSafeToGc(mLifetimeAssert, true); - } - - @NativeMethods - interface Natives { - long createAutocompleteClassifier(); - void deleteAutocompleteClassifier(long weblayerAutocompleteSchemeClassifier); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java deleted file mode 100644 index 0062a03..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java +++ /dev/null
@@ -1,309 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.SystemClock; -import android.view.ContextThemeWrapper; -import android.view.SurfaceControlViewHost; -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; - -import org.chromium.base.ContextUtils; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory; -import org.chromium.components.embedder_support.view.ContentView; -import org.chromium.ui.base.IntentRequestTracker; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -/** - * Implementation of RemoteFragmentImpl which provides the Fragment implementation for BrowserImpl. - */ -@JNINamespace("weblayer") -public class BrowserFragmentImpl extends FragmentHostingRemoteFragmentImpl { - private long mNativeBrowserFragmentImpl; - - private static int sResumedCount; - private static long sSessionStartTimeMs; - - private BrowserImpl mBrowser; - - private BrowserViewController mViewController; - - private LocaleChangedBroadcastReceiver mLocaleReceiver; - - private boolean mViewAttachedToWindow; - - private int mMinimumSurfaceWidth; - private int mMinimumSurfaceHeight; - - private FragmentWindowAndroid mWindowAndroid; - private Context mEmbedderContext; - - // Tracks whether the fragment is in the middle of a configuration change when stopped. During - // a configuration change the fragment goes through a full lifecycle and usually the webContents - // is hidden when detached and shown again when re-attached. Tracking the configuration change - // allows continuing to show the WebContents (still following all other lifecycle events as - // normal), which allows continuous playback of videos. - private boolean mInConfigurationChangeAndWasAttached; - - /** - * @param windowAndroid a window that was created by a {@link BrowserFragmentImpl}. It's not - * valid to call this method with other {@link WindowAndroid} instances. Typically this - * should be the {@link WindowAndroid} of a {@link WebContents}. - * @return the associated BrowserImpl instance. - */ - public static BrowserFragmentImpl fromWindowAndroid(WindowAndroid windowAndroid) { - assert windowAndroid instanceof FragmentWindowAndroid; - return ((FragmentWindowAndroid) windowAndroid).getFragment(); - } - - public BrowserFragmentImpl(BrowserImpl browser, Context context) { - super(context); - - mBrowser = browser; - mWindowAndroid = new FragmentWindowAndroid(getWebLayerContext(), this); - - mNativeBrowserFragmentImpl = BrowserFragmentImplJni.get().createBrowserFragment(); - } - - private void createAttachmentState(Context embedderContext) { - assert mViewController == null; - - mViewController = new BrowserViewController(embedderContext, mWindowAndroid, false); - mViewController.setMinimumSurfaceSize(mMinimumSurfaceWidth, mMinimumSurfaceHeight); - mViewAttachedToWindow = true; - - mLocaleReceiver = new LocaleChangedBroadcastReceiver(mWindowAndroid.getContext().get()); - } - - private void destroyAttachmentState() { - if (mLocaleReceiver != null) { - mLocaleReceiver.destroy(); - mLocaleReceiver = null; - } - if (mViewController != null) { - mViewController.destroy(); - mViewController = null; - mViewAttachedToWindow = false; - mBrowser.updateAllTabsViewAttachedState(); - } - } - - @Override - protected void onCreate() { - StrictModeWorkaround.apply(); - super.onCreate(); - } - - @Override - protected void onStart() { - StrictModeWorkaround.apply(); - super.onStart(); - mBrowser.updateAllTabs(); - } - - @Override - protected void onPause() { - super.onPause(); - sResumedCount--; - if (sResumedCount == 0) { - long deltaMs = SystemClock.uptimeMillis() - sSessionStartTimeMs; - RecordHistogram.recordLongTimesHistogram("Session.TotalDuration", deltaMs); - } - BrowserFragmentImplJni.get().onFragmentPause(mNativeBrowserFragmentImpl); - } - - @Override - protected void onResume() { - super.onResume(); - sResumedCount++; - if (sResumedCount == 1) sSessionStartTimeMs = SystemClock.uptimeMillis(); - WebLayerAccessibilityUtil.get().onBrowserResumed(mBrowser.getProfile()); - BrowserFragmentImplJni.get().onFragmentResume(mNativeBrowserFragmentImpl); - } - - @Override - protected void onAttach(Context embedderContext) { - StrictModeWorkaround.apply(); - super.onAttach(embedderContext); - mEmbedderContext = embedderContext; - - mInConfigurationChangeAndWasAttached = false; - - setMinimumSurfaceSize(mMinimumSurfaceWidth, mMinimumSurfaceHeight); - - createAttachmentState(embedderContext); - - mBrowser.updateAllTabs(); - setActiveTab(mBrowser.getActiveTab()); - mBrowser.checkPreferences(); - } - - @Override - protected void onDetach() { - StrictModeWorkaround.apply(); - super.onDetach(); - mEmbedderContext = null; - destroyAttachmentState(); - mBrowser.updateAllTabs(); - } - - @Override - protected void onStop() { - super.onStop(); - Activity activity = ContextUtils.activityFromContext(mEmbedderContext); - if (activity != null) { - mInConfigurationChangeAndWasAttached = activity.getChangingConfigurations() != 0; - } - - mBrowser.updateAllTabs(); - } - - @Override - protected void onDestroy() { - StrictModeWorkaround.apply(); - super.onDestroy(); - } - - @Override - public boolean startActivityForResult(Intent intent, int requestCode, Bundle options) { - try { - return mClient.startActivityForResult( - ObjectWrapper.wrap(intent), requestCode, ObjectWrapper.wrap(options)); - } catch (RemoteException e) { - } - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - StrictModeWorkaround.apply(); - if (mWindowAndroid != null) { - IntentRequestTracker tracker = mWindowAndroid.getIntentRequestTracker(); - assert tracker != null; - tracker.onActivityResult(requestCode, resultCode, data); - } - } - - @Override - protected void onRequestPermissionsResult( - int requestCode, String[] permissions, int[] grantResults) { - StrictModeWorkaround.apply(); - if (mWindowAndroid != null) { - mWindowAndroid.handlePermissionResult(requestCode, permissions, grantResults); - } - } - - @RequiresApi(Build.VERSION_CODES.R) - @Override - protected void setSurfaceControlViewHost(SurfaceControlViewHost host) { - // TODO(rayankans): Handle fallback for older devices. - host.setView(getViewController().getView(), 0, 0); - } - - @Override - protected View getContentViewRenderView() { - return getViewController().getView(); - } - - @Override - public void setMinimumSurfaceSize(int width, int height) { - StrictModeWorkaround.apply(); - mMinimumSurfaceWidth = width; - mMinimumSurfaceHeight = height; - if (mViewController == null) return; - mViewController.setMinimumSurfaceSize(width, height); - } - - // Only call this if it's guaranteed that Browser is attached to an activity. - @NonNull - public BrowserViewController getViewController() { - if (mViewController == null) { - throw new RuntimeException("Currently Tab requires Activity context, so " - + "it exists only while WebFragment is attached to an Activity"); - } - return mViewController; - } - - @Nullable - public BrowserViewController getPossiblyNullViewController() { - return mViewController; - } - - public BrowserImpl getBrowser() { - return mBrowser; - } - - void setActiveTab(TabImpl tab) { - if (mViewController == null) return; - mViewController.setActiveTab(tab); - } - - boolean compositorHasSurface() { - if (mViewController == null) return false; - return mViewController.compositorHasSurface(); - } - - @Nullable - ContentView getViewAndroidDelegateContainerView() { - if (mViewController == null) return null; - return mViewController.getContentView(); - } - - FragmentWindowAndroid getWindowAndroid() { - return mWindowAndroid; - } - - boolean isAttached() { - return mViewAttachedToWindow; - } - - /** - * Returns true if the Fragment should be considered visible. - */ - boolean isVisible() { - return mInConfigurationChangeAndWasAttached || mViewAttachedToWindow; - } - - void shutdown() { - destroyAttachmentState(); - - if (mWindowAndroid != null) { - mWindowAndroid.destroy(); - mWindowAndroid = null; - } - BrowserFragmentImplJni.get().deleteBrowserFragment(mNativeBrowserFragmentImpl); - } - - @Override - protected FragmentHostingRemoteFragmentImpl.RemoteFragmentContext createRemoteFragmentContext( - Context embedderContext) { - Context wrappedContext = ClassLoaderContextWrapperFactory.get(embedderContext); - Context themedContext = - new ContextThemeWrapper(wrappedContext, R.style.Theme_WebLayer_Settings); - return new FragmentHostingRemoteFragmentImpl.RemoteFragmentContext(themedContext); - } - - @NativeMethods - interface Natives { - long createBrowserFragment(); - void onFragmentResume(long nativeBrowserFragmentImpl); - void onFragmentPause(long nativeBrowserFragmentImpl); - void deleteBrowserFragment(long nativeBrowserFragmentImpl); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java deleted file mode 100644 index 0043eab..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java +++ /dev/null
@@ -1,436 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.content.res.Configuration; -import android.os.Bundle; -import android.os.RemoteException; -import android.provider.Settings; -import android.text.TextUtils; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.base.ObserverList; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.embedder_support.util.Origin; -import org.chromium.ui.base.DeviceFormFactor; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.weblayer_private.interfaces.BrowserFragmentArgs; -import org.chromium.weblayer_private.interfaces.DarkModeStrategy; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IBrowserClient; -import org.chromium.weblayer_private.interfaces.IMediaRouteDialogFragment; -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; -import org.chromium.weblayer_private.media.MediaRouteDialogFragmentImpl; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Implementation of {@link IBrowser}. - */ -@JNINamespace("weblayer") -public class BrowserImpl extends IBrowser.Stub { - private final ObserverList<VisibleSecurityStateObserver> mVisibleSecurityStateObservers = - new ObserverList<VisibleSecurityStateObserver>(); - - // Number of instances that have not been destroyed. - private static int sInstanceCount; - - private long mNativeBrowser; - private final ProfileImpl mProfile; - private final boolean mIsExternalIntentsEnabled; - private Context mServiceContext; - - private @Nullable List<Origin> mAllowedOrigins; - - private IBrowserClient mClient; - private boolean mInDestroy; - - // Cache the value instead of querying system every time. - private Boolean mPasswordEchoEnabled; - private Boolean mDarkThemeEnabled; - @DarkModeStrategy - private int mDarkModeStrategy = DarkModeStrategy.WEB_THEME_DARKENING_ONLY; - private Float mFontScale; - - // Created in the constructor from saved state. - private FullPersistenceInfo mFullPersistenceInfo; - - private BrowserFragmentImpl mBrowserFragmentImpl; - - // This persistence state is saved to disk, and loaded async. - private static final class FullPersistenceInfo { - String mPersistenceId; - }; - /** - * Allows observing of visible security state of the active tab. - */ - public static interface VisibleSecurityStateObserver { - public void onVisibleSecurityStateOfActiveTabChanged(); - } - public void addVisibleSecurityStateObserver(VisibleSecurityStateObserver observer) { - mVisibleSecurityStateObservers.addObserver(observer); - } - public void removeVisibleSecurityStateObserver(VisibleSecurityStateObserver observer) { - mVisibleSecurityStateObservers.removeObserver(observer); - } - - public BrowserImpl(Context serviceContext, ProfileManager profileManager, Bundle fragmentArgs) { - ++sInstanceCount; - mServiceContext = serviceContext; - - String persistenceId = fragmentArgs.getString(BrowserFragmentArgs.PERSISTENCE_ID); - String name = fragmentArgs.getString(BrowserFragmentArgs.PROFILE_NAME); - - boolean isIncognito; - if (fragmentArgs.containsKey(BrowserFragmentArgs.IS_INCOGNITO)) { - isIncognito = fragmentArgs.getBoolean(BrowserFragmentArgs.IS_INCOGNITO, false); - } else { - isIncognito = "".equals(name); - } - mProfile = profileManager.getProfile(name, isIncognito); - - mProfile.checkNotDestroyed(); // TODO(swestphal): or mProfile != null - - mIsExternalIntentsEnabled = - fragmentArgs.getBoolean(BrowserFragmentArgs.IS_EXTERNAL_INTENTS_ENABLED); - - List<String> allowedOriginStrings = - fragmentArgs.getStringArrayList(BrowserFragmentArgs.ALLOWED_ORIGINS); - if (allowedOriginStrings != null) { - mAllowedOrigins = new ArrayList<Origin>(); - - for (String allowedOriginString : allowedOriginStrings) { - Origin allowedOrigin = Origin.create(allowedOriginString); - if (allowedOrigin != null) { - mAllowedOrigins.add(allowedOrigin); - } - } - } - - if (!isIncognito && !TextUtils.isEmpty(persistenceId)) { - mFullPersistenceInfo = new FullPersistenceInfo(); - mFullPersistenceInfo.mPersistenceId = persistenceId; - } - - mNativeBrowser = BrowserImplJni.get().createBrowser( - mProfile.getNativeProfile(), serviceContext.getPackageName(), this); - mPasswordEchoEnabled = null; - } - - @Override - public IRemoteFragment createBrowserFragmentImpl() { - StrictModeWorkaround.apply(); - mBrowserFragmentImpl = new BrowserFragmentImpl(this, mServiceContext); - return mBrowserFragmentImpl; - } - - @Override - public IMediaRouteDialogFragment createMediaRouteDialogFragmentImpl() { - StrictModeWorkaround.apply(); - MediaRouteDialogFragmentImpl fragment = new MediaRouteDialogFragmentImpl(mServiceContext); - return fragment.asIMediaRouteDialogFragment(); - } - - public Context getContext() { - return mBrowserFragmentImpl.getWebLayerContext(); - } - - @Override - public TabImpl createTab() { - StrictModeWorkaround.apply(); - TabImpl tab = new TabImpl(this, mProfile, mBrowserFragmentImpl.getWindowAndroid()); - // This needs |alwaysAdd| set to true as the Tab is created with the Browser already set to - // this. - addTab(tab, /* alwaysAdd */ true); - return tab; - } - - @Override - @NonNull - public ProfileImpl getProfile() { - StrictModeWorkaround.apply(); - return mProfile; - } - - @Override - public void addTab(ITab iTab) { - StrictModeWorkaround.apply(); - addTab((TabImpl) iTab, /* alwaysAdd */ false); - } - - private void addTab(TabImpl tab, boolean alwaysAdd) { - if (!alwaysAdd && tab.getBrowser() == this) return; - BrowserImplJni.get().addTab(mNativeBrowser, tab.getNativeTab()); - } - - @CalledByNative - private void createJavaTabForNativeTab(long nativeTab) { - new TabImpl(this, mProfile, mBrowserFragmentImpl.getWindowAndroid(), nativeTab); - } - - void checkPreferences() { - boolean changed = false; - if (mPasswordEchoEnabled != null) { - boolean oldEnabled = mPasswordEchoEnabled; - mPasswordEchoEnabled = null; - boolean newEnabled = getPasswordEchoEnabled(); - changed = changed || oldEnabled != newEnabled; - } - if (mDarkThemeEnabled != null) { - boolean oldEnabled = mDarkThemeEnabled; - mDarkThemeEnabled = null; - boolean newEnabled = getDarkThemeEnabled(); - changed = changed || oldEnabled != newEnabled; - } - if (changed) { - BrowserImplJni.get().webPreferencesChanged(mNativeBrowser); - } - } - - @CalledByNative - private boolean getPasswordEchoEnabled() { - Context context = getContext(); - if (context == null) return false; - if (mPasswordEchoEnabled == null) { - mPasswordEchoEnabled = Settings.System.getInt(context.getContentResolver(), - Settings.System.TEXT_SHOW_PASSWORD, 1) - == 1; - } - return mPasswordEchoEnabled; - } - - @CalledByNative - boolean getDarkThemeEnabled() { - if (mServiceContext == null) return false; - if (mDarkThemeEnabled == null) { - if (mServiceContext == null) return false; - int uiMode = mServiceContext.getApplicationContext() - .getResources() - .getConfiguration() - .uiMode; - mDarkThemeEnabled = - (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; - } - return mDarkThemeEnabled; - } - - @CalledByNative - private void onTabAdded(TabImpl tab) throws RemoteException { - tab.attachToBrowser(this); - if (mClient != null) mClient.onTabAdded(tab); - } - - @CalledByNative - private void onActiveTabChanged(TabImpl tab) throws RemoteException { - mBrowserFragmentImpl.setActiveTab(tab); - if (!mInDestroy && mClient != null) { - mClient.onActiveTabChanged(tab != null ? tab.getId() : 0); - } - } - - @CalledByNative - private void onTabRemoved(TabImpl tab) throws RemoteException { - if (mInDestroy) return; - if (mClient != null) mClient.onTabRemoved(tab.getId()); - // This doesn't reset state on TabImpl as |browser| is either about to be - // destroyed, or switching to a different fragment. - } - - @CalledByNative - private void onVisibleSecurityStateOfActiveTabChanged() { - for (VisibleSecurityStateObserver observer : mVisibleSecurityStateObservers) { - observer.onVisibleSecurityStateOfActiveTabChanged(); - } - } - - @CalledByNative - private boolean compositorHasSurface() { - return mBrowserFragmentImpl.compositorHasSurface(); - } - - @Override - public boolean setActiveTab(ITab iTab) { - StrictModeWorkaround.apply(); - TabImpl tab = (TabImpl) iTab; - if (tab != null && tab.getBrowser() != this) return false; - BrowserImplJni.get().setActiveTab(mNativeBrowser, tab != null ? tab.getNativeTab() : 0); - mBrowserFragmentImpl.setActiveTab(tab); - return true; - } - - public @Nullable TabImpl getActiveTab() { - return BrowserImplJni.get().getActiveTab(mNativeBrowser); - } - - @Override - public List<TabImpl> getTabs() { - StrictModeWorkaround.apply(); - return Arrays.asList(BrowserImplJni.get().getTabs(mNativeBrowser)); - } - - @Override - public int getActiveTabId() { - StrictModeWorkaround.apply(); - return getActiveTab() != null ? getActiveTab().getId() : 0; - } - - @Override - public int[] getTabIds() { - StrictModeWorkaround.apply(); - List<TabImpl> tabs = getTabs(); - int[] ids = new int[tabs.size()]; - for(int i = 0; i < tabs.size(); i++) { - ids[i] = tabs.get(i).getId(); - } - return ids; - } - - boolean isExternalIntentsEnabled() { - return mIsExternalIntentsEnabled; - } - - boolean isUrlAllowed(String url) { - // Defaults to all origins being allowed if a developer list is not provided. - if (mAllowedOrigins == null) { - return true; - } - - return mAllowedOrigins.contains(Origin.create(url)); - } - - public boolean isWindowOnSmallDevice() { - WindowAndroid windowAndroid = mBrowserFragmentImpl.getWindowAndroid(); - assert windowAndroid != null; - return !DeviceFormFactor.isWindowOnTablet(windowAndroid); - } - - @Override - public void setClient(IBrowserClient client) { - // This function is called from the client once everything has been setup (meaning all the - // client classes have been created and AIDL interfaces established in both directions). - // This function is called immediately after the constructor of BrowserImpl from the client. - - StrictModeWorkaround.apply(); - mClient = client; - - if (mFullPersistenceInfo != null) { - FullPersistenceInfo persistenceInfo = mFullPersistenceInfo; - mFullPersistenceInfo = null; - BrowserImplJni.get().restoreStateIfNecessary( - mNativeBrowser, persistenceInfo.mPersistenceId); - } else { - boolean setActiveResult = setActiveTab(createTab()); - assert setActiveResult; - try { - onTabInitializationCompleted(); - } catch (RemoteException e) { - } - } - } - - @Override - public void destroyTab(ITab iTab) { - StrictModeWorkaround.apply(); - TabImpl tab = (TabImpl) iTab; - if (tab.getBrowser() != this) return; - destroyTabImpl((TabImpl) iTab); - } - - @CalledByNative - private void destroyTabImpl(TabImpl tab) { - tab.destroy(); - } - - @Override - public void setDarkModeStrategy(@DarkModeStrategy int strategy) { - StrictModeWorkaround.apply(); - if (mDarkModeStrategy == strategy) { - return; - } - mDarkModeStrategy = strategy; - BrowserImplJni.get().webPreferencesChanged(mNativeBrowser); - } - - @CalledByNative - int getDarkModeStrategy() { - return mDarkModeStrategy; - } - - @Override - public boolean isRestoringPreviousState() { - StrictModeWorkaround.apply(); - return BrowserImplJni.get().isRestoringPreviousState(mNativeBrowser); - } - - @CalledByNative - private void onRestoreCompleted() throws RemoteException { - mClient.onTabInitializationCompleted(); - } - - private void onTabInitializationCompleted() throws RemoteException { - mClient.onTabInitializationCompleted(); - } - - @Override - public void shutdown() { - StrictModeWorkaround.apply(); - mInDestroy = true; - - BrowserImplJni.get().prepareForShutdown(mNativeBrowser); - - for (Object tab : getTabs()) { - destroyTabImpl((TabImpl) tab); - } - mBrowserFragmentImpl.shutdown(); - BrowserImplJni.get().deleteBrowser(mNativeBrowser); - - mVisibleSecurityStateObservers.clear(); - - --sInstanceCount; - } - - void updateAllTabsViewAttachedState() { - for (Object tab : getTabs()) { - ((TabImpl) tab).updateViewAttachedStateFromBrowser(); - } - } - - void updateAllTabs() { - for (Object tab : getTabs()) { - ((TabImpl) tab).updateFromBrowser(); - } - } - - long getNativeBrowser() { - return mNativeBrowser; - } - - public BrowserFragmentImpl getBrowserFragment() { - return mBrowserFragmentImpl; - } - - @NativeMethods - interface Natives { - long createBrowser(long profile, String packageName, BrowserImpl caller); - void deleteBrowser(long browser); - void addTab(long nativeBrowserImpl, long nativeTab); - TabImpl[] getTabs(long nativeBrowserImpl); - void setActiveTab(long nativeBrowserImpl, long nativeTab); - TabImpl getActiveTab(long nativeBrowserImpl); - void prepareForShutdown(long nativeBrowserImpl); - void restoreStateIfNecessary(long nativeBrowserImpl, String persistenceId); - void webPreferencesChanged(long nativeBrowserImpl); - boolean isRestoringPreviousState(long nativeBrowserImpl); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserList.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserList.java deleted file mode 100644 index 7f99d7ce..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserList.java +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import androidx.annotation.NonNull; - -import org.chromium.base.ObserverList; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; - -/** - * Tracks the set of Browsers. - */ -@JNINamespace("weblayer") -public final class BrowserList { - private static BrowserList sInstance; - private final ObserverList<BrowserListObserver> mObservers; - - @CalledByNative - private static BrowserList createBrowserList() { - // The native side should call this only once. - assert sInstance == null; - sInstance = new BrowserList(); - return sInstance; - } - - @NonNull - public static BrowserList getInstance() { - // The native side creates this early on. It should never be null. - if (sInstance == null) { - BrowserListJni.get().createBrowserList(); - assert sInstance != null; - } - return sInstance; - } - - private BrowserList() { - mObservers = new ObserverList<>(); - } - - public void addObserver(BrowserListObserver o) { - mObservers.addObserver(o); - } - - public void removeObserver(BrowserListObserver o) { - mObservers.removeObserver(o); - } - - @CalledByNative - private void onBrowserCreated(BrowserImpl browser) { - for (BrowserListObserver observer : mObservers) { - observer.onBrowserCreated(browser); - } - } - - @CalledByNative - private void onBrowserDestroyed(BrowserImpl browser) { - for (BrowserListObserver observer : mObservers) { - observer.onBrowserDestroyed(browser); - } - } - - @NativeMethods - interface Natives { - void createBrowserList(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserListObserver.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserListObserver.java deleted file mode 100644 index a7f0eac..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserListObserver.java +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -/** - * Notified of changes to BrowserList. - */ -public interface BrowserListObserver { - void onBrowserCreated(BrowserImpl browser); - void onBrowserDestroyed(BrowserImpl browser); -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java b/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java deleted file mode 100644 index 581384b..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java +++ /dev/null
@@ -1,376 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Activity; -import android.content.Context; -import android.content.res.Resources; -import android.os.RemoteException; -import android.util.AndroidRuntimeException; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.widget.FrameLayout; -import android.widget.RelativeLayout; - -import org.chromium.base.ContextUtils; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerFactory; -import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver; -import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; -import org.chromium.components.browser_ui.bottomsheet.ManagedBottomSheetController; -import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; -import org.chromium.components.browser_ui.widget.InsetObserverView; -import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; -import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator.SystemUiScrimDelegate; -import org.chromium.components.content_capture.ContentCaptureConsumer; -import org.chromium.components.content_capture.OnscreenContentProvider; -import org.chromium.components.embedder_support.view.ContentView; -import org.chromium.components.webapps.bottomsheet.PwaBottomSheetController; -import org.chromium.components.webapps.bottomsheet.PwaBottomSheetControllerFactory; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.KeyboardVisibilityDelegate; -import org.chromium.ui.modaldialog.DialogDismissalCause; -import org.chromium.ui.modaldialog.ModalDialogManager; -import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; -import org.chromium.ui.modaldialog.ModalDialogProperties; -import org.chromium.ui.modaldialog.SimpleModalDialogController; -import org.chromium.ui.modelutil.PropertyModel; -import org.chromium.ui.util.TokenHolder; - -/** - * BrowserViewController controls the set of Views needed to show the WebContents. - */ -@JNINamespace("weblayer") -public final class BrowserViewController - implements WebContentsGestureStateTracker.OnGestureStateChangedListener, - ModalDialogManager.ModalDialogManagerObserver { - private final ContentViewRenderView mContentViewRenderView; - - private final Context mWeblayerContext; - - // Child of mContentViewRenderView. Be very careful adding Views to this, as any Views are not - // accessible (ContentView provides it's own accessible implementation that interacts with - // WebContents). - private final ContentView mContentView; - // Child of mContentViewRenderView, holds the SurfaceView for WebXR. - private final FrameLayout mArViewHolder; - // Other child of mContentViewRenderView, which holds views that sit on top of the web contents, - // such as tab modal dialogs. - private final FrameLayout mWebContentsOverlayView; - - private final FragmentWindowAndroid mWindowAndroid; - private final ModalDialogManager mModalDialogManager; - - private final ScrimCoordinator mScrim; - - private final ViewGroup mBottomSheetContainer; - private final ManagedBottomSheetController mBottomSheetController; - private final BottomSheetObserver mBottomSheetObserver; - - private PwaBottomSheetController mPwaBottomSheetController; - - private TabImpl mTab; - - private WebContentsGestureStateTracker mGestureStateTracker; - - private OnscreenContentProvider mOnscreenContentProvider; - - public BrowserViewController(Context embedderContext, FragmentWindowAndroid windowAndroid, - boolean recreateForConfigurationChange) { - mWindowAndroid = windowAndroid; - - mWeblayerContext = windowAndroid.getContext().get(); - - mContentViewRenderView = - new ContentViewRenderView(embedderContext, recreateForConfigurationChange); - - mContentViewRenderView.onNativeLibraryLoaded(mWindowAndroid); - mContentView = ContentViewWithAutofill.createContentView(embedderContext, null); - mContentViewRenderView.addView(mContentView, - new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, - RelativeLayout.LayoutParams.MATCH_PARENT)); - - mArViewHolder = new FrameLayout(embedderContext); - mArViewHolder.setVisibility(View.GONE); - mContentViewRenderView.addView(mArViewHolder, - new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - - mWebContentsOverlayView = new FrameLayout(embedderContext); - RelativeLayout.LayoutParams overlayParams = new RelativeLayout.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - mContentViewRenderView.addView(mWebContentsOverlayView, overlayParams); - mWindowAndroid.setAnimationPlaceholderView(mWebContentsOverlayView); - - mModalDialogManager = new ModalDialogManager( - new AppModalPresenter(mWeblayerContext), ModalDialogManager.ModalDialogType.APP); - - mModalDialogManager.addObserver(this); - mModalDialogManager.registerPresenter( - new WebLayerTabModalPresenter(this, mWeblayerContext), ModalDialogType.TAB); - - mWindowAndroid.setModalDialogManager(mModalDialogManager); - - SystemUiScrimDelegate systemUiDelegate = new SystemUiScrimDelegate() { - @Override - public void setStatusBarScrimFraction(float scrimFraction) { - // TODO(mdjones): Support status bar tinting if it is needed by WebLayer. - } - - @Override - public void setNavigationBarScrimFraction(float scrimFraction) {} - }; - mScrim = new ScrimCoordinator(embedderContext, systemUiDelegate, mContentViewRenderView, - mWeblayerContext.getResources().getColor(R.color.default_scrim_color)); - mBottomSheetContainer = new FrameLayout(mWeblayerContext); - mBottomSheetContainer.setLayoutParams( - new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - mBottomSheetContainer.setClipChildren(false); - mBottomSheetContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View view, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - // Allow the sheet container to layout once before hiding it until it is used. - mBottomSheetContainer.setVisibility(View.GONE); - mBottomSheetContainer.removeOnLayoutChangeListener(this); - } - }); - mContentViewRenderView.addView(mBottomSheetContainer); - - Activity activity = ContextUtils.activityFromContext(embedderContext); - if (activity == null) { - // TODO(rayankans): Remove assumptions about Activity from BottomSheetController. - mBottomSheetController = null; - mPwaBottomSheetController = null; - mBottomSheetObserver = null; - return; - } - mBottomSheetController = BottomSheetControllerFactory.createBottomSheetController( - () -> mScrim, (v) -> {}, activity.getWindow(), - KeyboardVisibilityDelegate.getInstance(), () -> mBottomSheetContainer); - BottomSheetControllerFactory.attach(mWindowAndroid, mBottomSheetController); - - mPwaBottomSheetController = - PwaBottomSheetControllerFactory.createPwaBottomSheetController(mWeblayerContext); - PwaBottomSheetControllerFactory.attach(mWindowAndroid, mPwaBottomSheetController); - mBottomSheetObserver = new EmptyBottomSheetObserver() { - /** A token for suppressing app modal dialogs. */ - private int mAppModalToken = TokenHolder.INVALID_TOKEN; - - /** A token for suppressing tab modal dialogs. */ - private int mTabModalToken = TokenHolder.INVALID_TOKEN; - - @Override - public void onSheetOpened(int reason) { - assert mAppModalToken == TokenHolder.INVALID_TOKEN; - assert mTabModalToken == TokenHolder.INVALID_TOKEN; - mAppModalToken = - mModalDialogManager.suspendType(ModalDialogManager.ModalDialogType.APP); - mTabModalToken = - mModalDialogManager.suspendType(ModalDialogManager.ModalDialogType.TAB); - } - - @Override - public void onSheetClosed(int reason) { - if (mAppModalToken != TokenHolder.INVALID_TOKEN - || mTabModalToken != TokenHolder.INVALID_TOKEN) { - // If one modal dialog token is set, the other should be as well. - assert mAppModalToken != TokenHolder.INVALID_TOKEN - && mTabModalToken != TokenHolder.INVALID_TOKEN; - mModalDialogManager.resumeType( - ModalDialogManager.ModalDialogType.APP, mAppModalToken); - mModalDialogManager.resumeType( - ModalDialogManager.ModalDialogType.TAB, mTabModalToken); - } - mAppModalToken = TokenHolder.INVALID_TOKEN; - mTabModalToken = TokenHolder.INVALID_TOKEN; - } - }; - mBottomSheetController.addObserver(mBottomSheetObserver); - } - - public void destroy() { - if (mBottomSheetController != null) { - BottomSheetControllerFactory.detach(mBottomSheetController); - mBottomSheetController.removeObserver(mBottomSheetObserver); - PwaBottomSheetControllerFactory.detach(mPwaBottomSheetController); - } - mWindowAndroid.setModalDialogManager(null); - setActiveTab(null); - if (mOnscreenContentProvider != null) mOnscreenContentProvider.destroy(); - mContentViewRenderView.destroy(); - } - - /** Returns top-level View this Controller works with */ - public View getView() { - return mContentViewRenderView; - } - - public InsetObserverView getInsetObserverView() { - return mContentViewRenderView.getInsetObserverView(); - } - - /** Returns the ViewGroup into which the InfoBarContainer should be parented. **/ - public ViewGroup getInfoBarContainerParentView() { - return mContentViewRenderView; - } - - public ContentView getContentView() { - return mContentView; - } - - public FrameLayout getWebContentsOverlayView() { - return mWebContentsOverlayView; - } - - public ViewGroup getArViewHolder() { - return mArViewHolder; - } - - public void setSurfaceProperties(boolean requiresAlphaChannel, boolean zOrderMediaOverlay) { - mContentViewRenderView.setSurfaceProperties(requiresAlphaChannel, zOrderMediaOverlay); - } - - // Returns the index at which the infobar container view should be inserted. - public int getDesiredInfoBarContainerViewIndex() { - // Ensure that infobars are positioned behind WebContents overlays in z-order. - // TODO(blundell): Should infobars instead be hidden while a WebContents overlay is - // presented? - return mContentViewRenderView.indexOfChild(mWebContentsOverlayView) - 1; - } - - public void setActiveTab(TabImpl tab) { - if (tab == mTab) return; - - if (mTab != null) { - mTab.onDetachedFromViewController(); - // WebContentsGestureStateTracker is relatively cheap, easier to destroy rather than - // update WebContents. - mGestureStateTracker.destroy(); - mGestureStateTracker = null; - } - - mModalDialogManager.dismissDialogsOfType( - ModalDialogType.TAB, DialogDismissalCause.TAB_SWITCHED); - - mTab = tab; - WebContents webContents = mTab != null ? mTab.getWebContents() : null; - // Create the WebContentsGestureStateTracker before setting the WebContents on - // the views as they may call back to this class. - if (mTab != null) { - mGestureStateTracker = - new WebContentsGestureStateTracker(mContentView, webContents, this); - } - mContentView.setWebContents(webContents); - - mContentViewRenderView.setWebContents(webContents); - if (mTab != null) { - mTab.onAttachedToViewController(); - mContentView.requestFocus(); - } - - if (mOnscreenContentProvider == null) { - mOnscreenContentProvider = new OnscreenContentProvider( - mWeblayerContext, mContentViewRenderView, webContents); - } else { - mOnscreenContentProvider.onWebContentsChanged(webContents); - } - } - - public TabImpl getTab() { - return mTab; - } - - public void addContentCaptureConsumerForTesting(ContentCaptureConsumer consumer) { - mOnscreenContentProvider.addConsumer(consumer); - } - - public boolean compositorHasSurface() { - return mContentViewRenderView.hasSurface(); - } - - public void setWebContentIsObscured(boolean isObscured) { - mContentView.setIsObscuredForAccessibility(isObscured); - } - - public View getViewForMagnifierReadback() { - return mContentViewRenderView.getViewForMagnifierReadback(); - } - - @Override - public void onGestureStateChanged() {} - - @Override - public void onDialogAdded(PropertyModel model) { - onDialogVisibilityChanged(true); - } - - @Override - public void onLastDialogDismissed() { - onDialogVisibilityChanged(false); - } - - private void onDialogVisibilityChanged(boolean showing) { - if (mModalDialogManager.getCurrentType() == ModalDialogType.TAB) { - // This shouldn't be called when |mTab| is null and the modal dialog type is TAB. OTOH, - // when an app-modal is displayed for a javascript dialog, this method can be called - // after the tab is destroyed. - assert mTab != null; - try { - mTab.getClient().onTabModalStateChanged(showing); - } catch (RemoteException e) { - throw new AndroidRuntimeException(e); - } - } - } - - public void setMinimumSurfaceSize(int width, int height) { - mContentViewRenderView.setMinimumSurfaceSize(width, height); - } - - /** - * @return true if a tab modal was showing and has been dismissed. - */ - public boolean dismissTabModalOverlay() { - return mModalDialogManager.dismissActiveDialogOfType( - ModalDialogType.TAB, DialogDismissalCause.NAVIGATE_BACK_OR_TOUCH_OUTSIDE); - } - - /** - * Asks the user to confirm a page reload on a POSTed page. - */ - public void showRepostFormWarningDialog() { - ModalDialogProperties.Controller dialogController = - new SimpleModalDialogController(mModalDialogManager, (Integer dismissalCause) -> { - WebContents webContents = mTab == null ? null : mTab.getWebContents(); - if (webContents == null) return; - switch (dismissalCause) { - case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: - webContents.getNavigationController().continuePendingReload(); - break; - default: - webContents.getNavigationController().cancelPendingReload(); - break; - } - }); - - Resources resources = mWeblayerContext.getResources(); - PropertyModel dialogModel = - new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) - .with(ModalDialogProperties.CONTROLLER, dialogController) - .with(ModalDialogProperties.TITLE, resources, - R.string.http_post_warning_title) - .with(ModalDialogProperties.MESSAGE_PARAGRAPH_1, - resources.getString(R.string.http_post_warning)) - .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, - R.string.http_post_warning_resend) - .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, - R.string.cancel) - .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true) - .build(); - - mModalDialogManager.showDialog(dialogModel, ModalDialogManager.ModalDialogType.TAB, true); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java deleted file mode 100644 index ccde651..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.IBinder; -import android.webkit.WebViewFactory; - -import com.google.android.gms.common.GooglePlayServicesUtilLight; - -import org.chromium.base.StrictModeContext; -import org.chromium.base.library_loader.LibraryLoader; -import org.chromium.base.library_loader.NativeLibraryPreloader; -import org.chromium.base.process_launcher.ChildProcessService; -import org.chromium.build.annotations.UsedByReflection; -import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory; -import org.chromium.content_public.app.ChildProcessServiceFactory; -import org.chromium.weblayer_private.interfaces.IChildProcessService; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -/** - * Implementation of IChildProcessService. - */ -@UsedByReflection("WebLayer") -public final class ChildProcessServiceImpl extends IChildProcessService.Stub { - private static final String TAG = "WebLayer"; - private ChildProcessService mService; - - @UsedByReflection("WebLayer") - public static IBinder create(Service service, Context appContext, Context remoteContext) { - setLibraryPreloader(remoteContext.getPackageName(), remoteContext.getClassLoader()); - ClassLoaderContextWrapperFactory.setLightDarkResourceOverrideContext( - remoteContext, remoteContext); - // Wrap the app context so that it can be used to load WebLayer implementation classes. - appContext = ClassLoaderContextWrapperFactory.get(appContext); - - // The GPU process may use GMS APIs using the host app's context. This is called in the - // browser process in GmsBridge. - GooglePlayServicesUtilLight.enableUsingApkIndependentContext(); - - return new ChildProcessServiceImpl(service, appContext); - } - - @Override - public void onCreate() { - StrictModeWorkaround.apply(); - mService.onCreate(); - } - - @Override - public void onDestroy() { - StrictModeWorkaround.apply(); - mService.onDestroy(); - mService = null; - } - - @Override - public IObjectWrapper onBind(IObjectWrapper intent) { - StrictModeWorkaround.apply(); - return ObjectWrapper.wrap(mService.onBind(ObjectWrapper.unwrap(intent, Intent.class))); - } - - private ChildProcessServiceImpl(Service service, Context context) { - mService = ChildProcessServiceFactory.create(service, context); - } - - public static void setLibraryPreloader(String webLayerPackageName, ClassLoader classLoader) { - if (!LibraryLoader.getInstance().isLoadedByZygote()) { - LibraryLoader.getInstance().setNativeLibraryPreloader(new NativeLibraryPreloader() { - @Override - public int loadLibrary(String packageName) { - return loadNativeLibrary(webLayerPackageName, classLoader); - } - }); - } - } - - private static int loadNativeLibrary(String packageName, ClassLoader cl) { - // Loading the library triggers disk access. - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - return WebViewFactory.loadWebViewNativeLibraryFromPackage(packageName, cl); - } - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContactsPickerAdapter.java b/weblayer/browser/java/org/chromium/weblayer_private/ContactsPickerAdapter.java deleted file mode 100644 index f928a57..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ContactsPickerAdapter.java +++ /dev/null
@@ -1,133 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.RemoteException; -import android.text.TextUtils; -import android.util.AndroidRuntimeException; -import android.webkit.ValueCallback; - -import androidx.annotation.Nullable; - -import org.chromium.components.browser_ui.contacts_picker.ContactDetails; -import org.chromium.components.browser_ui.contacts_picker.PickerAdapter; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.weblayer_private.interfaces.IUserIdentityCallbackClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collections; - -/** - * A {@link PickerAdapter} for WebLayer. - * This class synthesizes the self contact based on data provided by the client. - */ -public class ContactsPickerAdapter extends PickerAdapter { - private final WindowAndroid mWindowAndroid; - - // The avatar returned by the client, or null if it hasn't been returned. - private Bitmap mAvatar; - - // True after the self contact has been synthesized and prepended to the contact list. - private boolean mSelfContactSynthesized; - - ContactsPickerAdapter(WindowAndroid windowAndroid) { - mWindowAndroid = windowAndroid; - } - - // PickerAdapter: - - @Override - protected String findOwnerEmail() { - IUserIdentityCallbackClient identityCallback = getUserIdentityCallback(); - if (identityCallback == null) return null; - - String email; - try { - email = identityCallback.getEmail(); - } catch (RemoteException e) { - throw new AndroidRuntimeException(e); - } - return TextUtils.isEmpty(email) ? null : email; - } - - @Override - protected void addOwnerInfoToContacts(ArrayList<ContactDetails> contacts) { - // This method should only be called if there was a valid email returned in - // findOwnerEmail(). - IUserIdentityCallbackClient identityCallback = getUserIdentityCallback(); - assert identityCallback != null; - - String name; - // Weak ref so that the outstanding callback doesn't hold a ref to |this|. - final WeakReference<ContactsPickerAdapter> weakThis = - new WeakReference<ContactsPickerAdapter>(this); - try { - name = identityCallback.getFullName(); - ValueCallback<Bitmap> onAvatarLoaded = (Bitmap returnedAvatar) -> { - ContactsPickerAdapter strongThis = weakThis.get(); - if (strongThis == null) return; - - strongThis.updateOwnerInfoWithIcon(returnedAvatar); - }; - identityCallback.getAvatar(getIconRawPixelSize(), ObjectWrapper.wrap(onAvatarLoaded)); - } catch (RemoteException e) { - throw new AndroidRuntimeException(e); - } - - if (TextUtils.isEmpty(name)) { - name = getOwnerEmail(); - } - - ContactDetails contact = new ContactDetails(ContactDetails.SELF_CONTACT_ID, name, - Collections.singletonList(getOwnerEmail()), /*phoneNumbers=*/null, - /*addresses=*/null); - contact.setIsSelf(true); - contact.setSelfIcon(createAvatarDrawable()); - contacts.add(0, contact); - - mSelfContactSynthesized = true; - } - - @Nullable - private IUserIdentityCallbackClient getUserIdentityCallback() { - return BrowserFragmentImpl.fromWindowAndroid(mWindowAndroid) - .getBrowser() - .getProfile() - .getUserIdentityCallbackClient(); - } - - private void updateOwnerInfoWithIcon(Bitmap icon) { - if (icon == null) return; - - mAvatar = icon.copy(icon.getConfig(), true); - mAvatar.setDensity( - mWindowAndroid.getContext().get().getResources().getConfiguration().densityDpi); - - if (mSelfContactSynthesized) { - getAllContacts().get(0).setSelfIcon(createAvatarDrawable()); - update(); - } - } - - private Drawable createAvatarDrawable() { - if (mAvatar == null) return null; - - Resources res = mWindowAndroid.getContext().get().getResources(); - int sideLength = getIconRawPixelSize(); - return new BitmapDrawable( - res, Bitmap.createScaledBitmap(mAvatar, sideLength, sideLength, true)); - } - - private int getIconRawPixelSize() { - Resources res = mWindowAndroid.getContext().get().getResources(); - return res.getDimensionPixelSize(R.dimen.contact_picker_icon_size); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java deleted file mode 100644 index 91c75f9..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java +++ /dev/null
@@ -1,865 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.content.res.Configuration; -import android.graphics.Color; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.os.SystemClock; -import android.util.Size; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.FrameLayout; -import android.widget.RelativeLayout; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.browser_ui.widget.InsetObserverView; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.ui.display.DisplayAndroid; -import org.chromium.ui.resources.ResourceManager; - -import java.util.ArrayList; - -/** - * This class manages the chromium compositor and the Surface that is used by - * the chromium compositor. Note it can be used to display only one WebContents. - */ -@JNINamespace("weblayer") -public class ContentViewRenderView - extends RelativeLayout implements WindowAndroid.SelectionHandlesObserver { - private static final int CONFIG_TIMEOUT_MS = 1000; - - // A child view of this class. Parent of SurfaceView. - // Needed to support not resizing the surface when soft keyboard is showing. - private final SurfaceParent mSurfaceParent; - - // This is mode that is requested by client. - private SurfaceData mRequested; - // This is the mode that last supplied the Surface to the compositor. - // This should generally be equal to |mRequested| except during transitions. - private SurfaceData mCurrent; - - // The native side of this object. - private long mNativeContentViewRenderView; - - private Surface mLastSurface; - private boolean mLastCanBeUsedWithSurfaceControl; - - private int mMinimumSurfaceWidth; - private int mMinimumSurfaceHeight; - - // An invisible view that notifies observers of changes to window insets and safe area. - private InsetObserverView mInsetObserverView; - - private WindowAndroid mWindowAndroid; - private WebContents mWebContents; - - private int mBackgroundColor; - - // This is the size of the surfaces, so the "physical" size for the compositor. - // This is the size of the |mSurfaceParent| view, which is the immediate parent - // of the SurfaceView. Note this does not always match the size of - // this ContentViewRenderView; when the soft keyboard is displayed, - // ContentViewRenderView will shrink in height, but |mSurfaceParent| will not. - private int mPhysicalWidth; - private int mPhysicalHeight; - - private int mWebContentsHeightDelta; - - private boolean mCompositorHasSurface; - - private DisplayAndroid.DisplayAndroidObserver mDisplayAndroidObserver; - - private boolean mSelectionHandlesActive; - - private boolean mRequiresAlphaChannel; - private boolean mZOrderMediaOverlay; - - // The time stamp when a configuration was detected (if any). - // This is used along with a timeout to determine if a resize surface resize - // is due to screen rotation. - private long mConfigurationChangedTimestamp; - - private final ArrayList<TrackedRunnable> mPendingRunnables = new ArrayList<>(); - - // Runnables posted via View.postOnAnimation may not run after the view is detached, - // if nothing else causes animation. However a pending runnable may held by a GC root - // from the thread itself, and thus can cause leaks. This class here is so ensure that - // on destroy, all pending tasks are run immediately so they do not lead to leaks. - private abstract class TrackedRunnable implements Runnable { - private boolean mHasRun; - public TrackedRunnable() { - mPendingRunnables.add(this); - } - - @Override - public final void run() { - // View.removeCallbacks is not always reliable, and may run the callback even - // after it has been removed. - if (mHasRun) return; - assert mPendingRunnables.contains(this); - mPendingRunnables.remove(this); - mHasRun = true; - doRun(); - } - - protected abstract void doRun(); - } - - // Non-static class that forward calls to native Compositor. - // It is also responsible for updating |mRequested| and |mCurrent|. - private class SurfaceEventListener { - private SurfaceData mSurfaceData; - - public void setRequestData(SurfaceData surfaceData) { - assert mSurfaceData == null; - mSurfaceData = surfaceData; - } - - public void surfaceCreated() { - assert mNativeContentViewRenderView != 0; - assert mSurfaceData == ContentViewRenderView.this.mRequested - || mSurfaceData == ContentViewRenderView.this.mCurrent; - if (ContentViewRenderView.this.mCurrent != null - && ContentViewRenderView.this.mCurrent != mSurfaceData) { - ContentViewRenderView.this.mCurrent.markForDestroy(true /* hasNextSurface */); - mSurfaceData.setSurfaceDataNeedsDestroy(ContentViewRenderView.this.mCurrent); - } - ContentViewRenderView.this.mCurrent = mSurfaceData; - updateNeedsDidSwapBuffersCallback(); - ContentViewRenderViewJni.get().surfaceCreated(mNativeContentViewRenderView); - } - - public void surfaceChanged(Surface surface, boolean canBeUsedWithSurfaceControl, int width, - int height, boolean transparentBackground) { - assert mNativeContentViewRenderView != 0; - assert mSurfaceData == ContentViewRenderView.this.mCurrent; - if (mLastSurface == surface - && mLastCanBeUsedWithSurfaceControl == canBeUsedWithSurfaceControl) { - surface = null; - } else { - mLastSurface = surface; - mLastCanBeUsedWithSurfaceControl = canBeUsedWithSurfaceControl; - } - ContentViewRenderViewJni.get().surfaceChanged(mNativeContentViewRenderView, - canBeUsedWithSurfaceControl, width, height, transparentBackground, surface); - mCompositorHasSurface = mLastSurface != null; - maybeUpdatePhysicalBackingSize(width, height); - updateBackgroundColor(); - } - - public void surfaceDestroyed(boolean cacheBackBuffer) { - assert mNativeContentViewRenderView != 0; - assert mSurfaceData == ContentViewRenderView.this.mCurrent; - ContentViewRenderViewJni.get().surfaceDestroyed( - mNativeContentViewRenderView, cacheBackBuffer); - mCompositorHasSurface = false; - mLastSurface = null; - mLastCanBeUsedWithSurfaceControl = false; - } - } - - // Abstract lifetime of one SurfaceView. - private class SurfaceData implements SurfaceHolder.Callback2 { - private final SurfaceEventListener mListener; - private final FrameLayout mParent; - private final boolean mAllowSurfaceControl; - private final boolean mRequiresAlphaChannel; - private final boolean mZOrderMediaOverlay; - private final Runnable mEvict; - - private boolean mMarkedForDestroy; - private boolean mCachedSurfaceNeedsEviction; - - private boolean mNeedsOnSurfaceDestroyed; - - // During transitioning between two SurfaceData, there is a complicated series of calls to - // avoid visual artifacts. - // 1) Allocate new SurfaceData, and insert it into view hierarchy below the existing - // SurfaceData, so it is not yet showing. - // 2) When Surface is allocated by new View, swap chromium compositor to the - // new Surface. |markForDestroy| is called on the previous SurfaceData, and the two - // SurfaceDatas are linked through these two variables. - // Note at this point the existing view is still visible. - // 3) Wait wait for two swaps from the chromium compositor so it has content and is ready to - // be shown. - // 4) New SurfaceData calls |destroy| on previous SurfaceData. To avoid flicker, move it to - // the back first before and wait two frames before detaching. - private SurfaceData mPrevSurfaceDataNeedsDestroy; - - private final SurfaceView mSurfaceView; - private int mNumSurfaceViewSwapsUntilVisible; - - private ArrayList<Runnable> mSurfaceRedrawNeededCallbacks; - - public SurfaceData(FrameLayout parent, SurfaceEventListener listener, int backgroundColor, - boolean allowSurfaceControl, boolean requiresAlphaChannel, - boolean zOrderMediaOverlay, Runnable evict) { - mListener = listener; - mParent = parent; - mAllowSurfaceControl = allowSurfaceControl; - mRequiresAlphaChannel = requiresAlphaChannel; - mZOrderMediaOverlay = zOrderMediaOverlay; - mEvict = evict; - mSurfaceView = new SurfaceView(parent.getContext()); - mSurfaceView.setZOrderMediaOverlay(mZOrderMediaOverlay); - mSurfaceView.setBackgroundColor(backgroundColor); - - mSurfaceView.getHolder().addCallback(this); - mSurfaceView.setVisibility(View.VISIBLE); - - // TODO(boliu): This is only needed when video is lifted into a separate - // surface. Keeping this constantly will use one more byte per pixel constantly. - mSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); - - // This postOnAnimation is to avoid manipulating the view tree inside layout or draw. - parent.postOnAnimation(new TrackedRunnable() { - @Override - protected void doRun() { - if (mMarkedForDestroy) return; - View view = mSurfaceView; - assert view != null; - // Always insert view for new surface below the existing view to avoid artifacts - // during surface swaps. Index 0 is the lowest child. - mParent.addView(view, 0, - new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.MATCH_PARENT)); - mParent.invalidate(); - } - }); - } - - public void setSurfaceDataNeedsDestroy(SurfaceData surfaceData) { - assert !mMarkedForDestroy; - assert mPrevSurfaceDataNeedsDestroy == null; - mPrevSurfaceDataNeedsDestroy = surfaceData; - } - - public boolean getAllowSurfaceControl() { - return mAllowSurfaceControl; - } - - public boolean getRequiresAlphaChannel() { - return mRequiresAlphaChannel; - } - - public boolean getZOrderMediaOverlay() { - return mZOrderMediaOverlay; - } - - // Tearing down is separated into markForDestroy and destroy. After markForDestroy - // this class will is guaranteed to not issue any calls to its SurfaceEventListener. - public void markForDestroy(boolean hasNextSurface) { - if (mMarkedForDestroy) return; - mMarkedForDestroy = true; - - if (mNeedsOnSurfaceDestroyed) { - // SurfaceView being used with SurfaceControl need to cache the back buffer - // (EGLSurface). Otherwise the surface is destroyed immediate before the - // SurfaceView is detached. - mCachedSurfaceNeedsEviction = hasNextSurface; - mListener.surfaceDestroyed(mCachedSurfaceNeedsEviction); - mNeedsOnSurfaceDestroyed = false; - } - runSurfaceRedrawNeededCallbacks(); - - mSurfaceView.getHolder().removeCallback(this); - } - - // Remove view from parent hierarchy. - public void destroy() { - assert mMarkedForDestroy; - // This postOnAnimation is to avoid manipulating the view tree inside layout or draw. - mParent.postOnAnimation(new TrackedRunnable() { - @Override - protected void doRun() { - // Detaching a SurfaceView causes a flicker because the SurfaceView - // tears down the Surface in SurfaceFlinger before removing its hole in - // the view tree. This is a complicated heuristics to avoid this. It - // first moves the SurfaceView behind the new View. Then wait two frames - // before detaching the SurfaceView. Waiting for a single frame still - // causes flickers on high end devices like Pixel 3. - moveChildToBackWithoutDetach(mParent, mSurfaceView); - TrackedRunnable inner = new TrackedRunnable() { - @Override - public void doRun() { - mParent.removeView(mSurfaceView); - mParent.invalidate(); - if (mCachedSurfaceNeedsEviction) { - mEvict.run(); - mCachedSurfaceNeedsEviction = false; - } - } - }; - TrackedRunnable outer = new TrackedRunnable() { - @Override - public void doRun() { - mParent.postOnAnimation(inner); - } - }; - mParent.postOnAnimation(outer); - } - }); - } - - private void moveChildToBackWithoutDetach(ViewGroup parent, View child) { - final int numberOfChildren = parent.getChildCount(); - final int childIndex = parent.indexOfChild(child); - if (childIndex <= 0) return; - for (int i = 0; i < childIndex; ++i) { - parent.bringChildToFront(parent.getChildAt(0)); - } - assert parent.indexOfChild(child) == 0; - for (int i = 0; i < numberOfChildren - childIndex - 1; ++i) { - parent.bringChildToFront(parent.getChildAt(1)); - } - parent.invalidate(); - } - - public void setBackgroundColor(int color) { - assert !mMarkedForDestroy; - mSurfaceView.setBackgroundColor(color); - } - - /** @return true if should keep swapping frames */ - public boolean didSwapFrame() { - if (mSurfaceView != null && mSurfaceView.getBackground() != null) { - mSurfaceView.post(new Runnable() { - @Override - public void run() { - if (mSurfaceView != null) mSurfaceView.setBackgroundResource(0); - } - }); - } - // We have no reliable signal for when to show a SurfaceView. This is a heuristic - // (used by chrome as well) is to wait for 2 swaps from the chromium comopsitor - // as a signal that the SurfaceView has content and is ready to be displayed. - if (mNumSurfaceViewSwapsUntilVisible > 0) { - mNumSurfaceViewSwapsUntilVisible--; - } - if (mNumSurfaceViewSwapsUntilVisible == 0) { - destroyPreviousData(); - } - return mNumSurfaceViewSwapsUntilVisible > 0; - } - - public void runSurfaceRedrawNeededCallbacks() { - ArrayList<Runnable> callbacks = mSurfaceRedrawNeededCallbacks; - mSurfaceRedrawNeededCallbacks = null; - if (callbacks == null) return; - for (Runnable r : callbacks) { - r.run(); - } - updateNeedsDidSwapBuffersCallback(); - } - - public boolean hasSurfaceRedrawNeededCallbacks() { - return mSurfaceRedrawNeededCallbacks != null - && !mSurfaceRedrawNeededCallbacks.isEmpty(); - } - - public View getView() { - return mSurfaceView; - } - - private void destroyPreviousData() { - if (mPrevSurfaceDataNeedsDestroy != null) { - mPrevSurfaceDataNeedsDestroy.destroy(); - mPrevSurfaceDataNeedsDestroy = null; - } - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - if (mMarkedForDestroy) return; - - // On pre-M Android, layers start in the hidden state until a relayout happens. - // There is a bug that manifests itself when entering overlay mode on pre-M devices, - // where a relayout never happens. This bug is out of Chromium's control, but can be - // worked around by forcibly re-setting the visibility of the surface view. - // Otherwise, the screen stays black, and some tests fail. - if (mSurfaceView != null) { - mSurfaceView.setVisibility(mSurfaceView.getVisibility()); - } - mListener.surfaceCreated(); - mNeedsOnSurfaceDestroyed = true; - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - // Surface surface, boolean canBeUsedWithSurfaceControl, int width, - // int height, boolean transparentBackground) { - if (mMarkedForDestroy) return; - // Selection magnifier does not work with surface control enabled. - mListener.surfaceChanged(holder.getSurface(), mAllowSurfaceControl, width, height, - /*transparentBackground=*/false); - mNumSurfaceViewSwapsUntilVisible = 2; - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - if (mMarkedForDestroy) return; - assert mNeedsOnSurfaceDestroyed; - mListener.surfaceDestroyed(/*cacheBackBuffer=*/false); - mNeedsOnSurfaceDestroyed = false; - runSurfaceRedrawNeededCallbacks(); - } - - @Override - public void surfaceRedrawNeeded(SurfaceHolder holder) { - // Intentionally not implemented. - } - - @Override - public void surfaceRedrawNeededAsync(SurfaceHolder holder, Runnable drawingFinished) { - if (mMarkedForDestroy) { - drawingFinished.run(); - return; - } - assert mNativeContentViewRenderView != 0; - assert this == ContentViewRenderView.this.mCurrent; - if (mSurfaceRedrawNeededCallbacks == null) { - mSurfaceRedrawNeededCallbacks = new ArrayList<>(); - } - mSurfaceRedrawNeededCallbacks.add(drawingFinished); - updateNeedsDidSwapBuffersCallback(); - ContentViewRenderViewJni.get().setNeedsRedraw(mNativeContentViewRenderView); - } - } - - // This is a child of ContentViewRenderView and parent of SurfaceView. - // This exists to avoid resizing SurfaceView when the soft keyboard is displayed. - // Also has workaround for SurfaceView `onAttachedToWindow` visual glitch. - private class SurfaceParent extends FrameLayout { - // This view is used to cover up any SurfaceView for a few frames immediately - // after `onAttachedToWindow`. This is the workaround a bug in SurfaceView (on some versions - // of android) which punches a hole before the surface below has any content, resulting in - // black for a few frames. `mCoverView` is a workaround for this bug. It covers up - // SurfaceView with the background color, and is removed after a few swaps. - private final View mCoverView; - private int mNumSwapsUntilHideCover; - - public SurfaceParent(Context context) { - super(context); - mCoverView = new View(context); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int existingHeight = getMeasuredHeight(); - int width = MeasureSpec.getSize(widthMeasureSpec); - int height = MeasureSpec.getSize(heightMeasureSpec); - - if (width <= mMinimumSurfaceWidth && height <= mMinimumSurfaceHeight) { - width = mMinimumSurfaceWidth; - height = mMinimumSurfaceHeight; - } - - // If width is the same and height shrinks, then check if we should - // avoid this resize for displaying the soft keyboard. - if (getMeasuredWidth() == width && existingHeight > height - && shouldAvoidSurfaceResizeForSoftKeyboard()) { - // Just set the height to the current height. - height = existingHeight; - } - super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - mPhysicalWidth = w; - mPhysicalHeight = h; - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - mNumSwapsUntilHideCover = 2; - // Add as the top child covering up any other children. - addView(mCoverView, - new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.MATCH_PARENT)); - if (mNativeContentViewRenderView != 0) { - ContentViewRenderViewJni.get().setNeedsRedraw(mNativeContentViewRenderView); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mNumSwapsUntilHideCover = 0; - removeView(mCoverView); - } - - /** @return true if should keep swapping frames */ - public boolean didSwapFrame() { - if (mNumSwapsUntilHideCover <= 0) return false; - mNumSwapsUntilHideCover--; - if (mNumSwapsUntilHideCover == 0) removeView(mCoverView); - return mNumSwapsUntilHideCover > 0; - } - - public void updateCoverViewColor(int color) { - mCoverView.setBackgroundColor(color); - } - } - - /** - * Constructs a new ContentViewRenderView. - * This should be called and the {@link ContentViewRenderView} should be added to the view - * hierarchy before the first draw to avoid a black flash that is seen every time a - * {@link SurfaceView} is added. - * @param context The context used to create this. - * @param recreateForConfigurationChange indicates that views are recreated after BrowserImpl - * is retained, but Activity is recreated, for a - * configuration change. - */ - public ContentViewRenderView(Context context, boolean recreateForConfigurationChange) { - super(context); - mSurfaceParent = new SurfaceParent(context); - addView(mSurfaceParent, - new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - - mInsetObserverView = InsetObserverView.create(context); - addView(mInsetObserverView); - mInsetObserverView.addObserver(new InsetObserverView.WindowInsetObserver() { - @Override - public void onInsetChanged(int left, int top, int right, int bottom) { - if (mWebContents != null && mWebContents.isFullscreenForCurrentTab()) { - updateWebContentsSize(); - } - } - - @Override - public void onSafeAreaChanged(Rect area) {} - }); - if (recreateForConfigurationChange) updateConfigChangeTimeStamp(); - } - - /** - * Initialization that requires native libraries should be done here. - * Native code should add/remove the layers to be rendered through the ContentViewLayerRenderer. - * @param rootWindow The {@link WindowAndroid} this render view should be linked to. - */ - public void onNativeLibraryLoaded(WindowAndroid rootWindow) { - assert rootWindow != null; - mNativeContentViewRenderView = - ContentViewRenderViewJni.get().init(ContentViewRenderView.this, rootWindow); - assert mNativeContentViewRenderView != 0; - mWindowAndroid = rootWindow; - maybeRecreateSurfaceView(); - mDisplayAndroidObserver = new DisplayAndroid.DisplayAndroidObserver() { - @Override - public void onRotationChanged(int rotation) { - updateConfigChangeTimeStamp(); - } - }; - mWindowAndroid.getDisplay().addObserver(mDisplayAndroidObserver); - mWindowAndroid.addSelectionHandlesObserver(this); - updateBackgroundColor(); - } - - public void maybeRecreateSurfaceView() { - boolean allowSurfaceControl = !mSelectionHandlesActive && !mRequiresAlphaChannel; - if (mRequested != null - && (mRequested.getAllowSurfaceControl() != allowSurfaceControl - || mRequested.getRequiresAlphaChannel() != mRequiresAlphaChannel - || mRequested.getZOrderMediaOverlay() != mZOrderMediaOverlay)) { - if (mRequested != mCurrent) { - mRequested.markForDestroy(false /* hasNextSurface */); - mRequested.destroy(); - } - mRequested = null; - } - - if (mRequested == null) { - SurfaceEventListener listener = new SurfaceEventListener(); - mRequested = - new SurfaceData(mSurfaceParent, listener, mBackgroundColor, allowSurfaceControl, - mRequiresAlphaChannel, mZOrderMediaOverlay, this::evictCachedSurface); - listener.setRequestData(mRequested); - } - } - - public void setMinimumSurfaceSize(int width, int height) { - mMinimumSurfaceWidth = width; - mMinimumSurfaceHeight = height; - } - - /** - * Sets how much to decrease the height of the WebContents by. - */ - public void setWebContentsHeightDelta(int delta) { - if (delta == mWebContentsHeightDelta) return; - mWebContentsHeightDelta = delta; - updateWebContentsSize(); - } - - /** - * Return the view used for selection magnifier readback. - */ - public View getViewForMagnifierReadback() { - if (mCurrent == null) return null; - return mCurrent.getView(); - } - - private void updateWebContentsSize() { - if (mWebContents == null) return; - Size size = getViewportSize(); - mWebContents.setSize(size.getWidth(), size.getHeight() - mWebContentsHeightDelta); - } - - /** {@link CompositorViewHolder#getViewportSize()} for explanation. */ - private Size getViewportSize() { - if (mWebContents.isFullscreenForCurrentTab() - && mWindowAndroid.getKeyboardDelegate().isKeyboardShowing(getContext(), this)) { - Rect visibleRect = new Rect(); - getWindowVisibleDisplayFrame(visibleRect); - return new Size(Math.min(visibleRect.width(), getWidth()), - Math.min(visibleRect.height(), getHeight())); - } - - return new Size(getWidth(), getHeight()); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - if (mWebContents == null) return; - updateWebContentsSize(); - Size viewportSize = getViewportSize(); - ContentViewRenderViewJni.get().onViewportSizeChanged( - mNativeContentViewRenderView, viewportSize.getWidth(), viewportSize.getHeight()); - } - - /** - * View's method override to notify WindowAndroid about changes in its visibility. - */ - @Override - protected void onWindowVisibilityChanged(int visibility) { - super.onWindowVisibilityChanged(visibility); - - if (mWindowAndroid == null) return; - - if (visibility == View.GONE) { - mWindowAndroid.onVisibilityChanged(false); - } else if (visibility == View.VISIBLE) { - mWindowAndroid.onVisibilityChanged(true); - } - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - updateBackgroundColor(); - } - - /** - * Sets the background color of the surface / texture view. This method is necessary because - * the background color of ContentViewRenderView itself is covered by the background of - * SurfaceView. - * @param color The color of the background. - */ - @Override - public void setBackgroundColor(int color) { - if (mBackgroundColor == color) return; - - mBackgroundColor = color; - super.setBackgroundColor(color); - mSurfaceParent.updateCoverViewColor(color); - if (mRequested != null) { - mRequested.setBackgroundColor(color); - } - if (mCurrent != null) { - mCurrent.setBackgroundColor(color); - } - ContentViewRenderViewJni.get().updateBackgroundColor(mNativeContentViewRenderView); - } - - // SelectionHandlesObserver overrides - @Override - public void onSelectionHandlesStateChanged(boolean active) { - if (mSelectionHandlesActive == active) return; - mSelectionHandlesActive = active; - if (mCurrent == null) return; - - // maybeRecreateSurfaceView will take into account the updated |mSelectionHandlesActive| - // and respond appropriately, even if mode is the same. - maybeRecreateSurfaceView(); - } - - public InsetObserverView getInsetObserverView() { - return mInsetObserverView; - } - - public void setSurfaceProperties(boolean requiresAlphaChannel, boolean zOrderMediaOverlay) { - if (mRequiresAlphaChannel == requiresAlphaChannel - && mZOrderMediaOverlay == zOrderMediaOverlay) { - return; - } - mRequiresAlphaChannel = requiresAlphaChannel; - mZOrderMediaOverlay = zOrderMediaOverlay; - - if (mCurrent == null) return; - maybeRecreateSurfaceView(); - - ContentViewRenderViewJni.get().setRequiresAlphaChannel( - mNativeContentViewRenderView, requiresAlphaChannel); - } - - /** - * Should be called when the ContentViewRenderView is not needed anymore so its associated - * native resource can be freed. - */ - public void destroy() { - if (mRequested != null) { - mRequested.markForDestroy(false /* hasNextSurface */); - mRequested.destroy(); - if (mCurrent != null && mCurrent != mRequested) { - mCurrent.markForDestroy(false /* hasNextSurface */); - mCurrent.destroy(); - } - } - mRequested = null; - mCurrent = null; - - if (mDisplayAndroidObserver != null) { - mWindowAndroid.getDisplay().removeObserver(mDisplayAndroidObserver); - mDisplayAndroidObserver = null; - } - mWindowAndroid.removeSelectionHandlesObserver(this); - mWindowAndroid = null; - - while (!mPendingRunnables.isEmpty()) { - TrackedRunnable runnable = mPendingRunnables.get(0); - mSurfaceParent.removeCallbacks(runnable); - runnable.run(); - assert !mPendingRunnables.contains(runnable); - } - ContentViewRenderViewJni.get().destroy(mNativeContentViewRenderView); - mNativeContentViewRenderView = 0; - } - - public void setWebContents(WebContents webContents) { - assert mNativeContentViewRenderView != 0; - mWebContents = webContents; - - if (webContents != null && getWidth() != 0 && getHeight() != 0) { - updateWebContentsSize(); - maybeUpdatePhysicalBackingSize(mPhysicalWidth, mPhysicalHeight); - } - ContentViewRenderViewJni.get().setCurrentWebContents( - mNativeContentViewRenderView, webContents); - } - - public ResourceManager getResourceManager() { - return ContentViewRenderViewJni.get().getResourceManager(mNativeContentViewRenderView); - } - - public boolean hasSurface() { - return mCompositorHasSurface; - } - - @CalledByNative - private boolean didSwapFrame() { - assert mCurrent != null; - boolean ret = mCurrent.didSwapFrame(); - ret = ret || mSurfaceParent.didSwapFrame(); - return ret; - } - - @CalledByNative - private void didSwapBuffers(boolean sizeMatches) { - assert mCurrent != null; - if (!sizeMatches) return; - mCurrent.runSurfaceRedrawNeededCallbacks(); - } - - // Should be called any time inputs used to compute `needsDidSwapBuffersCallback` change. - private void updateNeedsDidSwapBuffersCallback() { - boolean needsDidSwapBuffersCallback = - mCurrent != null && mCurrent.hasSurfaceRedrawNeededCallbacks(); - ContentViewRenderViewJni.get().setDidSwapBuffersCallbackEnabled( - mNativeContentViewRenderView, needsDidSwapBuffersCallback); - } - - private void evictCachedSurface() { - if (mNativeContentViewRenderView == 0) return; - ContentViewRenderViewJni.get().evictCachedSurface(mNativeContentViewRenderView); - } - - public long getNativeHandle() { - return mNativeContentViewRenderView; - } - - private void updateBackgroundColor() { - int uiMode = getContext().getResources().getConfiguration().uiMode; - boolean darkThemeEnabled = - (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; - int color; - if (darkThemeEnabled) { - color = Color.BLACK; - } else { - color = Color.WHITE; - } - setBackgroundColor(color); - } - - @CalledByNative - private int getBackgroundColor() { - return mBackgroundColor; - } - - private boolean shouldAvoidSurfaceResizeForSoftKeyboard() { - boolean isFullWidth = isAttachedToWindow() && getWidth() == getRootView().getWidth(); - if (!isFullWidth) return false; - - InputMethodManager inputMethodManager = - (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - return inputMethodManager.isActive(); - } - - private void updateConfigChangeTimeStamp() { - mConfigurationChangedTimestamp = SystemClock.uptimeMillis(); - } - - private void maybeUpdatePhysicalBackingSize(int width, int height) { - if (mWebContents == null) return; - boolean forConfigChange = - SystemClock.uptimeMillis() - mConfigurationChangedTimestamp < CONFIG_TIMEOUT_MS; - ContentViewRenderViewJni.get().onPhysicalBackingSizeChanged( - mNativeContentViewRenderView, mWebContents, width, height, forConfigChange); - } - - @NativeMethods - interface Natives { - long init(ContentViewRenderView caller, WindowAndroid rootWindow); - void destroy(long nativeContentViewRenderView); - void setCurrentWebContents(long nativeContentViewRenderView, WebContents webContents); - void onPhysicalBackingSizeChanged(long nativeContentViewRenderView, WebContents webContents, - int width, int height, boolean forConfigChange); - void onViewportSizeChanged(long nativeContentViewRenderView, int width, int height); - void surfaceCreated(long nativeContentViewRenderView); - void surfaceDestroyed(long nativeContentViewRenderView, boolean cacheBackBuffer); - void surfaceChanged(long nativeContentViewRenderView, boolean canBeUsedWithSurfaceControl, - int width, int height, boolean transparentBackground, Surface newSurface); - void setNeedsRedraw(long nativeContentViewRenderView); - void evictCachedSurface(long nativeContentViewRenderView); - ResourceManager getResourceManager(long nativeContentViewRenderView); - void updateBackgroundColor(long nativeContentViewRenderView); - void setRequiresAlphaChannel( - long nativeContentViewRenderView, boolean requiresAlphaChannel); - void setDidSwapBuffersCallbackEnabled(long nativeContentViewRenderView, boolean enabled); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewWithAutofill.java b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewWithAutofill.java deleted file mode 100644 index eff6cf15..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewWithAutofill.java +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.os.Build; -import android.util.SparseArray; -import android.view.View; -import android.view.ViewStructure; -import android.view.autofill.AutofillValue; - -import org.chromium.components.embedder_support.view.ContentView; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.base.EventOffsetHandler; - -/** - * API level 26 implementation that includes autofill. - */ -public class ContentViewWithAutofill extends ContentView { - public static ContentView createContentView( - Context context, EventOffsetHandler eventOffsetHandler) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - return new ContentViewWithAutofill(context, eventOffsetHandler); - } - return ContentView.createContentView(context, eventOffsetHandler, null /* webContents */); - } - - private TabImpl mTab; - - private ContentViewWithAutofill(Context context, EventOffsetHandler eventOffsetHandler) { - super(context, eventOffsetHandler, null /* webContents */); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // The Autofill system-level infrastructure has heuristics for which Views it considers - // important for autofill; only these Views will be queried for their autofill - // structure on notifications that a new (virtual) View was entered. By default, - // FrameLayout is not considered important for autofill. Thus, for ContentView to be - // queried for its autofill structure, we must explicitly inform the autofill system - // that this View is important for autofill. - setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES); - } - } - - @Override - public void setWebContents(WebContents webContents) { - mTab = TabImpl.fromWebContents(webContents); - super.setWebContents(webContents); - } - - @Override - public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) { - // A new (virtual) View has been entered, and the autofill system-level - // infrastructure wants us to populate |structure| with the autofill structure of the - // (virtual) View. Forward this on to TabImpl to accomplish. - if (mTab != null) { - mTab.onProvideAutofillVirtualStructure(structure, flags); - } - } - - @Override - public void autofill(final SparseArray<AutofillValue> values) { - // The autofill system-level infrastructure has information that we can use to - // autofill the current (virtual) View. Forward this on to TabImpl to - // accomplish. - if (mTab != null) { - mTab.autofill(values); - } - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java deleted file mode 100644 index 52a68fdee..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java +++ /dev/null
@@ -1,163 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import org.chromium.base.Callback; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.CookieChangeCause; -import org.chromium.weblayer_private.interfaces.ExceptionType; -import org.chromium.weblayer_private.interfaces.IBooleanCallback; -import org.chromium.weblayer_private.interfaces.ICookieChangedCallbackClient; -import org.chromium.weblayer_private.interfaces.ICookieManager; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IStringCallback; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.lang.ref.WeakReference; -import java.util.Arrays; -import java.util.List; - -/** - * Implementation of ICookieManager. - */ -@JNINamespace("weblayer") -public final class CookieManagerImpl extends ICookieManager.Stub { - private long mNativeCookieManager; - private ProfileImpl mProfile; - - CookieManagerImpl(long nativeCookieManager, ProfileImpl profile) { - mNativeCookieManager = nativeCookieManager; - mProfile = profile; - } - - public void destroy() { - mNativeCookieManager = 0; - } - - @Override - public void setCookie(String url, String value, IBooleanCallback callback) { - StrictModeWorkaround.apply(); - - WebLayerOriginVerificationScheduler originVerifier = - WebLayerOriginVerificationScheduler.getInstance(); - - originVerifier.verify(url, (verified) -> { - if (!verified) { - try { - callback.onException(ExceptionType.RESTRICTED_API, - "Application does not have permissions to modify " + url); - } catch (RemoteException e) { - } - } - Callback<Boolean> baseCallback = (Boolean result) -> { - try { - callback.onResult(result); - } catch (RemoteException e) { - } - }; - CookieManagerImplJni.get().setCookie(mNativeCookieManager, url, value, baseCallback); - }); - } - - @Override - public void getCookie(String url, IStringCallback callback) { - StrictModeWorkaround.apply(); - - WebLayerOriginVerificationScheduler originVerifier = - WebLayerOriginVerificationScheduler.getInstance(); - - originVerifier.verify(url, (verified) -> { - if (!verified) { - try { - callback.onException(ExceptionType.RESTRICTED_API, - "Application does not have permissions to modify " + url); - } catch (RemoteException e) { - } - } - Callback<String> baseCallback = (String result) -> { - try { - callback.onResult(result); - } catch (RemoteException e) { - } - }; - CookieManagerImplJni.get().getCookie(mNativeCookieManager, url, baseCallback); - }); - } - - @Override - public void getResponseCookies(String url, IObjectWrapper callback) { - StrictModeWorkaround.apply(); - ValueCallback<List<String>> valueCallback = - (ValueCallback<List<String>>) ObjectWrapper.unwrap(callback, ValueCallback.class); - Callback<String[]> baseCallback = - (String[] result) -> valueCallback.onReceiveValue(Arrays.asList(result)); - CookieManagerImplJni.get().getResponseCookies(mNativeCookieManager, url, baseCallback); - } - - @Override - public IObjectWrapper addCookieChangedCallback( - String url, String name, ICookieChangedCallbackClient callback) { - StrictModeWorkaround.apply(); - int id = CookieManagerImplJni.get().addCookieChangedCallback( - mNativeCookieManager, url, name, callback); - // Use a weak reference to make sure we don't keep |this| alive in the closure. - WeakReference<CookieManagerImpl> weakSelf = new WeakReference<>(this); - Runnable close = () -> { - CookieManagerImpl impl = weakSelf.get(); - if (impl != null && impl.mNativeCookieManager != 0) { - CookieManagerImplJni.get().removeCookieChangedCallback( - impl.mNativeCookieManager, id); - } - }; - return ObjectWrapper.wrap(close); - } - - @CalledByNative - private static void onCookieChange(ICookieChangedCallbackClient callback, String cookie, - int cause) throws RemoteException { - callback.onCookieChanged(cookie, mojoCauseToJavaType(cause)); - } - - @CookieChangeCause - private static int mojoCauseToJavaType(int cause) { - assert org.chromium.network.mojom.CookieChangeCause.isKnownValue(cause); - switch (cause) { - case org.chromium.network.mojom.CookieChangeCause.INSERTED: - return CookieChangeCause.INSERTED; - case org.chromium.network.mojom.CookieChangeCause.EXPLICIT: - return CookieChangeCause.EXPLICIT; - case org.chromium.network.mojom.CookieChangeCause.UNKNOWN_DELETION: - return CookieChangeCause.UNKNOWN_DELETION; - case org.chromium.network.mojom.CookieChangeCause.OVERWRITE: - return CookieChangeCause.OVERWRITE; - case org.chromium.network.mojom.CookieChangeCause.EXPIRED: - return CookieChangeCause.EXPIRED; - case org.chromium.network.mojom.CookieChangeCause.EVICTED: - return CookieChangeCause.EVICTED; - case org.chromium.network.mojom.CookieChangeCause.EXPIRED_OVERWRITE: - return CookieChangeCause.EXPIRED_OVERWRITE; - } - assert false; - return CookieChangeCause.EXPLICIT; - } - - @NativeMethods - interface Natives { - void setCookie( - long nativeCookieManagerImpl, String url, String value, Callback<Boolean> callback); - void getCookie(long nativeCookieManagerImpl, String url, Callback<String> callback); - void getResponseCookies( - long nativeCookieManagerImpl, String url, Callback<String[]> callback); - int addCookieChangedCallback(long nativeCookieManagerImpl, String url, String name, - ICookieChangedCallbackClient callback); - void removeCookieChangedCallback(long nativeCookieManagerImpl, int id); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterController.java b/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterController.java deleted file mode 100644 index 8bd9c15..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterController.java +++ /dev/null
@@ -1,242 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.Bundle; - -import androidx.annotation.Nullable; - -import org.json.JSONException; -import org.json.JSONObject; - -import org.chromium.base.Log; -import org.chromium.base.PathUtils; -import org.chromium.base.TraceEvent; -import org.chromium.base.task.AsyncTask; -import org.chromium.components.crash.browser.ChildProcessCrashObserver; -import org.chromium.components.minidump_uploader.CrashFileManager; -import org.chromium.components.minidump_uploader.MinidumpUploader; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; - -/** - * CrashReporterController handles crashes in weblayer_private and delegates them to the - * CrashReceiverService from android_webview non-embedded code. - */ -public final class CrashReporterController { - private static final String TAG = "CrashReporter"; - private static final int MAX_UPLOAD_RETRIES = 3; - - private CrashFileManager mCrashFileManager; - private boolean mIsNativeInitialized; - - private static class Holder { - static CrashReporterController sInstance = new CrashReporterController(); - } - - private CrashReporterController() {} - - public static CrashReporterController getInstance() { - return Holder.sInstance; - } - - public void notifyNativeInitialized() { - mIsNativeInitialized = true; - - processNewMinidumps(); - TraceEvent.instant(TAG, "Start observing child process crashes"); - ChildProcessCrashObserver.registerCrashCallback( - new ChildProcessCrashObserver.ChildCrashedCallback() { - @Override - public void childCrashed(int pid) { - TraceEvent.instant(TAG, "Child process crashed. Process new minidumps."); - processNewMinidumps(); - } - }); - } - - public void deleteCrash(String localId) { - StrictModeWorkaround.apply(); - AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { deleteCrashOnBackgroundThread(localId); }); - } - - public void uploadCrash(String localId) { - StrictModeWorkaround.apply(); - AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { - TraceEvent.instant(TAG, "CrashReporterController: Begin uploading crash"); - File minidumpFile = getCrashFileManager().getCrashFileWithLocalId(localId); - if (minidumpFile == null) { - return; - } - MinidumpUploader.Result result = new MinidumpUploader().upload(minidumpFile); - if (result.isSuccess()) { - CrashFileManager.markUploadSuccess(minidumpFile); - } else { - CrashFileManager.tryIncrementAttemptNumber(minidumpFile); - } - - TraceEvent.instant(TAG, - "CrashReporterController: Crash upload " - + (result.isSuccess() ? "succeeded" : "failed")); - }); - } - - public @Nullable Bundle getCrashKeys(String localId) { - StrictModeWorkaround.apply(); - JSONObject data = readSidecar(localId); - if (data == null) { - return null; - } - Bundle result = new Bundle(); - Iterator<String> iter = data.keys(); - while (iter.hasNext()) { - String key = iter.next(); - try { - result.putCharSequence(key, data.getString(key)); - } catch (JSONException e) { - // Skip non-string values. - } - } - return result; - } - - /** Start an async task to import crashes, and notify if any are found. */ - private void processNewMinidumps() { - AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { processNewMinidumpsOnBackgroundThread(); }); - } - - /** Delete a crash report (and any sidecar file) given its local ID. */ - private void deleteCrashOnBackgroundThread(String localId) { - File minidumpFile = getCrashFileManager().getCrashFileWithLocalId(localId); - File sidecarFile = sidecarFile(localId); - if (minidumpFile != null) { - CrashFileManager.deleteFile(minidumpFile); - } - if (sidecarFile != null) { - CrashFileManager.deleteFile(sidecarFile); - } - } - - /** - * Determine the set of crashes that are currently ready to be uploaded. - * - * Clean out crashes that are too old, and return the any remaining crashes that have not - * exceeded their upload retry limit. - * - * @return An array of local IDs for crashes that are ready to be uploaded. - */ - private String[] getPendingMinidumpsOnBackgroundThread() { - TraceEvent.instant( - TAG, "CrashReporterController: Start determining crashes ready to be uploaded."); - getCrashFileManager().cleanOutAllNonFreshMinidumpFiles(); - File[] pendingMinidumps = - getCrashFileManager().getMinidumpsReadyForUpload(MAX_UPLOAD_RETRIES); - ArrayList<String> localIds = new ArrayList<>(pendingMinidumps.length); - for (File minidump : pendingMinidumps) { - localIds.add(CrashFileManager.getCrashLocalIdFromFileName(minidump.getName())); - } - TraceEvent.instant( - TAG, "CrashReporterController: Finish determinining crashes ready to be uploaded."); - return localIds.toArray(new String[0]); - } - - /** - * Use the CrashFileManager to import crashes from crashpad. - * - * For each imported crash, a sidecar file (in JSON format) is written, containing the - * crash keys that were recorded at the time of the crash. - * - * @return An array of local IDs of the new crashes (may be empty). - */ - private String[] processNewMinidumpsOnBackgroundThread() { - TraceEvent.instant( - TAG, "CrashReporterController: Start processing minidumps in the background."); - Map<String, Map<String, String>> crashesInfoMap = - getCrashFileManager().importMinidumpsCrashKeys(); - if (crashesInfoMap == null) return new String[0]; - ArrayList<String> localIds = new ArrayList<>(crashesInfoMap.size()); - for (Map.Entry<String, Map<String, String>> entry : crashesInfoMap.entrySet()) { - JSONObject crashKeysJson = new JSONObject(entry.getValue()); - String uuid = entry.getKey(); - // TODO(tobiasjs): the minidump uploader uses the last component of the uuid as - // the local ID. The ergonomics of this should be improved. - localIds.add(CrashFileManager.getCrashLocalIdFromFileName(uuid + ".dmp")); - writeSidecar(uuid, crashKeysJson); - } - for (File minidump : getCrashFileManager().getMinidumpsSansLogcat()) { - CrashFileManager.trySetReadyForUpload(minidump); - } - TraceEvent.instant( - TAG, "CrashReporterController: Finish processing minidumps in the background."); - return localIds.toArray(new String[0]); - } - - /** - * Generate a sidecar file path given a crash local ID. - * - * The sidecar file holds a JSON representation of the crash keys associated - * with the crash. All crash keys and values are strings. - */ - private @Nullable File sidecarFile(String localId) { - File minidumpFile = getCrashFileManager().getCrashFileWithLocalId(localId); - if (minidumpFile == null) { - return null; - } - String uuid = minidumpFile.getName().split("\\.")[0]; - return new File(minidumpFile.getParent(), uuid + ".json"); - } - - /** Write JSON formatted crash key data to the sidecar file for a crash. */ - private void writeSidecar(String localId, JSONObject data) { - File sidecar = sidecarFile(localId); - if (sidecar == null) { - return; - } - try (FileOutputStream out = new FileOutputStream(sidecar)) { - out.write(data.toString().getBytes("UTF-8")); - } catch (IOException e) { - Log.w(TAG, "Failed to write crash keys JSON for crash " + localId); - sidecar.delete(); - } - } - - /** Read JSON formatted crash key data previously written to a crash sidecar file. */ - private @Nullable JSONObject readSidecar(String localId) { - File sidecar = sidecarFile(localId); - if (sidecar == null) { - return null; - } - try (FileInputStream in = new FileInputStream(sidecar)) { - byte[] data = new byte[(int) sidecar.length()]; - int offset = 0; - while (offset < data.length) { - int count = in.read(data, offset, data.length - offset); - if (count <= 0) break; - offset += count; - } - return new JSONObject(new String(data, "UTF-8")); - } catch (IOException | JSONException e) { - return null; - } - } - - private CrashFileManager getCrashFileManager() { - if (mCrashFileManager == null) { - File cacheDir = new File(PathUtils.getCacheDirectory()); - // Make sure the cache dir has been created, since this may be called before WebLayer - // has been initialized. - cacheDir.mkdir(); - mCrashFileManager = new CrashFileManager(cacheDir); - } - return mCrashFileManager; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/DownloadCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/DownloadCallbackProxy.java deleted file mode 100644 index 903b7f4..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/DownloadCallbackProxy.java +++ /dev/null
@@ -1,147 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.Manifest.permission; -import android.content.pm.PackageManager; -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import org.chromium.base.ThreadUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.url.GURL; -import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * Owns the c++ DownloadCallbackProxy class, which is responsible for forwarding all - * DownloadDelegate delegate calls to this class, which in turn forwards to the - * DownloadCallbackClient. - */ -@JNINamespace("weblayer") -public final class DownloadCallbackProxy { - private final ProfileImpl mProfile; - private long mNativeDownloadCallbackProxy; - private IDownloadCallbackClient mClient; - - DownloadCallbackProxy(ProfileImpl profile) { - mProfile = profile; - mNativeDownloadCallbackProxy = DownloadCallbackProxyJni.get().createDownloadCallbackProxy( - this, profile.getNativeProfile()); - } - - public void setClient(IDownloadCallbackClient client) { - mClient = client; - } - - public void destroy() { - DownloadCallbackProxyJni.get().deleteDownloadCallbackProxy(mNativeDownloadCallbackProxy); - mNativeDownloadCallbackProxy = 0; - } - - @CalledByNative - private boolean interceptDownload(String url, String userAgent, String contentDisposition, - String mimetype, long contentLength) throws RemoteException { - if (mClient == null) { - return false; - } - - return mClient.interceptDownload( - url, userAgent, contentDisposition, mimetype, contentLength); - } - - @CalledByNative - private void allowDownload(TabImpl tab, String url, String requestMethod, - String requestInitiator, long callbackId) throws RemoteException { - WindowAndroid window = tab.getBrowser().getBrowserFragment().getWindowAndroid(); - if (window.hasPermission(permission.WRITE_EXTERNAL_STORAGE)) { - continueAllowDownload(url, requestMethod, requestInitiator, callbackId); - return; - } - - String[] requestPermissions = new String[] {permission.WRITE_EXTERNAL_STORAGE}; - window.requestPermissions(requestPermissions, (permissions, grantResults) -> { - if (grantResults.length == 0 || grantResults[0] == PackageManager.PERMISSION_DENIED) { - DownloadCallbackProxyJni.get().allowDownload(callbackId, false); - return; - } - - try { - continueAllowDownload(url, requestMethod, requestInitiator, callbackId); - } catch (RemoteException e) { - } - }); - } - - private void continueAllowDownload(String url, String requestMethod, String requestInitiator, - long callbackId) throws RemoteException { - if (mClient == null) { - DownloadCallbackProxyJni.get().allowDownload(callbackId, true); - return; - } - - ValueCallback<Boolean> callback = new ValueCallback<Boolean>() { - @Override - public void onReceiveValue(Boolean result) { - ThreadUtils.assertOnUiThread(); - if (mNativeDownloadCallbackProxy == 0) { - throw new IllegalStateException("Called after destroy()"); - } - DownloadCallbackProxyJni.get().allowDownload(callbackId, result); - } - }; - - mClient.allowDownload(url, requestMethod, requestInitiator, ObjectWrapper.wrap(callback)); - } - - @CalledByNative - private DownloadImpl createDownload( - long nativeDownloadImpl, int id, boolean isTransient, GURL sourceUrl) { - return new DownloadImpl(mProfile.getName(), mProfile.isIncognito(), mClient, - nativeDownloadImpl, id, isTransient, sourceUrl); - } - - @CalledByNative - private void downloadStarted(DownloadImpl download) throws RemoteException { - if (mClient != null) { - mClient.downloadStarted(download.getClientDownload()); - } - download.downloadStarted(); - } - - @CalledByNative - private void downloadProgressChanged(DownloadImpl download) throws RemoteException { - if (mClient != null) { - mClient.downloadProgressChanged(download.getClientDownload()); - } - download.downloadProgressChanged(); - } - - @CalledByNative - private void downloadCompleted(DownloadImpl download) throws RemoteException { - if (mClient != null) { - mClient.downloadCompleted(download.getClientDownload()); - } - download.downloadCompleted(); - } - - @CalledByNative - private void downloadFailed(DownloadImpl download) throws RemoteException { - if (mClient != null) { - mClient.downloadFailed(download.getClientDownload()); - } - download.downloadFailed(); - } - - @NativeMethods - interface Natives { - long createDownloadCallbackProxy(DownloadCallbackProxy proxy, long tab); - void deleteDownloadCallbackProxy(long proxy); - void allowDownload(long callbackId, boolean allow); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/DownloadImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/DownloadImpl.java deleted file mode 100644 index 2e84a7a..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/DownloadImpl.java +++ /dev/null
@@ -1,554 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.PendingIntent; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.RemoteException; -import android.text.TextUtils; - -import androidx.core.app.NotificationCompat; - -import org.chromium.base.ContentUriUtils; -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxy; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; -import org.chromium.components.browser_ui.notifications.NotificationMetadata; -import org.chromium.components.browser_ui.notifications.PendingIntentProvider; -import org.chromium.components.browser_ui.util.DownloadUtils; -import org.chromium.url.GURL; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.DownloadError; -import org.chromium.weblayer_private.interfaces.DownloadState; -import org.chromium.weblayer_private.interfaces.IClientDownload; -import org.chromium.weblayer_private.interfaces.IDownload; -import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.io.File; -import java.util.HashMap; - -/** - * Implementation of IDownload. - */ -@JNINamespace("weblayer") -public final class DownloadImpl extends IDownload.Stub { - private static final String DOWNLOADS_PREFIX = "org.chromium.weblayer.downloads"; - - // These actions have to be synchronized with the receiver defined in AndroidManifest.xml. - private static final String OPEN_INTENT = DOWNLOADS_PREFIX + ".OPEN"; - private static final String ACTIVATE_TRANSIENT_INTENT = - DOWNLOADS_PREFIX + ".ACTIVATE_TRANSIENT"; - private static final String DELETE_INTENT = DOWNLOADS_PREFIX + ".DELETE"; - private static final String PAUSE_INTENT = DOWNLOADS_PREFIX + ".PAUSE"; - private static final String RESUME_INTENT = DOWNLOADS_PREFIX + ".RESUME"; - private static final String CANCEL_INTENT = DOWNLOADS_PREFIX + ".CANCEL"; - - private static final String EXTRA_NOTIFICATION_ID = DOWNLOADS_PREFIX + ".NOTIFICATION_ID"; - private static final String EXTRA_NOTIFICATION_LOCATION = - DOWNLOADS_PREFIX + ".NOTIFICATION_LOCATION"; - private static final String EXTRA_NOTIFICATION_MIME_TYPE = - DOWNLOADS_PREFIX + ".NOTIFICATION_MIME_TYPE"; - private static final String EXTRA_NOTIFICATION_PROFILE = - DOWNLOADS_PREFIX + ".NOTIFICATION_PROFILE"; - private static final String EXTRA_NOTIFICATION_PROFILE_IS_INCOGNITO = - DOWNLOADS_PREFIX + ".NOTIFICATION_PROFILE_IS_INCOGNITO"; - private static final String EXTRA_NOTIFICATION_SESSION_ID = - DOWNLOADS_PREFIX + ".NOTIFICATION_SESSION_ID"; - // The intent prefix is used as the notification's tag since it's guaranteed not to conflict - // with intent prefixes used by other subsystems that display notifications. - private static final String NOTIFICATION_TAG = DOWNLOADS_PREFIX; - private static final String TAG = "DownloadImpl"; - - private final String mProfileName; - private final boolean mIsIncognito; - // The client is only used for downloads to disk, so it will be null for transient downloads. - private final IDownloadCallbackClient mClient; - private final IClientDownload mClientDownload; - // WARNING: DownloadImpl may outlive the native side, in which case this member is set to 0. - private long mNativeDownloadImpl; - private boolean mDisableNotification; - - // The time this download started, in milliseconds. - private final long mStartTime; - - // A transient download is not persisted to disk, which affects its UI treatment. - private final boolean mIsTransient; - - // The originating URL for this download. - private final GURL mSourceUrl; - - // The large icon to show. Once this is successfully fetched from native, it won't be updated. - private Bitmap mLargeIcon; - - private final int mNotificationId; - private static final HashMap<Integer, DownloadImpl> sMap = new HashMap<Integer, DownloadImpl>(); - - /** - * @return a string that prefixes all intents that can be handled by {@link forwardIntent}. - */ - public static String getIntentPrefix() { - return DOWNLOADS_PREFIX; - } - - public static void forwardIntent( - Context context, Intent intent, ProfileManager profileManager) { - if (intent.getAction().equals(OPEN_INTENT)) { - String location = intent.getStringExtra(EXTRA_NOTIFICATION_LOCATION); - if (TextUtils.isEmpty(location)) { - Log.d(TAG, "Didn't find location for open intent"); - return; - } - - String mimeType = intent.getStringExtra(EXTRA_NOTIFICATION_MIME_TYPE); - - Intent openIntent = new Intent(Intent.ACTION_VIEW); - if (TextUtils.isEmpty(mimeType)) { - openIntent.setData(getDownloadUri(location)); - } else { - openIntent.setDataAndType(getDownloadUri(location), mimeType); - } - openIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - openIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - openIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - context.startActivity(openIntent); - } catch (ActivityNotFoundException ex) { - // TODO: show some UI that there were no apps to handle this? - } - - return; - } - - String profileName = intent.getStringExtra(EXTRA_NOTIFICATION_PROFILE); - boolean isIncognito; - if (intent.hasExtra(EXTRA_NOTIFICATION_PROFILE_IS_INCOGNITO)) { - isIncognito = intent.getBooleanExtra(EXTRA_NOTIFICATION_PROFILE_IS_INCOGNITO, false); - } else { - isIncognito = "".equals(profileName); - } - - ProfileImpl profile = profileManager.getProfile(profileName, isIncognito); - if (!profile.areDownloadsInitialized()) { - profile.addDownloadNotificationIntent(intent); - } else { - handleIntent(intent); - } - } - - public static void handleIntent(Intent intent) { - int id = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); - DownloadImpl download = sMap.get(id); - if (download == null) { - Log.d(TAG, "Didn't find download for " + id); - // TODO(jam): handle download resumption after restart - return; - } - - if (intent.getAction().equals(PAUSE_INTENT)) { - download.pause(); - } else if (intent.getAction().equals(RESUME_INTENT)) { - download.resume(); - } else if (intent.getAction().equals(CANCEL_INTENT)) { - download.cancel(); - } else if (intent.getAction().equals(DELETE_INTENT)) { - sMap.remove(id); - DownloadImplJni.get().onFinishedImpl(download.mNativeDownloadImpl, /*activated=*/false); - } else if (intent.getAction().equals(ACTIVATE_TRANSIENT_INTENT)) { - assert download.mIsTransient; - DownloadImplJni.get().onFinishedImpl(download.mNativeDownloadImpl, /*activated=*/true); - } - } - - public DownloadImpl(String profileName, boolean isIncognito, IDownloadCallbackClient client, - long nativeDownloadImpl, int id, boolean isTransient, GURL sourceUrl) { - mProfileName = profileName; - mIsIncognito = isIncognito; - mClient = isTransient ? null : client; - mNativeDownloadImpl = nativeDownloadImpl; - mNotificationId = id; - mStartTime = System.currentTimeMillis(); - mIsTransient = isTransient; - mSourceUrl = sourceUrl; - - if (mClient == null) { - mClientDownload = null; - } else { - try { - mClientDownload = mClient.createClientDownload(this); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - DownloadImplJni.get().setJavaDownload(mNativeDownloadImpl, DownloadImpl.this); - } - - public IClientDownload getClientDownload() { - return mClientDownload; - } - - @DownloadState - private static int implStateToJavaType(@ImplDownloadState int type) { - switch (type) { - case ImplDownloadState.IN_PROGRESS: - return DownloadState.IN_PROGRESS; - case ImplDownloadState.COMPLETE: - return DownloadState.COMPLETE; - case ImplDownloadState.PAUSED: - return DownloadState.PAUSED; - case ImplDownloadState.CANCELLED: - return DownloadState.CANCELLED; - case ImplDownloadState.FAILED: - return DownloadState.FAILED; - } - assert false; - return DownloadState.FAILED; - } - - @DownloadError - private static int implErrorToJavaType(@ImplDownloadError int type) { - switch (type) { - case ImplDownloadError.NO_ERROR: - return DownloadError.NO_ERROR; - case ImplDownloadError.SERVER_ERROR: - return DownloadError.SERVER_ERROR; - case ImplDownloadError.SSL_ERROR: - return DownloadError.SSL_ERROR; - case ImplDownloadError.CONNECTIVITY_ERROR: - return DownloadError.CONNECTIVITY_ERROR; - case ImplDownloadError.NO_SPACE: - return DownloadError.NO_SPACE; - case ImplDownloadError.FILE_ERROR: - return DownloadError.FILE_ERROR; - case ImplDownloadError.CANCELLED: - return DownloadError.CANCELLED; - case ImplDownloadError.OTHER_ERROR: - return DownloadError.OTHER_ERROR; - } - assert false; - return DownloadError.OTHER_ERROR; - } - - @Override - @DownloadState - public int getState() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return implStateToJavaType(DownloadImplJni.get().getStateImpl(mNativeDownloadImpl)); - } - - @Override - public long getTotalBytes() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return DownloadImplJni.get().getTotalBytesImpl(mNativeDownloadImpl); - } - - @Override - public long getReceivedBytes() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return DownloadImplJni.get().getReceivedBytesImpl(mNativeDownloadImpl); - } - - @Override - public void pause() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - DownloadImplJni.get().pauseImpl(mNativeDownloadImpl); - updateNotification(); - } - - @Override - public void resume() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - DownloadImplJni.get().resumeImpl(mNativeDownloadImpl); - updateNotification(); - } - - @Override - public void cancel() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - DownloadImplJni.get().cancelImpl(mNativeDownloadImpl); - updateNotification(); - } - - @Override - public String getLocation() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return DownloadImplJni.get().getLocationImpl(mNativeDownloadImpl); - } - - @Override - public String getFileNameToReportToUser() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return DownloadImplJni.get().getFileNameToReportToUserImpl(mNativeDownloadImpl); - } - - @Override - public String getMimeType() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return DownloadImplJni.get().getMimeTypeImpl(mNativeDownloadImpl); - } - - @Override - @DownloadError - public int getError() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return implErrorToJavaType(DownloadImplJni.get().getErrorImpl(mNativeDownloadImpl)); - } - - @Override - public void disableNotification() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - mDisableNotification = true; - - NotificationManagerProxy notificationManager = getNotificationManager(); - notificationManager.cancel(NOTIFICATION_TAG, mNotificationId); - } - - private void throwIfNativeDestroyed() { - if (mNativeDownloadImpl == 0) { - throw new IllegalStateException("Using Download after native destroyed"); - } - } - - private Intent createIntent(String actionId) { - // Because the intent is using classes from the implementation's class loader, - // we need to use the constructor which doesn't take the app's context. - Intent intent = WebLayerImpl.createIntent(); - intent.setAction(actionId); - intent.putExtra(EXTRA_NOTIFICATION_ID, mNotificationId); - intent.putExtra(EXTRA_NOTIFICATION_PROFILE, mProfileName); - intent.putExtra(EXTRA_NOTIFICATION_PROFILE_IS_INCOGNITO, mIsIncognito); - return intent; - } - - public void downloadStarted() { - if (mDisableNotification) return; - - // TODO(jam): create a foreground service while the download is running to avoid the process - // being shut down if the user switches apps. - - sMap.put(Integer.valueOf(mNotificationId), this); - - updateNotification(); - } - - public void downloadProgressChanged() { - updateNotification(); - } - - public void downloadCompleted() { - updateNotification(); - } - - public void downloadFailed() { - updateNotification(); - } - - private void updateNotification() { - NotificationManagerProxy notificationManager = getNotificationManager(); - if (mDisableNotification || notificationManager == null) return; - - Context context = ContextUtils.getApplicationContext(); - - Intent deleteIntent = createIntent(DELETE_INTENT); - PendingIntentProvider deletePendingIntent = getPendingIntentProvider(deleteIntent); - - @DownloadState - int state = getState(); - if (state == DownloadState.CANCELLED) { - notificationManager.cancel(NOTIFICATION_TAG, mNotificationId); - mDisableNotification = true; - return; - } - - String channelId = state == DownloadState.COMPLETE - ? WebLayerNotificationChannels.ChannelId.COMPLETED_DOWNLOADS - : WebLayerNotificationChannels.ChannelId.ACTIVE_DOWNLOADS; - - WebLayerNotificationWrapperBuilder builder = WebLayerNotificationWrapperBuilder.create( - channelId, new NotificationMetadata(0, NOTIFICATION_TAG, mNotificationId)); - builder.setOngoing(true) - .setWhen(mStartTime) - .setShowWhen(true) - .setDeleteIntent(deletePendingIntent) - .setPriorityBeforeO(NotificationCompat.PRIORITY_DEFAULT); - - // The filename might not have been available initially. - String name = getFileNameToReportToUser(); - if (!TextUtils.isEmpty(name)) { - builder.setContentTitle(name); - } - - // Set the large icon/thumbnail, except when incognito. - if (!mIsIncognito && mLargeIcon == null) { - mLargeIcon = DownloadImplJni.get().getLargeIconImpl(mNativeDownloadImpl); - } - if (mLargeIcon != null) { - builder.setLargeIcon(mLargeIcon); - } - - // As with Chrome, transient downloads "promote" the source URL. - if (!mIsIncognito && mIsTransient) { - String formattedUrl = DownloadUtils.formatUrlForDisplayInNotification(mSourceUrl); - if (formattedUrl != null) builder.setSubText(formattedUrl); - } - // TODO(estade): In incognito, Chrome uses a subtext of "Incognito tab". Should WL display - // something similar? - - Resources resources = context.getResources(); - - if (state == DownloadState.COMPLETE) { - builder.setOngoing(false) - .setSmallIcon(android.R.drawable.stat_sys_download_done) - .setAutoCancel(true) - .setProgress(0, 0, false); - - Intent openIntent = null; - - if (mIsTransient) { - builder.setContentText( - resources.getString(R.string.download_notification_completed)); - openIntent = createIntent(ACTIVATE_TRANSIENT_INTENT); - } else { - builder.setContentText( - resources.getString(R.string.download_notification_completed_with_size, - DownloadUtils.getStringForBytes(context, getTotalBytes()))); - - openIntent = createIntent(OPEN_INTENT); - openIntent.putExtra(EXTRA_NOTIFICATION_LOCATION, getLocation()); - openIntent.putExtra(EXTRA_NOTIFICATION_MIME_TYPE, getMimeType()); - } - builder.setContentIntent(getPendingIntentProvider(openIntent)); - } else if (state == DownloadState.FAILED) { - builder.setContentText(resources.getString(R.string.download_notification_failed)) - .setOngoing(false) - .setSmallIcon(android.R.drawable.stat_sys_download_done) - .setProgress(0, 0, false); - } else if (state == DownloadState.IN_PROGRESS) { - Intent pauseIntent = createIntent(PAUSE_INTENT); - PendingIntentProvider pausePendingIntent = getPendingIntentProvider(pauseIntent); - - long bytes = getReceivedBytes(); - long totalBytes = getTotalBytes(); - boolean indeterminate = totalBytes == -1; - int progressCurrent = -1; - if (!indeterminate && totalBytes != 0) { - progressCurrent = (int) (bytes * 100 / totalBytes); - } - - if (!mIsTransient) { - String contentText; - String bytesString = DownloadUtils.getStringForBytes(context, bytes); - if (indeterminate) { - contentText = resources.getString( - R.string.download_ui_indeterminate_bytes, bytesString); - } else { - String totalString = DownloadUtils.getStringForBytes(context, totalBytes); - contentText = resources.getString( - R.string.download_ui_determinate_bytes, bytesString, totalString); - } - builder.setContentText(contentText); - } - builder.addAction(0 /* no icon */, - resources.getString(R.string.download_notification_pause_button), - pausePendingIntent, 0 /* no action for UMA */) - .setSmallIcon(android.R.drawable.stat_sys_download) - .setProgress(100, progressCurrent, indeterminate); - } else if (state == DownloadState.PAUSED) { - Intent resumeIntent = createIntent(RESUME_INTENT); - PendingIntentProvider resumePendingIntent = getPendingIntentProvider(resumeIntent); - builder.setContentText(resources.getString(R.string.download_notification_paused)) - .addAction(0 /* no icon */, - resources.getString(R.string.download_notification_resume_button), - resumePendingIntent, 0 /* no action for UMA */) - .setSmallIcon(android.R.drawable.ic_media_pause) - .setProgress(0, 0, false); - } - - if (state == DownloadState.IN_PROGRESS || state == DownloadState.PAUSED) { - Intent cancelIntent = createIntent(CANCEL_INTENT); - PendingIntentProvider cancelPendingIntent = getPendingIntentProvider(cancelIntent); - builder.addAction(0 /* no icon */, - resources.getString(R.string.download_notification_cancel_button), - cancelPendingIntent, 0 /* no action for UMA */); - } - - notificationManager.notify(builder.buildNotificationWrapper()); - } - - private PendingIntentProvider getPendingIntentProvider(Intent notificationIntent) { - // Transient intents use FLAG_CANCEL_CURRENT because the IDs can overlap across sessions. - // CANCEL_CURRENT makes sure the PendingIntent is not also reused, and prevents intents from - // old sessions from working (e.g. notifications lingering after WebLayer has crashed and - // failed to clear them). - return PendingIntentProvider.getBroadcast(ContextUtils.getApplicationContext(), - mNotificationId, notificationIntent, - mIsTransient ? PendingIntent.FLAG_CANCEL_CURRENT : 0); - } - - /** - * Returns the notification manager. - */ - private static NotificationManagerProxy getNotificationManager() { - return new NotificationManagerProxyImpl(ContextUtils.getApplicationContext()); - } - - private static Uri getDownloadUri(String location) { - if (ContentUriUtils.isContentUri(location)) return Uri.parse(location); - return ContentUriUtils.getContentUriFromFile(new File(location)); - } - - public static void activateNotificationForTesting(int id) { - DownloadImpl download = sMap.get(id); - assert download != null; - DownloadImplJni.get().onFinishedImpl(download.mNativeDownloadImpl, /*activated=*/true); - } - - @CalledByNative - private void onNativeDestroyed() { - mNativeDownloadImpl = 0; - sMap.remove(mNotificationId); - if (mIsTransient) { - getNotificationManager().cancel(NOTIFICATION_TAG, mNotificationId); - } - // TODO: this should likely notify delegate in some way. - } - - @NativeMethods - interface Natives { - void setJavaDownload(long nativeDownloadImpl, DownloadImpl caller); - int getStateImpl(long nativeDownloadImpl); - long getTotalBytesImpl(long nativeDownloadImpl); - long getReceivedBytesImpl(long nativeDownloadImpl); - void pauseImpl(long nativeDownloadImpl); - void resumeImpl(long nativeDownloadImpl); - void cancelImpl(long nativeDownloadImpl); - void onFinishedImpl(long nativeDownloadImpl, boolean activated); - String getLocationImpl(long nativeDownloadImpl); - String getFileNameToReportToUserImpl(long nativeDownloadImpl); - String getMimeTypeImpl(long nativeDownloadImpl); - int getErrorImpl(long nativeDownloadImpl); - Bitmap getLargeIconImpl(long nativeDownloadImpl); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ErrorPageCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/ErrorPageCallbackProxy.java deleted file mode 100644 index ef80c1d9..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ErrorPageCallbackProxy.java +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient; - -/** - * Owns the c++ ErrorPageCallbackProxy class, which is responsible for forwarding all - * ErrorPageDelegate calls to this class, which in turn forwards to the - * ErrorPageCallbackClient. - */ -@JNINamespace("weblayer") -public final class ErrorPageCallbackProxy { - private long mNativeErrorPageCallbackProxy; - private IErrorPageCallbackClient mClient; - - ErrorPageCallbackProxy(long tab, IErrorPageCallbackClient client) { - assert client != null; - mClient = client; - mNativeErrorPageCallbackProxy = - ErrorPageCallbackProxyJni.get().createErrorPageCallbackProxy(this, tab); - } - - public void setClient(IErrorPageCallbackClient client) { - assert client != null; - mClient = client; - } - - public void destroy() { - ErrorPageCallbackProxyJni.get().deleteErrorPageCallbackProxy(mNativeErrorPageCallbackProxy); - mNativeErrorPageCallbackProxy = 0; - } - - @CalledByNative - private boolean onBackToSafety() throws RemoteException { - return mClient.onBackToSafety(); - } - - @CalledByNative - private String getErrorPageContent(NavigationImpl navigation) throws RemoteException { - return mClient.getErrorPageContent(navigation.getClientNavigation()); - } - - @NativeMethods - interface Natives { - long createErrorPageCallbackProxy(ErrorPageCallbackProxy proxy, long tab); - void deleteErrorPageCallbackProxy(long proxy); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ExternalIntentInIncognitoCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/ExternalIntentInIncognitoCallbackProxy.java deleted file mode 100644 index f3b8d0a..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ExternalIntentInIncognitoCallbackProxy.java +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import org.chromium.base.Callback; -import org.chromium.weblayer_private.interfaces.IExternalIntentInIncognitoCallbackClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * Proxies calls to present the warning dialog gating external intent launches in incognito to - * ExternalIntentInIncognitoCallbackClient. - */ -public final class ExternalIntentInIncognitoCallbackProxy { - private IExternalIntentInIncognitoCallbackClient mClient; - - ExternalIntentInIncognitoCallbackProxy(IExternalIntentInIncognitoCallbackClient client) { - setClient(client); - } - - void setClient(IExternalIntentInIncognitoCallbackClient client) { - mClient = client; - } - - /* - * Proxies onExternalIntentInIncognito() calls to the client. - */ - void onExternalIntentInIncognito(Callback<Integer> onUserDecisionCallback) - throws RemoteException { - assert mClient != null; - - ValueCallback<Integer> onUserDecisionValueCallback = (Integer userDecision) -> { - onUserDecisionCallback.onResult(userDecision); - }; - - mClient.onExternalIntentInIncognito(ObjectWrapper.wrap(onUserDecisionValueCallback)); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java deleted file mode 100644 index daa24f2..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java +++ /dev/null
@@ -1,178 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.os.RemoteException; - -import org.chromium.base.Callback; -import org.chromium.base.supplier.Supplier; -import org.chromium.components.embedder_support.util.UrlUtilities; -import org.chromium.components.external_intents.ExternalNavigationDelegate; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.url.GURL; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.ExternalIntentInIncognitoUserDecision; - -import java.util.List; - -/** - * WebLayer's implementation of the {@link ExternalNavigationDelegate}. - */ -public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegate { - private final TabImpl mTab; - private boolean mTabDestroyed; - - public ExternalNavigationDelegateImpl(TabImpl tab) { - assert tab != null; - mTab = tab; - } - - public void onTabDestroyed() { - mTabDestroyed = true; - } - - @Override - public Context getContext() { - return mTab.getBrowser().getContext(); - } - - @Override - public boolean willAppHandleIntent(Intent intent) { - return false; - } - - @Override - public boolean shouldDisableExternalIntentRequestsForUrl(GURL url) { - return !mTab.getBrowser().isExternalIntentsEnabled(); - } - - @Override - public boolean shouldAvoidDisambiguationDialog(GURL intentDataUrl) { - // Don't show the disambiguation dialog if WebLayer can handle the intent. - return UrlUtilities.isAcceptedScheme(intentDataUrl); - } - - @Override - public boolean isApplicationInForeground() { - return mTab.getBrowser().getBrowserFragment().isVisible(); - } - - @Override - public void maybeSetWindowId(Intent intent) {} - - @Override - public boolean canLoadUrlInCurrentTab() { - return true; - } - - @Override - public void closeTab() { - InterceptNavigationDelegateClientImpl.closeTab(mTab); - } - - @Override - public boolean isIncognito() { - return mTab.getProfile().isIncognito(); - } - - @Override - public boolean hasCustomLeavingIncognitoDialog() { - return mTab.getExternalIntentInIncognitoCallbackProxy() != null; - } - - @Override - public void presentLeavingIncognitoModalDialog(Callback<Boolean> onUserDecision) { - try { - mTab.getExternalIntentInIncognitoCallbackProxy().onExternalIntentInIncognito( - (Integer result) -> { - @ExternalIntentInIncognitoUserDecision - int userDecision = result.intValue(); - switch (userDecision) { - case ExternalIntentInIncognitoUserDecision.ALLOW: - onUserDecision.onResult(Boolean.valueOf(true)); - break; - case ExternalIntentInIncognitoUserDecision.DENY: - onUserDecision.onResult(Boolean.valueOf(false)); - break; - default: - assert false; - } - }); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @Override - // This is relevant only if the intent ends up being handled by this app, which does not happen - // for WebLayer. - public void maybeSetRequestMetadata( - Intent intent, boolean hasUserGesture, boolean isRendererInitiated) {} - - @Override - // This is relevant only if the intent ends up being handled by this app, which does not happen - // for WebLayer. - public void maybeSetPendingReferrer(Intent intent, GURL referrerUrl) {} - - @Override - // This is relevant only if the intent ends up being handled by this app, which does not happen - // for WebLayer. - public void maybeSetPendingIncognitoUrl(Intent intent) {} - - @Override - public WindowAndroid getWindowAndroid() { - return mTab.getBrowser().getBrowserFragment().getWindowAndroid(); - } - - @Override - public WebContents getWebContents() { - return mTab.getWebContents(); - } - - @Override - public boolean hasValidTab() { - assert mTab != null; - return !mTabDestroyed; - } - - @Override - public boolean canCloseTabOnIncognitoIntentLaunch() { - return hasValidTab(); - } - - @Override - public boolean isForTrustedCallingApp(Supplier<List<ResolveInfo>> resolveInfoSupplier) { - return false; - } - - @Override - public boolean shouldLaunchWebApksOnInitialIntent() { - return false; - } - - @Override - public void setPackageForTrustedCallingApp(Intent intent) { - assert false; - } - - @Override - public boolean shouldEmbedderInitiatedNavigationsStayInBrowser() { - // WebLayer already has APIs that allow the embedder to specify that a navigation shouldn't - // result in an external intent (Navigation#disableIntentProcessing() and - // NavigateParams#disableIntentProcessing()), and historically embedder-initiated - // navigations have been allowed to leave the browser on the initial navigation, so we need - // to maintain that behavior. - return false; - } - - @Override - public String getSelfScheme() { - return null; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java deleted file mode 100644 index 6465e60..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.graphics.Bitmap; -import android.os.RemoteException; -import android.util.AndroidRuntimeException; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.IFaviconFetcher; -import org.chromium.weblayer_private.interfaces.IFaviconFetcherClient; - -/** - * Owns the c++ ErrorPageCallbackProxy class, which is responsible for forwarding all - * ErrorPageDelegate calls to this class, which in turn forwards to the - * ErrorPageCallbackClient. - */ -@JNINamespace("weblayer") -public final class FaviconCallbackProxy extends IFaviconFetcher.Stub { - private TabImpl mTab; - private long mNativeFaviconCallbackProxy; - private IFaviconFetcherClient mClient; - - FaviconCallbackProxy(TabImpl tab, long nativeTab, IFaviconFetcherClient client) { - assert client != null; - mTab = tab; - mClient = client; - mNativeFaviconCallbackProxy = - FaviconCallbackProxyJni.get().createFaviconCallbackProxy(this, nativeTab); - } - - @Override - public void destroy() { - // As Tab implicitly destroys this, and the embedder is allowed to destroy this, allow - // destroy() to be called multiple times. - if (mNativeFaviconCallbackProxy == 0) { - return; - } - mTab.removeFaviconCallbackProxy(this); - try { - mClient.onDestroyed(); - } catch (RemoteException e) { - throw new AndroidRuntimeException(e); - } - FaviconCallbackProxyJni.get().deleteFaviconCallbackProxy(mNativeFaviconCallbackProxy); - mNativeFaviconCallbackProxy = 0; - mClient = null; - } - - @CalledByNative - private void onFaviconChanged(Bitmap bitmap) throws RemoteException { - mTab.onFaviconChanged(bitmap); - mClient.onFaviconChanged(bitmap); - } - - @NativeMethods - interface Natives { - long createFaviconCallbackProxy(FaviconCallbackProxy proxy, long tab); - void deleteFaviconCallbackProxy(long proxy); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/FragmentAndroidPermissionDelegate.java b/weblayer/browser/java/org/chromium/weblayer_private/FragmentAndroidPermissionDelegate.java deleted file mode 100644 index e4ef6a9..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/FragmentAndroidPermissionDelegate.java +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.compat.ApiHelperForM; -import org.chromium.ui.permissions.AndroidPermissionDelegateWithRequester; - -/** - * AndroidPermissionDelegate implementation for BrowserFragment. - */ -public class FragmentAndroidPermissionDelegate extends AndroidPermissionDelegateWithRequester { - private BrowserFragmentImpl mFragment; - - public FragmentAndroidPermissionDelegate(BrowserFragmentImpl fragment) { - mFragment = fragment; - } - - @Override - public final boolean shouldShowRequestPermissionRationale(String permission) { - if (mFragment.getActivity() == null) return false; - return mFragment.shouldShowRequestPermissionRationale(permission); - } - - @Override - protected final boolean isPermissionRevokedByPolicyInternal(String permission) { - if (mFragment.getActivity() == null) return false; - return ApiHelperForM.isPermissionRevokedByPolicy(mFragment.getActivity(), permission); - } - - @Override - protected final boolean requestPermissionsFromRequester(String[] permissions, int requestCode) { - if (mFragment.getActivity() == null) return false; - mFragment.requestPermissions(permissions, requestCode); - return true; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java deleted file mode 100644 index b118120..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java +++ /dev/null
@@ -1,251 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.content.ContextWrapper; -import android.os.Handler; -import android.util.AttributeSet; -import android.view.InflateException; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewStub; - -import androidx.appcompat.app.AppCompatDelegate; -import androidx.fragment.app.FragmentController; -import androidx.fragment.app.FragmentHostCallback; -import androidx.fragment.app.FragmentManager; - -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.lang.reflect.Constructor; - -/** - * A base class for RemoteFragmentImpls that need to host child Fragments. - * - * Because Fragments created in WebLayer use the AndroidX library from WebLayer's ClassLoader, we - * can't attach Fragments created here directly to the embedder's Fragment tree, and have to create - * a local FragmentController to manage them. This class handles creating the FragmentController, - * and forwards all Fragment lifecycle events from the RemoteFragment in the embedder's Fragment - * tree to child Fragments of this class. - */ -public abstract class FragmentHostingRemoteFragmentImpl extends RemoteFragmentImpl { - // The WebLayer-wrapped context object. This context gets assets and resources from WebLayer, - // not from the embedder. Use this for the most part, especially to resolve WebLayer-specific - // resource IDs. - private Context mContext; - - private boolean mStarted; - private FragmentController mFragmentController; - - protected static class RemoteFragmentContext - extends ContextWrapper implements LayoutInflater.Factory2 { - private static final Class<?>[] VIEW_CONSTRUCTOR_ARGS = - new Class[] {Context.class, AttributeSet.class}; - - public RemoteFragmentContext(Context webLayerContext) { - super(webLayerContext); - } - - // This method is needed to work around a LayoutInflater bug in Android <N. Before - // LayoutInflater creates an instance of a View, it needs to look up the class by name to - // get a reference to its Constructor. As an optimization, it caches this name to - // Constructor mapping. This cache causes issues if a class gets loaded multiple times with - // different ClassLoaders. In some UIs, some AndroidX Views get loaded early on with the - // embedding app's ClassLoader, so the Constructor from that ClassLoader's version of the - // class gets cached. When the WebLayer implementation later tries to inflate the same - // class, it instantiates a version from the wrong ClassLoader, which leads to a - // ClassCastException when casting that View to its original class. This was fixed in - // Android N, but to work around it on L & M, we inflate the Views manually here, which - // bypasses LayoutInflater's cache. - @Override - public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { - // If the class doesn't have a '.' in its name, it's probably a built-in Android View, - // which are often referenced by just their class names with no package prefix. For - // these classes we can return null to fall back to LayoutInflater's default behavior. - if (name.indexOf('.') == -1) { - return null; - } - - Class<? extends View> clazz = null; - try { - clazz = context.getClassLoader().loadClass(name).asSubclass(View.class); - LayoutInflater inflater = getLayoutInflater(); - if (inflater.getFilter() != null && !inflater.getFilter().onLoadClass(clazz)) { - throw new InflateException(attrs.getPositionDescription() - + ": Class not allowed to be inflated " + name); - } - - Constructor<? extends View> constructor = - clazz.getConstructor(VIEW_CONSTRUCTOR_ARGS); - constructor.setAccessible(true); - View view = constructor.newInstance(new Object[] {context, attrs}); - if (view instanceof ViewStub) { - // Use the same Context when inflating ViewStub later. - ViewStub viewStub = (ViewStub) view; - viewStub.setLayoutInflater(inflater.cloneInContext(context)); - } - return view; - } catch (Exception e) { - InflateException ie = new InflateException(attrs.getPositionDescription() - + ": Error inflating class " - + (clazz == null ? "<unknown>" : clazz.getName())); - ie.initCause(e); - throw ie; - } - } - - @Override - public View onCreateView(String name, Context context, AttributeSet attrs) { - StrictModeWorkaround.apply(); - return null; - } - - private LayoutInflater getLayoutInflater() { - return (LayoutInflater) getBaseContext().getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - } - } - - private static class RemoteFragmentHostCallback extends FragmentHostCallback<Context> { - private final FragmentHostingRemoteFragmentImpl mFragmentImpl; - - private RemoteFragmentHostCallback(FragmentHostingRemoteFragmentImpl fragmentImpl) { - super(fragmentImpl.getWebLayerContext(), new Handler(), 0); - mFragmentImpl = fragmentImpl; - } - - @Override - public Context onGetHost() { - return mFragmentImpl.getWebLayerContext(); - } - - @Override - public LayoutInflater onGetLayoutInflater() { - Context context = mFragmentImpl.getWebLayerContext(); - return ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)) - .cloneInContext(context); - } - - @Override - public boolean onHasView() { - // This is always false. - return mFragmentImpl.getView() != null; - } - - @Override - public View onFindViewById(int id) { - // This is always null. - return onHasView() ? mFragmentImpl.getView().findViewById(id) : null; - } - } - - protected FragmentHostingRemoteFragmentImpl(Context context) { - super(); - mContext = createRemoteFragmentContext(context); - } - - @Override - protected void onAttach(Context embedderContext) { - StrictModeWorkaround.apply(); - super.onAttach(embedderContext); - - // Some appcompat functionality depends on Fragments being hosted from within an - // AppCompatActivity, which performs some static initialization. Even if we're running - // within an AppCompatActivity, it will be from the embedder's ClassLoader, so in WebLayer's - // ClassLoader the initialization hasn't occurred. Creating an AppCompatDelegate manually - // here will perform the necessary initialization. - if (getActivity() != null) { - AppCompatDelegate.create(getActivity(), null); - } - } - - @Override - protected void onCreate() { - StrictModeWorkaround.apply(); - super.onCreate(); - - mFragmentController = - FragmentController.createController(new RemoteFragmentHostCallback(this)); - mFragmentController.attachHost(null); - - mFragmentController.dispatchCreate(); - } - - @Override - protected void onDestroyView() { - StrictModeWorkaround.apply(); - super.onDestroyView(); - mFragmentController.dispatchDestroyView(); - } - - @Override - protected void onDestroy() { - StrictModeWorkaround.apply(); - super.onDestroy(); - - if (!mFragmentController.getSupportFragmentManager().isDestroyed()) { - mFragmentController.dispatchDestroy(); - assert mFragmentController.getSupportFragmentManager().isDestroyed(); - } - } - - @Override - protected void onDetach() { - StrictModeWorkaround.apply(); - super.onDetach(); - } - - @Override - protected void onStart() { - StrictModeWorkaround.apply(); - super.onStart(); - - if (!mStarted) { - mStarted = true; - mFragmentController.dispatchActivityCreated(); - } - mFragmentController.noteStateNotSaved(); - mFragmentController.execPendingActions(); - mFragmentController.dispatchStart(); - } - - @Override - protected void onStop() { - StrictModeWorkaround.apply(); - super.onStop(); - mFragmentController.dispatchStop(); - } - - @Override - protected void onResume() { - StrictModeWorkaround.apply(); - super.onResume(); - mFragmentController.dispatchResume(); - } - - @Override - protected void onPause() { - StrictModeWorkaround.apply(); - super.onPause(); - mFragmentController.dispatchPause(); - } - - public FragmentManager getSupportFragmentManager() { - return mFragmentController.getSupportFragmentManager(); - } - - /** - * Returns the RemoteFragmentContext that should be used in the child Fragment tree. - * - * Implementations will typically wrap embedderContext with ClassLoaderContextWrapperFactory, - * and possibly set a Theme. - */ - protected abstract RemoteFragmentContext createRemoteFragmentContext(Context embedderContext); - - protected Context getWebLayerContext() { - return mContext; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/FragmentWindowAndroid.java b/weblayer/browser/java/org/chromium/weblayer_private/FragmentWindowAndroid.java deleted file mode 100644 index ce76266..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/FragmentWindowAndroid.java +++ /dev/null
@@ -1,124 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.IntentSender; -import android.os.Build; -import android.view.View; - -import androidx.annotation.RequiresApi; -import androidx.fragment.app.FragmentManager; - -import org.chromium.ui.base.ActivityKeyboardVisibilityDelegate; -import org.chromium.ui.base.ImmutableWeakReference; -import org.chromium.ui.base.IntentRequestTracker; -import org.chromium.ui.base.IntentRequestTracker.Delegate; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.ui.modaldialog.ModalDialogManager; - -import java.lang.ref.WeakReference; - -/** - * Implements intent sending for a fragment based window. This should be created when - * onAttach() is called on the fragment, and destroyed when onDetach() is called. - */ -public class FragmentWindowAndroid extends WindowAndroid { - private final BrowserFragmentImpl mFragment; - private ModalDialogManager mModalDialogManager; - - /** - * WebLayer's implementation of the delegate of a IntentRequestTracker. - */ - private static class TrackerDelegateImpl implements Delegate { - private final RemoteFragmentImpl mFragment; - // This WeakReference is purely to avoid gc churn of creating a new WeakReference in - // every getActivity call. It is not needed for correctness. - private ImmutableWeakReference<Activity> mActivityWeakRefHolder; - - /** - * Create an instance of delegate for the given fragment that will own the - * IntentRequestTracker. - * @param fragment The fragment that owns the IntentRequestTracker. - */ - private TrackerDelegateImpl(RemoteFragmentImpl fragment) { - mFragment = fragment; - } - - @Override - public boolean startActivityForResult(Intent intent, int requestCode) { - return mFragment.startActivityForResult(intent, requestCode, null); - } - - @Override - public boolean startIntentSenderForResult(IntentSender intentSender, int requestCode) { - return mFragment.startIntentSenderForResult( - intentSender, requestCode, new Intent(), 0, 0, 0, null); - } - - @Override - public void finishActivity(int requestCode) { - Activity activity = getActivity().get(); - if (activity == null) return; - activity.finishActivity(requestCode); - } - - @Override - public final WeakReference<Activity> getActivity() { - if (mActivityWeakRefHolder == null - || mActivityWeakRefHolder.get() != mFragment.getActivity()) { - mActivityWeakRefHolder = new ImmutableWeakReference<>(mFragment.getActivity()); - } - return mActivityWeakRefHolder; - } - } - - /* package */ FragmentWindowAndroid(Context context, BrowserFragmentImpl fragment) { - super(context, IntentRequestTracker.createFromDelegate(new TrackerDelegateImpl(fragment))); - mFragment = fragment; - - setKeyboardDelegate(new ActivityKeyboardVisibilityDelegate(getActivity())); - setAndroidPermissionDelegate(new FragmentAndroidPermissionDelegate(mFragment)); - } - - @Override - public final WeakReference<Activity> getActivity() { - return getIntentRequestTracker().getActivity(); - } - - @Override - public final ModalDialogManager getModalDialogManager() { - return mModalDialogManager; - } - - @Override - public View getReadbackView() { - BrowserViewController viewController = mFragment.getPossiblyNullViewController(); - if (viewController == null) return null; - return viewController.getViewForMagnifierReadback(); - } - - public void setModalDialogManager(ModalDialogManager modalDialogManager) { - mModalDialogManager = modalDialogManager; - } - - public BrowserFragmentImpl getFragment() { - return mFragment; - } - - public FragmentManager getFragmentManager() { - return mFragment.getSupportFragmentManager(); - } - - @Override - @RequiresApi(Build.VERSION_CODES.O) - public void setWideColorEnabled(boolean enabled) { - // WebLayer should not change its behavior when the content contains wide color. - // Rather, the app embedding the WebLayer gets to choose whether or not it is wide. - // So we should do nothing in this override. - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/FullscreenCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/FullscreenCallbackProxy.java deleted file mode 100644 index 217348d6..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/FullscreenCallbackProxy.java +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.ThreadUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.IFullscreenCallbackClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * Owns the c++ FullscreenCallbackProxy class, which is responsible for forwarding all - * FullscreenDelegate delegate calls to this class, which in turn forwards to the - * FullscreenCallbackClient. - */ -@JNINamespace("weblayer") -public final class FullscreenCallbackProxy { - private long mNativeFullscreenCallbackProxy; - private IFullscreenCallbackClient mClient; - private TabImpl mTab; - private FullscreenToast mToast; - private boolean mIsNotifyingClientOfEnter; - // Used so that only the most recent callback supplied to the client is acted on. - private int mNextFullscreenId; - - FullscreenCallbackProxy(TabImpl tab, long nativeTab, IFullscreenCallbackClient client) { - assert client != null; - mClient = client; - mTab = tab; - mNativeFullscreenCallbackProxy = - FullscreenCallbackProxyJni.get().createFullscreenCallbackProxy(this, nativeTab); - } - - public void setClient(IFullscreenCallbackClient client) { - assert client != null; - mClient = client; - } - - public void destroy() { - FullscreenCallbackProxyJni.get().deleteFullscreenCallbackProxy( - mNativeFullscreenCallbackProxy); - mNativeFullscreenCallbackProxy = 0; - destroyToast(); - mTab = null; - } - - public void destroyToast() { - if (mToast == null) return; - mToast.destroy(); - mToast = null; - } - - @VisibleForTesting - public boolean didShowFullscreenToast() { - return mToast != null && mToast.didShowFullscreenToast(); - } - - @CalledByNative - private void enterFullscreen() throws RemoteException { - final int id = ++mNextFullscreenId; - ValueCallback<Void> exitFullscreenCallback = new ValueCallback<Void>() { - @Override - public void onReceiveValue(Void result) { - ThreadUtils.assertOnUiThread(); - if (id != mNextFullscreenId) { - // This is an old fullscreen request. Ignore it. - return; - } - if (mNativeFullscreenCallbackProxy == 0) { - throw new IllegalStateException("Called after destroy()"); - } - if (mIsNotifyingClientOfEnter) { - throw new IllegalStateException( - "Fullscreen callback must not be called synchronously"); - } - destroyToast(); - FullscreenCallbackProxyJni.get().doExitFullscreen(mNativeFullscreenCallbackProxy); - } - }; - destroyToast(); - mToast = new FullscreenToast(mTab); - mIsNotifyingClientOfEnter = true; - try { - mClient.enterFullscreen(ObjectWrapper.wrap(exitFullscreenCallback)); - } finally { - mIsNotifyingClientOfEnter = false; - } - } - - @CalledByNative - private void exitFullscreen() throws RemoteException { - mClient.exitFullscreen(); - destroyToast(); - } - - @NativeMethods - interface Natives { - long createFullscreenCallbackProxy(FullscreenCallbackProxy proxy, long tab); - void deleteFullscreenCallbackProxy(long proxy); - void doExitFullscreen(long nativeFullscreenCallbackProxy); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/FullscreenToast.java b/weblayer/browser/java/org/chromium/weblayer_private/FullscreenToast.java deleted file mode 100644 index 02a2ac4..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/FullscreenToast.java +++ /dev/null
@@ -1,105 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.view.Gravity; -import android.view.View; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.components.embedder_support.view.ContentView; -import org.chromium.ui.widget.Toast; - -/** - * FullscreenToast is responsible for showing toast when fullscreen mode is entered. As the embedder - * is responsible for entering fullscreen mode, there is no guarantee when or if fullscreen mode - * will be entered. This waits for the system to enter fullscreen mode and then show the toast. If - * fullscreen isn't entered after a short delay this assumes the embedder won't enter fullscreen - * and the toast is never shown. - */ -public final class FullscreenToast { - // The tab the toast is showing from. - private TabImpl mTab; - - // View used to register for system ui change notification. - private ContentView mView; - - private View.OnSystemUiVisibilityChangeListener mSystemUiVisibilityChangeListener; - - // Set to true once toast is shown. - private boolean mDidShowToast; - - // The toast. - private Toast mToast; - - FullscreenToast(TabImpl tab) { - mTab = tab; - // TODO(https://crbug.com/1130096): This should really be handled lower down in the stack. - if (tab.getBrowser().getActiveTab() != tab) return; - addSystemUiChangedObserver(); - } - - @VisibleForTesting - public boolean didShowFullscreenToast() { - return mDidShowToast; - } - - public void destroy() { - // This may be called more than once. - if (mTab == null) return; - - if (mSystemUiVisibilityChangeListener != null) { - // mSystemUiVisibilityChangeListener is only installed if mView is non-null. - assert mView != null; - mView.removeOnSystemUiVisibilityChangeListener(mSystemUiVisibilityChangeListener); - mSystemUiVisibilityChangeListener = null; - } - mTab = null; - mView = null; - if (mToast != null) { - mToast.cancel(); - mToast = null; - } - } - - private void addSystemUiChangedObserver() { - if (mTab.getBrowser().getBrowserFragment().getViewAndroidDelegateContainerView() == null) { - return; - } - mView = mTab.getBrowser().getBrowserFragment().getViewAndroidDelegateContainerView(); - mSystemUiVisibilityChangeListener = new View.OnSystemUiVisibilityChangeListener() { - @Override - public void onSystemUiVisibilityChange(int visibility) { - // The listener should have been removed if destroy() was called. - assert mTab != null; - if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { - // No longer in fullscreen. Destroy. - destroy(); - } else if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 - && !mDidShowToast) { - // Only show the toast when navigation is hidden and toast wasn't already shown. - showToast(); - mDidShowToast = true; - } - } - }; - mView.addOnSystemUiVisibilityChangeListener(mSystemUiVisibilityChangeListener); - // See class description for details on why a timeout is used. - mView.postDelayed(() -> { - if (!mDidShowToast) destroy(); - }, 1000); - } - - private void showToast() { - assert mToast == null; - mDidShowToast = true; - int resId = R.string.immersive_fullscreen_api_notification; - mToast = Toast.makeText( - mTab.getBrowser().getBrowserFragment().getWindowAndroid().getContext().get(), resId, - Toast.LENGTH_LONG); - mToast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0); - mToast.show(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/GmsBridge.java b/weblayer/browser/java/org/chromium/weblayer_private/GmsBridge.java deleted file mode 100644 index ddf1926f..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/GmsBridge.java +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Service; -import android.content.Context; -import android.os.Handler; -import android.os.HandlerThread; - -import androidx.annotation.Nullable; - -import org.chromium.base.Callback; -import org.chromium.base.ThreadUtils; -import org.chromium.components.metrics.AndroidMetricsLogConsumer; -import org.chromium.components.metrics.AndroidMetricsLogUploader; - -/** - * This class manages functionality related to Google Mobile Services (i.e. GMS). - * Platform specific implementations are provided in GmsBridgeImpl.java. - */ -public abstract class GmsBridge { - private static GmsBridge sInstance; - private static final Object sInstanceLock = new Object(); - - private static HandlerThread sHandlerThread; - private static Handler sHandler; - private static final Object sHandlerLock = new Object(); - - protected GmsBridge() { - AndroidMetricsLogUploader.setConsumer(new AndroidMetricsLogConsumer() { - @Override - public int log(byte[] data) { - logMetrics(data); - // Just pass 200 (HTTP OK) and pretend everything is peachy. - return 200; - } - }); - } - - public static GmsBridge getInstance() { - synchronized (sInstanceLock) { - if (sInstance == null) { - // Load an instance of GmsBridgeImpl. Because this can change depending on - // the GN configuration, this may not be the GmsBridgeImpl defined upstream. - sInstance = new GmsBridgeImpl(); - } - return sInstance; - } - } - - // Provide a mocked GmsBridge for testing. - public static void injectInstance(GmsBridge testBridge) { - synchronized (sInstanceLock) { - sInstance = testBridge; - } - } - - // Return a handler appropriate for executing blocking Platform Service tasks. - public static Handler getHandler() { - synchronized (sHandlerLock) { - if (sHandler == null) { - sHandlerThread = new HandlerThread("GmsBridgeHandlerThread"); - sHandlerThread.start(); - sHandler = new Handler(sHandlerThread.getLooper()); - } - } - return sHandler; - } - - // Returns true if the WebLayer can use Google Mobile Services (GMS). - public boolean canUseGms() { - return false; - } - - public void setSafeBrowsingHandler() { - // We don't have this specialized service here. - } - - public void initializeBuiltInPaymentApps() { - // We don't have this specialized service here. - } - - /** Creates an instance of GooglePayDataCallbacksService. */ - @Nullable - public Service createGooglePayDataCallbacksService() { - // We don't have this specialized service here. - return null; - } - - // Overriding implementations may call "callback" asynchronously. For simplicity (and not - // because of any technical limitation) we require that "queryMetricsSetting" and "callback" - // both get called on WebLayer's UI thread. - public void queryMetricsSetting(Callback<Boolean> callback) { - ThreadUtils.assertOnUiThread(); - callback.onResult(false); - } - - public void logMetrics(byte[] data) {} - - /** - * Performs checks to make sure the client app context can load WebLayer. Throws an - * AndroidRuntimeException on failure. - * - * TODO(crbug.com/1192294): Consider moving this somewhere else since it doesn't use anything - * from GMS. - */ - public void checkClientAppContext(Context context) {} -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/GmsBridgeImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/GmsBridgeImpl.java deleted file mode 100644 index f0d4413..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/GmsBridgeImpl.java +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -/** - * Instantiable version of {@link GmsBridge}, don't add anything to this class! - * Downstream targets may provide a different implementation. - */ -public class GmsBridgeImpl extends GmsBridge {}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherProxy.java deleted file mode 100644 index ad90d371..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherProxy.java +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.IGoogleAccountAccessTokenFetcherClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * Owns the C++ GoogleAccountAccessTokenFetcherProxy class, which is responsible for forwarding all - * access token fetches made from C++ to this class, which in turn forwards to the - * GoogleAccountAccessTokenFetcherClient. - */ -@JNINamespace("weblayer") -public final class GoogleAccountAccessTokenFetcherProxy { - private long mNativeGoogleAccountAccessTokenFetcherProxy; - private IGoogleAccountAccessTokenFetcherClient mClient; - - GoogleAccountAccessTokenFetcherProxy(ProfileImpl profile) { - mNativeGoogleAccountAccessTokenFetcherProxy = - GoogleAccountAccessTokenFetcherProxyJni.get() - .createGoogleAccountAccessTokenFetcherProxy( - this, profile.getNativeProfile()); - } - - public void setClient(IGoogleAccountAccessTokenFetcherClient client) { - mClient = client; - } - - public void destroy() { - GoogleAccountAccessTokenFetcherProxyJni.get().deleteGoogleAccountAccessTokenFetcherProxy( - mNativeGoogleAccountAccessTokenFetcherProxy); - mNativeGoogleAccountAccessTokenFetcherProxy = 0; - } - - /* - * Proxies fetchAccessToken() calls to the client. Returns the empty string if the client is not - * set. - */ - public void fetchAccessToken(Set<String> scopes, ValueCallback<String> onTokenFetchedCallback) - throws RemoteException { - if (mClient == null) { - onTokenFetchedCallback.onReceiveValue(""); - return; - } - - mClient.fetchAccessToken( - ObjectWrapper.wrap(scopes), ObjectWrapper.wrap(onTokenFetchedCallback)); - } - - /* - * Proxies onAccessTokenIdentifiedAsInvalid() calls to the client if it is set. - */ - public void onAccessTokenIdentifiedAsInvalid(Set<String> scopes, String token) - throws RemoteException { - if (WebLayerFactoryImpl.getClientMajorVersion() < 93) return; - - if (mClient == null) return; - - mClient.onAccessTokenIdentifiedAsInvalid( - ObjectWrapper.wrap(scopes), ObjectWrapper.wrap(token)); - } - - /* - * Proxies access token requests from C++ to the public fetchAccessToken() interface. - */ - @CalledByNative - private void fetchAccessToken(String[] scopes, long callbackId) throws RemoteException { - ValueCallback<String> onTokenFetchedCallback = (String token) -> { - GoogleAccountAccessTokenFetcherProxyJni.get().runOnTokenFetchedCallback( - callbackId, token); - }; - - fetchAccessToken(new HashSet<String>(Arrays.asList(scopes)), onTokenFetchedCallback); - } - - /* - * Proxies invalid access token notifications from C++ to the public interface. - */ - @CalledByNative - private void onAccessTokenIdentifiedAsInvalid(String[] scopes, String token) - throws RemoteException { - onAccessTokenIdentifiedAsInvalid(new HashSet<String>(Arrays.asList(scopes)), token); - } - - @NativeMethods - interface Natives { - long createGoogleAccountAccessTokenFetcherProxy( - GoogleAccountAccessTokenFetcherProxy proxy, long profile); - void deleteGoogleAccountAccessTokenFetcherProxy(long proxy); - void runOnTokenFetchedCallback(long callbackId, String token); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/GoogleAccountsCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/GoogleAccountsCallbackProxy.java deleted file mode 100644 index 4aa3186..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/GoogleAccountsCallbackProxy.java +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.signin.GAIAServiceType; -import org.chromium.weblayer_private.interfaces.GoogleAccountServiceType; -import org.chromium.weblayer_private.interfaces.IGoogleAccountsCallbackClient; - -/** - * Owns the C++ GoogleAccountsCallbackProxy which is responsible for forwarding all calls to this - * class. - */ -@JNINamespace("weblayer") -public final class GoogleAccountsCallbackProxy { - private long mNativeGoogleAccountsCallbackProxy; - private IGoogleAccountsCallbackClient mClient; - - GoogleAccountsCallbackProxy(long tab, IGoogleAccountsCallbackClient client) { - assert client != null; - mClient = client; - mNativeGoogleAccountsCallbackProxy = - GoogleAccountsCallbackProxyJni.get().createGoogleAccountsCallbackProxy(this, tab); - } - - public void setClient(IGoogleAccountsCallbackClient client) { - assert client != null; - mClient = client; - } - - public void destroy() { - GoogleAccountsCallbackProxyJni.get().deleteGoogleAccountsCallbackProxy( - mNativeGoogleAccountsCallbackProxy); - mNativeGoogleAccountsCallbackProxy = 0; - } - - @CalledByNative - private void onGoogleAccountsRequest(@GAIAServiceType int serviceType, String email, - String continueUrl, boolean isSameTab) throws RemoteException { - mClient.onGoogleAccountsRequest( - implTypeToJavaType(serviceType), email, continueUrl, isSameTab); - } - - @CalledByNative - private String getGaiaId() throws RemoteException { - return mClient.getGaiaId(); - } - - @GoogleAccountServiceType - private static int implTypeToJavaType(@GAIAServiceType int type) { - switch (type) { - case GAIAServiceType.GAIA_SERVICE_TYPE_SIGNOUT: - return GoogleAccountServiceType.SIGNOUT; - case GAIAServiceType.GAIA_SERVICE_TYPE_ADDSESSION: - return GoogleAccountServiceType.ADD_SESSION; - // SIGNUP and INCOGNITO should not be possible currently, so pass through to DEFAULT. - case GAIAServiceType.GAIA_SERVICE_TYPE_SIGNUP: - case GAIAServiceType.GAIA_SERVICE_TYPE_INCOGNITO: - case GAIAServiceType.GAIA_SERVICE_TYPE_DEFAULT: - return GoogleAccountServiceType.DEFAULT; - } - assert false; - return GoogleAccountServiceType.DEFAULT; - } - - @NativeMethods - interface Natives { - long createGoogleAccountsCallbackProxy(GoogleAccountsCallbackProxy proxy, long tab); - void deleteGoogleAccountsCallbackProxy(long proxy); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/HttpAuthHandlerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/HttpAuthHandlerImpl.java deleted file mode 100644 index e054b42..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/HttpAuthHandlerImpl.java +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.browser_ui.http_auth.LoginPrompt; -import org.chromium.url.GURL; - -/** - * Handles showing http auth prompt. - */ -@JNINamespace("weblayer") -public final class HttpAuthHandlerImpl implements LoginPrompt.Observer { - private long mNativeHttpAuthHandlerImpl; - private LoginPrompt mLoginPrompt; - - @CalledByNative - public static HttpAuthHandlerImpl create(long nativeAuthHandler, TabImpl tab, GURL url) { - return new HttpAuthHandlerImpl(nativeAuthHandler, tab.getBrowser().getContext(), url); - } - - @CalledByNative - void handlerDestroyed() { - mNativeHttpAuthHandlerImpl = 0; - } - - @CalledByNative - private void closeDialog() { - if (mLoginPrompt != null) mLoginPrompt.dismiss(); - } - - private HttpAuthHandlerImpl(long nativeHttpAuthHandlerImpl, Context context, GURL url) { - mNativeHttpAuthHandlerImpl = nativeHttpAuthHandlerImpl; - - mLoginPrompt = new LoginPrompt(context, url.getHost(), url, this); - mLoginPrompt.show(); - } - - @Override - public void proceed(String username, String password) { - if (mNativeHttpAuthHandlerImpl != 0) { - HttpAuthHandlerImplJni.get().proceed(mNativeHttpAuthHandlerImpl, username, password); - } - } - - @Override - public void cancel() { - if (mNativeHttpAuthHandlerImpl != 0) { - HttpAuthHandlerImplJni.get().cancel(mNativeHttpAuthHandlerImpl); - } - } - - @NativeMethods - interface Natives { - void proceed(long nativeHttpAuthHandlerImpl, String username, String password); - void cancel(long nativeHttpAuthHandlerImpl); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/InfoBarContainer.java b/weblayer/browser/java/org/chromium/weblayer_private/InfoBarContainer.java deleted file mode 100644 index 751229ac..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/InfoBarContainer.java +++ /dev/null
@@ -1,472 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.ObserverList; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.chrome.browser.infobar.InfoBarIdentifier; -import org.chromium.components.infobars.InfoBar; -import org.chromium.components.infobars.InfoBarAnimationListener; -import org.chromium.components.infobars.InfoBarUiItem; -import org.chromium.content_public.browser.NavigationHandle; -import org.chromium.content_public.browser.WebContents; -import org.chromium.content_public.browser.WebContentsObserver; -import org.chromium.ui.KeyboardVisibilityDelegate.KeyboardVisibilityListener; -import org.chromium.ui.accessibility.AccessibilityState; - -import java.util.ArrayList; - -/** - * A container for all the infobars of a specific tab. - * Note that infobars creation can be initiated from Java or from native code. - * When initiated from native code, special code is needed to keep the Java and native infobar in - * sync, see NativeInfoBar. - */ -@JNINamespace("weblayer") -public class InfoBarContainer implements KeyboardVisibilityListener, InfoBar.Container { - private static final String TAG = "InfoBarContainer"; - - // Number of instances that have not been destroyed. - private static int sInstanceCount; - - // InfoBarContainer's handling of accessibility is a global toggle, and thus a static observer - // suffices. |sAccessibilityObserver| is added as an observer to {@link AccessibilityState.java} - // whenever the number of non-destroyed InfoBarContainers becomes non-zero. The Listener is - // added to a WeakHashSet so garbage collection is handled without needing to remove here. - private static final AccessibilityState.Listener sAccessibilityStateListener; - static { - sAccessibilityStateListener = (oldAccessibilityState, newAccessibilityState) -> { - setIsAllowedToAutoHide(!newAccessibilityState.isTouchExplorationEnabled - && !newAccessibilityState.isPerformGesturesEnabled); - }; - } - - /** - * An observer that is notified of changes to a {@link InfoBarContainer} object. - */ - public interface InfoBarContainerObserver { - /** - * Called when an {@link InfoBar} is about to be added (before the animation). - * @param container The notifying {@link InfoBarContainer} - * @param infoBar An {@link InfoBar} being added - * @param isFirst Whether the infobar container was empty - */ - void onAddInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isFirst); - - /** - * Called when an {@link InfoBar} is about to be removed (before the animation). - * @param container The notifying {@link InfoBarContainer} - * @param infoBar An {@link InfoBar} being removed - * @param isLast Whether the infobar container is going to be empty - */ - void onRemoveInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isLast); - - /** - * Called when the InfobarContainer is attached to the window. - * @param hasInfobars True if infobar container has infobars to show. - */ - void onInfoBarContainerAttachedToWindow(boolean hasInfobars); - - /** - * A notification that the shown ratio of the infobar container has changed. - * @param container The notifying {@link InfoBarContainer} - * @param shownRatio The shown ratio of the infobar container. - */ - void onInfoBarContainerShownRatioChanged(InfoBarContainer container, float shownRatio); - } - - /** - * Resets the visibility of the InfoBarContainer when the user navigates, following Chrome's - * behavior. In particular in Chrome some features hide the infobar container. This hiding is - * always on a per-URL basis that should be undone on navigation. While no feature in WebLayer - * yet does this, we put this * defensive behavior in place so that any such added features - * don't end up inadvertently hiding the infobar container "forever" in a given tab. - */ - private final WebContentsObserver mWebContentsObserver = new WebContentsObserver() { - @Override - public void didFinishNavigationInPrimaryMainFrame(NavigationHandle navigation) { - if (navigation.hasCommitted()) { - setHidden(false); - } - } - }; - - public void onTabAttachedToViewController() { - initializeContainerView(mTab.getBrowser().getContext()); - updateWebContents(); - mInfoBarContainerView.addToParentView(); - } - - public void onTabDetachedFromViewController() { - mInfoBarContainerView.removeFromParentView(); - destroyContainerView(); - } - - /** The list of all InfoBars in this container, regardless of whether they've been shown yet. */ - private final ArrayList<InfoBar> mInfoBars = new ArrayList<>(); - - private final ObserverList<InfoBarContainerObserver> mObservers = new ObserverList<>(); - private final ObserverList<InfoBarAnimationListener> mAnimationListeners = new ObserverList<>(); - - private final InfoBarContainerView.ContainerViewObserver mContainerViewObserver = - new InfoBarContainerView.ContainerViewObserver() { - @Override - public void notifyAnimationFinished(int animationType) { - for (InfoBarAnimationListener listener : mAnimationListeners) { - listener.notifyAnimationFinished(animationType); - } - } - - @Override - public void notifyAllAnimationsFinished(InfoBarUiItem frontInfoBar) { - for (InfoBarAnimationListener listener : mAnimationListeners) { - listener.notifyAllAnimationsFinished(frontInfoBar); - } - } - - @Override - public void onShownRatioChanged(float shownFraction) { - for (InfoBarContainer.InfoBarContainerObserver observer : mObservers) { - observer.onInfoBarContainerShownRatioChanged( - InfoBarContainer.this, shownFraction); - } - } - }; - - /** The tab that hosts this infobar container. */ - private final TabImpl mTab; - - /** Native InfoBarContainer pointer which will be set by InfoBarContainerJni.get().init(). */ - private long mNativeInfoBarContainer; - - /** True when this container has been emptied and its native counterpart has been destroyed. */ - private boolean mDestroyed; - - /** Whether or not this View should be hidden. */ - private boolean mIsHidden; - - /** - * The view for this {@link InfoBarContainer}. It will be null when the {@link Tab} is detached - * from a {@link ChromeActivity}. - */ - private @Nullable InfoBarContainerView mInfoBarContainerView; - - InfoBarContainer(TabImpl tab) { - if (++sInstanceCount == 1) { - AccessibilityState.addListener(sAccessibilityStateListener); - } - - mTab = tab; - mTab.getWebContents().addObserver(mWebContentsObserver); - - // Chromium's InfoBarContainer may add an InfoBar immediately during this initialization - // call, so make sure everything in the InfoBarContainer is completely ready beforehand. - mNativeInfoBarContainer = InfoBarContainerJni.get().init(InfoBarContainer.this); - } - - /** - * Adds an {@link InfoBarContainerObserver}. - * @param observer The {@link InfoBarContainerObserver} to add. - */ - public void addObserver(InfoBarContainerObserver observer) { - mObservers.addObserver(observer); - } - - /** - * Removes a {@link InfoBarContainerObserver}. - * @param observer The {@link InfoBarContainerObserver} to remove. - */ - public void removeObserver(InfoBarContainerObserver observer) { - mObservers.removeObserver(observer); - } - - /** - * Sets the parent {@link ViewGroup} that contains the {@link InfoBarContainer}. - */ - public void setParentView(ViewGroup parent) { - assert mTab.getBrowser().getActiveTab() == mTab; - if (mInfoBarContainerView != null) mInfoBarContainerView.setParentView(parent); - } - - @VisibleForTesting - public void addAnimationListener(InfoBarAnimationListener listener) { - mAnimationListeners.addObserver(listener); - } - - /** - * Removes the passed in {@link InfoBarAnimationListener} from the {@link InfoBarContainer}. - */ - public void removeAnimationListener(InfoBarAnimationListener listener) { - mAnimationListeners.removeObserver(listener); - } - - /** - * Adds an InfoBar to the view hierarchy. - * @param infoBar InfoBar to add to the View hierarchy. - */ - @CalledByNative - private void addInfoBar(InfoBar infoBar) { - assert !mDestroyed; - if (infoBar == null) { - return; - } - if (mInfoBars.contains(infoBar)) { - assert false : "Trying to add an info bar that has already been added."; - return; - } - - infoBar.setContext(mInfoBarContainerView.getContext()); - infoBar.setContainer(this); - - // We notify observers immediately (before the animation starts). - for (InfoBarContainerObserver observer : mObservers) { - observer.onAddInfoBar(this, infoBar, mInfoBars.isEmpty()); - } - - assert mInfoBarContainerView != null : "The container view is null when adding an InfoBar"; - - // We add the infobar immediately to mInfoBars but we wait for the animation to end to - // notify it's been added, as tests rely on this notification but expects the infobar view - // to be available when they get the notification. - mInfoBars.add(infoBar); - - mInfoBarContainerView.addInfoBar(infoBar); - } - - public View getViewForTesting() { - return mInfoBarContainerView; - } - - /** - * Adds an InfoBar to the view hierarchy. - * @param infoBar InfoBar to add to the View hierarchy. - */ - public void addInfoBarForTesting(InfoBar infoBar) { - addInfoBar(infoBar); - } - - @Override - public void notifyInfoBarViewChanged() { - assert !mDestroyed; - if (mInfoBarContainerView != null) mInfoBarContainerView.notifyInfoBarViewChanged(); - } - - /** - * Sets the visibility for the {@link InfoBarContainerView}. - * @param visibility One of {@link View#GONE}, {@link View#INVISIBLE}, or {@link View#VISIBLE}. - */ - public void setVisibility(int visibility) { - if (mInfoBarContainerView != null) mInfoBarContainerView.setVisibility(visibility); - } - - /** - * @return The visibility of the {@link InfoBarContainerView}. - */ - public int getVisibility() { - return mInfoBarContainerView != null ? mInfoBarContainerView.getVisibility() : View.GONE; - } - - @Override - public void removeInfoBar(InfoBar infoBar) { - assert !mDestroyed; - - if (!mInfoBars.remove(infoBar)) { - assert false : "Trying to remove an InfoBar that is not in this container."; - return; - } - - // Notify observers immediately, before any animations begin. - for (InfoBarContainerObserver observer : mObservers) { - observer.onRemoveInfoBar(this, infoBar, mInfoBars.isEmpty()); - } - - assert mInfoBarContainerView - != null : "The container view is null when removing an InfoBar."; - mInfoBarContainerView.removeInfoBar(infoBar); - } - - @Override - public boolean isDestroyed() { - return mDestroyed; - } - - public void destroy() { - mTab.getWebContents().removeObserver(mWebContentsObserver); - - if (mInfoBarContainerView != null) destroyContainerView(); - if (mNativeInfoBarContainer != 0) { - InfoBarContainerJni.get().destroy(mNativeInfoBarContainer, InfoBarContainer.this); - mNativeInfoBarContainer = 0; - } - mDestroyed = true; - } - - /** - * @return all of the InfoBars held in this container. - */ - public ArrayList<InfoBar> getInfoBarsForTesting() { - return mInfoBars; - } - - /** - * @return True if the container has any InfoBars. - */ - @CalledByNative - public boolean hasInfoBars() { - return !mInfoBars.isEmpty(); - } - - /** - * @return InfoBarIdentifier of the InfoBar which is currently at the top of the infobar stack, - * or InfoBarIdentifier.INVALID if there are no infobars. - */ - @CalledByNative - private @InfoBarIdentifier int getTopInfoBarIdentifier() { - if (!hasInfoBars()) return InfoBarIdentifier.INVALID; - return mInfoBars.get(0).getInfoBarIdentifier(); - } - - /** - * Hides or stops hiding this View. - * - * @param isHidden Whether this View is should be hidden. - */ - public void setHidden(boolean isHidden) { - mIsHidden = isHidden; - if (mInfoBarContainerView == null) return; - mInfoBarContainerView.setHidden(isHidden); - } - - /** - * Sets whether the InfoBarContainer is allowed to auto-hide when the user scrolls the page. - * Expected to be called when Touch Exploration is enabled. - * @param isAllowed Whether auto-hiding is allowed. - */ - private static void setIsAllowedToAutoHide(boolean isAllowed) { - InfoBarContainerView.setIsAllowedToAutoHide(isAllowed); - } - - // KeyboardVisibilityListener implementation. - @Override - public void keyboardVisibilityChanged(boolean isKeyboardShowing) { - assert mInfoBarContainerView != null; - boolean isShowing = (mInfoBarContainerView.getVisibility() == View.VISIBLE); - if (isKeyboardShowing) { - if (isShowing) { - mInfoBarContainerView.setVisibility(View.INVISIBLE); - } - } else { - if (!isShowing && !mIsHidden) { - mInfoBarContainerView.setVisibility(View.VISIBLE); - } - } - } - - private void updateWebContents() { - // When the tab is detached, we don't update the InfoBarContainer web content so that it - // stays null until the tab is attached to some ChromeActivity. - if (mInfoBarContainerView == null) return; - WebContents webContents = mTab.getWebContents(); - - if (webContents != null && webContents != mInfoBarContainerView.getWebContents()) { - mInfoBarContainerView.setWebContents(webContents); - if (mNativeInfoBarContainer != 0) { - InfoBarContainerJni.get().setWebContents( - mNativeInfoBarContainer, InfoBarContainer.this, webContents); - } - } - } - - private void initializeContainerView(Context chromeActivity) { - assert chromeActivity - != null - : "ChromeActivity should not be null when initializing InfoBarContainerView"; - mInfoBarContainerView = new InfoBarContainerView(chromeActivity, mContainerViewObserver, - mTab, /*isTablet=*/!mTab.getBrowser().isWindowOnSmallDevice()); - - mInfoBarContainerView.addOnAttachStateChangeListener( - new View.OnAttachStateChangeListener() { - @Override - public void onViewAttachedToWindow(View view) { - for (InfoBarContainer.InfoBarContainerObserver observer : mObservers) { - observer.onInfoBarContainerAttachedToWindow(!mInfoBars.isEmpty()); - } - } - - @Override - public void onViewDetachedFromWindow(View view) {} - }); - - mInfoBarContainerView.setHidden(mIsHidden); - BrowserViewController viewController = - mTab.getBrowser().getBrowserFragment().getPossiblyNullViewController(); - if (viewController != null) { - setParentView(viewController.getInfoBarContainerParentView()); - } - - mTab.getBrowser() - .getBrowserFragment() - .getWindowAndroid() - .getKeyboardDelegate() - .addKeyboardVisibilityListener(this); - } - - private void destroyContainerView() { - if (mInfoBarContainerView != null) { - mInfoBarContainerView.setWebContents(null); - if (mNativeInfoBarContainer != 0) { - InfoBarContainerJni.get().setWebContents( - mNativeInfoBarContainer, InfoBarContainer.this, null); - } - mInfoBarContainerView.destroy(); - mInfoBarContainerView = null; - } - - mTab.getBrowser() - .getBrowserFragment() - .getWindowAndroid() - .getKeyboardDelegate() - .removeKeyboardVisibilityListener(this); - } - - @Override - public boolean isFrontInfoBar(InfoBar infoBar) { - if (mInfoBars.isEmpty()) return false; - return mInfoBars.get(0) == infoBar; - } - - /** - * Returns true if any animations are pending or in progress. - */ - @VisibleForTesting - public boolean isAnimating() { - assert mInfoBarContainerView != null; - return mInfoBarContainerView.isAnimating(); - } - - /** - * @return The {@link InfoBarContainerView} this class holds. - */ - public InfoBarContainerView getContainerViewForTesting() { - return mInfoBarContainerView; - } - - @NativeMethods - interface Natives { - long init(InfoBarContainer caller); - void setWebContents(long nativeInfoBarContainerAndroid, InfoBarContainer caller, - WebContents webContents); - void destroy(long nativeInfoBarContainerAndroid, InfoBarContainer caller); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/InfoBarContainerView.java b/weblayer/browser/java/org/chromium/weblayer_private/InfoBarContainerView.java deleted file mode 100644 index c2c3a37..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/InfoBarContainerView.java +++ /dev/null
@@ -1,264 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.content.Context; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.RelativeLayout; - -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.MathUtils; -import org.chromium.components.browser_ui.banners.SwipableOverlayView; -import org.chromium.components.infobars.InfoBar; -import org.chromium.components.infobars.InfoBarAnimationListener; -import org.chromium.components.infobars.InfoBarContainerLayout; -import org.chromium.components.infobars.InfoBarUiItem; -import org.chromium.ui.display.DisplayAndroid; -import org.chromium.ui.display.DisplayUtil; - -/** - * The {@link View} for the {@link InfoBarContainer}. - */ -public class InfoBarContainerView extends SwipableOverlayView { - /** - * Observes container view changes. - */ - public interface ContainerViewObserver extends InfoBarAnimationListener { - /** - * Called when the height of shown content changed. - * @param shownFraction The ratio of height of shown content to the height of the container - * view. - */ - void onShownRatioChanged(float shownFraction); - } - - /** Top margin, including the toolbar and tabstrip height and 48dp of web contents. */ - private static final int TOP_MARGIN_PHONE_DP = 104; - private static final int TOP_MARGIN_TABLET_DP = 144; - - /** Length of the animation to fade the InfoBarContainer back into View. */ - private static final long REATTACH_FADE_IN_MS = 250; - - /** Whether or not the InfoBarContainer is allowed to hide when the user scrolls. */ - private static boolean sIsAllowedToAutoHide = true; - - private final ContainerViewObserver mContainerViewObserver; - private final InfoBarContainerLayout mLayout; - - /** Parent view that contains the InfoBarContainerLayout. */ - private ViewGroup mParentView; - - private TabImpl mTab; - - /** Animation used to snap the container to the nearest state if scroll direction changes. */ - private Animator mScrollDirectionChangeAnimation; - - /** Whether or not the current scroll is downward. */ - private boolean mIsScrollingDownward; - - /** Tracks the previous event's scroll offset to determine if a scroll is up or down. */ - private int mLastScrollOffsetY; - - /** - * @param context The {@link Context} that this view is attached to. - * @param containerViewObserver The {@link ContainerViewObserver} that gets notified on - * container view changes. - * @param isTablet Whether this view is displayed on tablet or not. - */ - InfoBarContainerView(@NonNull Context context, - @NonNull ContainerViewObserver containerViewObserver, TabImpl tab, boolean isTablet) { - super(context, null); - mTab = tab; - mContainerViewObserver = containerViewObserver; - - // TODO(newt): move this workaround into the infobar views if/when they're scrollable. - // Workaround for http://crbug.com/407149. See explanation in onMeasure() below. - setVerticalScrollBarEnabled(false); - - updateLayoutParams(context, isTablet); - - Runnable makeContainerVisibleRunnable = () -> runUpEventAnimation(true); - mLayout = new InfoBarContainerLayout( - context, makeContainerVisibleRunnable, new InfoBarAnimationListener() { - @Override - public void notifyAnimationFinished(int animationType) { - mContainerViewObserver.notifyAnimationFinished(animationType); - } - - @Override - public void notifyAllAnimationsFinished(InfoBarUiItem frontInfoBar) { - mContainerViewObserver.notifyAllAnimationsFinished(frontInfoBar); - } - }); - - addView(mLayout, - new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, - Gravity.CENTER_HORIZONTAL)); - } - - void destroy() { - removeFromParentView(); - mTab = null; - } - - // SwipableOverlayView implementation. - @Override - @VisibleForTesting - public boolean isAllowedToAutoHide() { - return sIsAllowedToAutoHide; - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (getVisibility() != View.GONE) { - setVisibility(VISIBLE); - setAlpha(0f); - animate().alpha(1f).setDuration(REATTACH_FADE_IN_MS); - } - } - - @Override - protected void runUpEventAnimation(boolean visible) { - if (mScrollDirectionChangeAnimation != null) mScrollDirectionChangeAnimation.cancel(); - super.runUpEventAnimation(visible); - } - - @Override - protected boolean isIndependentlyAnimating() { - return mScrollDirectionChangeAnimation != null; - } - - // View implementation. - @Override - public void setTranslationY(float translationY) { - int contentHeightDelta = 0; // No bottom bar. - - // Push the infobar container up by any delta caused by the bottom toolbar while ensuring - // that it does not ascend beyond the top of the bottom toolbar nor descend beyond its own - // height. - float newTranslationY = MathUtils.clamp( - translationY - contentHeightDelta, -contentHeightDelta, getHeight()); - - super.setTranslationY(newTranslationY); - - float shownFraction = 0; - if (getHeight() > 0) { - shownFraction = contentHeightDelta > 0 ? 1f : 1f - (translationY / getHeight()); - } - mContainerViewObserver.onShownRatioChanged(shownFraction); - } - - /** - * Sets whether the InfoBarContainer is allowed to auto-hide when the user scrolls the page. - * Expected to be called when Touch Exploration is enabled. - * @param isAllowed Whether auto-hiding is allowed. - */ - public static void setIsAllowedToAutoHide(boolean isAllowed) { - sIsAllowedToAutoHide = isAllowed; - } - - /** - * Notifies that an infobar's View ({@link InfoBar#getView}) has changed. If the infobar is - * visible, a view swapping animation will be run. - */ - void notifyInfoBarViewChanged() { - mLayout.notifyInfoBarViewChanged(); - } - - /** - * Sets the parent {@link ViewGroup} that contains the {@link InfoBarContainer}. - */ - void setParentView(ViewGroup parent) { - mParentView = parent; - // Don't attach the container to the new parent if it is not previously attached. - if (removeFromParentView()) addToParentView(); - } - - /** - * Adds this class to the parent view {@link #mParentView}. - */ - void addToParentView() { - // If mTab is null, destroy() was called. This should not be added after destroyed. - assert mTab != null; - BrowserViewController viewController = - mTab.getBrowser().getBrowserFragment().getPossiblyNullViewController(); - if (viewController != null) { - super.addToParentViewAtIndex( - mParentView, viewController.getDesiredInfoBarContainerViewIndex()); - } - } - - /** - * Adds an {@link InfoBar} to the layout. - * @param infoBar The {@link InfoBar} to be added. - */ - void addInfoBar(InfoBar infoBar) { - infoBar.createView(); - mLayout.addInfoBar(infoBar); - } - - /** - * Removes an {@link InfoBar} from the layout. - * @param infoBar The {@link InfoBar} to be removed. - */ - void removeInfoBar(InfoBar infoBar) { - mLayout.removeInfoBar(infoBar); - } - - /** - * Hides or stops hiding this View. - * @param isHidden Whether this View is should be hidden. - */ - void setHidden(boolean isHidden) { - setVisibility(isHidden ? View.GONE : View.VISIBLE); - } - - /** - * Run an animation when the scrolling direction of a gesture has changed (this does not mean - * the gesture has ended). - * @param visible Whether or not the view should be visible. - */ - private void runDirectionChangeAnimation(boolean visible) { - mScrollDirectionChangeAnimation = createVerticalSnapAnimation(visible); - mScrollDirectionChangeAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mScrollDirectionChangeAnimation = null; - } - }); - mScrollDirectionChangeAnimation.start(); - } - - @Override - // Ensure that this view's custom layout params are passed when adding it to its parent. - public ViewGroup.MarginLayoutParams createLayoutParams() { - return (ViewGroup.MarginLayoutParams) getLayoutParams(); - } - - private void updateLayoutParams(Context context, boolean isTablet) { - RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); - int topMarginDp = isTablet ? TOP_MARGIN_TABLET_DP : TOP_MARGIN_PHONE_DP; - lp.topMargin = DisplayUtil.dpToPx(DisplayAndroid.getNonMultiDisplay(context), topMarginDp); - setLayoutParams(lp); - } - - /** - * Returns true if any animations are pending or in progress. - */ - @VisibleForTesting - public boolean isAnimating() { - return mLayout.isAnimating(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/InstalledAppProviderFactory.java b/weblayer/browser/java/org/chromium/weblayer_private/InstalledAppProviderFactory.java deleted file mode 100644 index 477398c..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/InstalledAppProviderFactory.java +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.components.installedapp.InstalledAppProviderImpl; -import org.chromium.content_public.browser.RenderFrameHost; -import org.chromium.content_public.browser.WebContentsStatics; -import org.chromium.installedapp.mojom.InstalledAppProvider; -import org.chromium.services.service_manager.InterfaceFactory; - -/** Factory to create instances of the InstalledAppProvider Mojo service. */ -public class InstalledAppProviderFactory implements InterfaceFactory<InstalledAppProvider> { - private final RenderFrameHost mRenderFrameHost; - - public InstalledAppProviderFactory(RenderFrameHost renderFrameHost) { - mRenderFrameHost = renderFrameHost; - } - - @Override - public InstalledAppProvider createImpl() { - TabImpl tab = - TabImpl.fromWebContents(WebContentsStatics.fromRenderFrameHost(mRenderFrameHost)); - if (tab == null) return null; - return new InstalledAppProviderImpl( - tab.getProfile(), mRenderFrameHost, (unusedA, unusedB, unusedC) -> false); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/IntentUtils.java b/weblayer/browser/java/org/chromium/weblayer_private/IntentUtils.java deleted file mode 100644 index f6b3557..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/IntentUtils.java +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Intent; -import android.os.RemoteException; -import android.util.AndroidRuntimeException; - -/** A utility class for creating and handling common intents. */ -public class IntentUtils { - private static final String sExtraTabId = "TAB_ID"; - private static final String sActivateTabAction = - "org.chromium.weblayer.intent_utils.ACTIVATE_TAB"; - - /** - * Handles an intent generated by this class. - * @return true if the intent was handled, or false if the intent wasn't generated by this - * class. - */ - public static boolean handleIntent(Intent intent) { - if (!intent.getAction().equals(sActivateTabAction)) return false; - - int tabId = intent.getIntExtra(sExtraTabId, -1); - TabImpl tab = TabImpl.getTabById(tabId); - if (tab == null) return true; - - try { - tab.getClient().bringTabToFront(); - } catch (RemoteException e) { - throw new AndroidRuntimeException(e); - } - return true; - } - - /** - * Creates an intent to bring a tab to the foreground. - * This intent should also bring the app to the foreground. - * @param tabId the identifier for the tab. - */ - public static Intent createBringTabToFrontIntent(int tabId) { - Intent intent = WebLayerImpl.createIntent(); - intent.putExtra(sExtraTabId, tabId); - intent.setAction(sActivateTabAction); - return intent; - } -};
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java deleted file mode 100644 index 0bf36f8..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java +++ /dev/null
@@ -1,177 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Activity; -import android.os.SystemClock; - -import org.chromium.base.ContextUtils; -import org.chromium.components.external_intents.ExternalNavigationHandler; -import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingAsyncActionType; -import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult; -import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType; -import org.chromium.components.external_intents.InterceptNavigationDelegateClient; -import org.chromium.components.external_intents.InterceptNavigationDelegateImpl; -import org.chromium.components.external_intents.RedirectHandler; -import org.chromium.content_public.browser.LoadUrlParams; -import org.chromium.content_public.browser.NavigationHandle; -import org.chromium.content_public.browser.WebContents; -import org.chromium.content_public.browser.WebContentsObserver; - -/** - * Class that provides embedder-level information to InterceptNavigationDelegateImpl based off a - * Tab. - */ -public class InterceptNavigationDelegateClientImpl implements InterceptNavigationDelegateClient { - private TabImpl mTab; - private WebContentsObserver mWebContentsObserver; - private RedirectHandler mRedirectHandler; - private InterceptNavigationDelegateImpl mInterceptNavigationDelegate; - private long mLastNavigationWithUserGestureTime = RedirectHandler.INVALID_TIME; - private boolean mDestroyed; - - InterceptNavigationDelegateClientImpl(TabImpl tab) { - mTab = tab; - mRedirectHandler = RedirectHandler.create(); - mWebContentsObserver = new WebContentsObserver() { - @Override - public void didFinishNavigationInPrimaryMainFrame(NavigationHandle navigationHandle) { - mInterceptNavigationDelegate.onNavigationFinishedInPrimaryMainFrame( - navigationHandle); - } - }; - } - - public void initializeWithDelegate(InterceptNavigationDelegateImpl delegate) { - mInterceptNavigationDelegate = delegate; - getWebContents().addObserver(mWebContentsObserver); - } - - public void onActivityAttachmentChanged(boolean attached) { - if (attached) { - mInterceptNavigationDelegate.setExternalNavigationHandler( - createExternalNavigationHandler()); - } - } - - public void destroy() { - mDestroyed = true; - getWebContents().removeObserver(mWebContentsObserver); - mInterceptNavigationDelegate.associateWithWebContents(null); - } - - @Override - public WebContents getWebContents() { - return mTab.getWebContents(); - } - - @Override - public ExternalNavigationHandler createExternalNavigationHandler() { - return new ExternalNavigationHandler(new ExternalNavigationDelegateImpl(mTab)); - } - - @Override - public long getLastUserInteractionTime() { - // NOTE: Chrome listens for user interaction with its Activity. However, this depends on - // being able to subclass the Activity, which is not possible in WebLayer. As a proxy, - // WebLayer uses the time of the last navigation with a user gesture to serve as the last - // time of user interaction. Note that the user interacting with the webpage causes the - // user gesture bit to be set on any navigation in that page for the next several seconds - // (cf. comments on //third_party/blink/public/common/frame/user_activation_state.h). This - // fact further increases the fidelity of this already-reasonable heuristic as a proxy. To - // date we have not seen any concrete evidence of user-visible differences resulting from - // the use of the different heuristic. - return mLastNavigationWithUserGestureTime; - } - - @Override - public RedirectHandler getOrCreateRedirectHandler() { - return mRedirectHandler; - } - - @Override - public boolean isIncognito() { - return mTab.getProfile().isIncognito(); - } - - @Override - public boolean areIntentLaunchesAllowedInHiddenTabsForNavigation( - NavigationHandle navigationHandle) { - NavigationImpl navigation = mTab.getNavigationControllerImpl().getNavigationImplFromId( - navigationHandle.getNavigationId()); - if (navigation == null) return false; - - return navigation.areIntentLaunchesAllowedInBackground(); - } - - @Override - public Activity getActivity() { - return ContextUtils.activityFromContext(mTab.getBrowser().getContext()); - } - - @Override - public boolean wasTabLaunchedFromExternalApp() { - return false; - } - - @Override - public boolean wasTabLaunchedFromLongPressInBackground() { - return false; - } - - @Override - public void closeTab() { - // When InterceptNavigationDelegate determines that a tab needs to be closed, it posts a - // task invoking this method. It is possible that in the interim the tab was closed for - // another reason. In that case there is nothing more to do here. - if (mDestroyed) return; - - closeTab(mTab); - } - - @Override - public void onNavigationStarted(NavigationHandle navigationHandle) { - if (navigationHandle.hasUserGesture()) { - mLastNavigationWithUserGestureTime = SystemClock.elapsedRealtime(); - } - } - - @Override - public void onDecisionReachedForNavigation( - NavigationHandle navigationHandle, OverrideUrlLoadingResult overrideUrlLoadingResult) { - NavigationImpl navigation = mTab.getNavigationControllerImpl().getNavigationImplFromId( - navigationHandle.getNavigationId()); - - // As the navigation is still ongoing at this point there should be a NavigationImpl - // instance for it. - assert navigation != null; - - switch (overrideUrlLoadingResult.getResultType()) { - case OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT: - navigation.setIntentLaunched(); - break; - case OverrideUrlLoadingResultType.OVERRIDE_WITH_ASYNC_ACTION: - if (overrideUrlLoadingResult.getAsyncActionType() - == OverrideUrlLoadingAsyncActionType.UI_GATING_INTENT_LAUNCH) { - navigation.setIsUserDecidingIntentLaunch(); - } - break; - case OverrideUrlLoadingResultType.OVERRIDE_WITH_NAVIGATE_TAB: - case OverrideUrlLoadingResultType.NO_OVERRIDE: - default: - break; - } - } - - static void closeTab(TabImpl tab) { - tab.getBrowser().destroyTab(tab); - } - - @Override - public void loadUrlIfPossible(LoadUrlParams loadUrlParams) { - if (mDestroyed) return; - mTab.loadUrl(loadUrlParams); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java b/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java deleted file mode 100644 index aeadbc8..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -import org.chromium.base.ContextUtils; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; - -/** - * Triggered when Android's locale changes. - */ -@JNINamespace("weblayer::i18n") -public class LocaleChangedBroadcastReceiver extends BroadcastReceiver { - private final Context mContext; - - public LocaleChangedBroadcastReceiver(Context context) { - mContext = context; - ContextUtils.registerProtectedBroadcastReceiver( - mContext, this, new IntentFilter(Intent.ACTION_LOCALE_CHANGED)); - } - - public void destroy() { - mContext.unregisterReceiver(this); - } - - @Override - public void onReceive(Context context, Intent intent) { - if (!Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) return; - LocaleChangedBroadcastReceiverJni.get().localeChanged(); - WebLayerNotificationChannels.onLocaleChanged(); - } - - @NativeMethods - interface Natives { - void localeChanged(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java b/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java deleted file mode 100644 index 25f3c7e..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.blink.mojom.Authenticator; -import org.chromium.components.webauthn.AuthenticatorFactory; -import org.chromium.content_public.browser.InterfaceRegistrar; -import org.chromium.content_public.browser.RenderFrameHost; -import org.chromium.content_public.browser.WebContents; -import org.chromium.installedapp.mojom.InstalledAppProvider; -import org.chromium.payments.mojom.PaymentRequest; -import org.chromium.services.service_manager.InterfaceRegistry; -import org.chromium.weblayer_private.payments.WebLayerPaymentRequestFactory; -import org.chromium.webshare.mojom.ShareService; - -/** - * Registers Java implementations of mojo interfaces. - */ -class MojoInterfaceRegistrar { - @CalledByNative - private static void registerMojoInterfaces() { - InterfaceRegistrar.Registry.addWebContentsRegistrar(new WebContentsInterfaceRegistrar()); - InterfaceRegistrar.Registry.addRenderFrameHostRegistrar( - new RenderFrameHostInterfaceRegistrar()); - } - - private static class WebContentsInterfaceRegistrar implements InterfaceRegistrar<WebContents> { - @Override - public void registerInterfaces(InterfaceRegistry registry, final WebContents webContents) { - registry.addInterface(ShareService.MANAGER, new WebShareServiceFactory(webContents)); - } - } - - private static class RenderFrameHostInterfaceRegistrar - implements InterfaceRegistrar<RenderFrameHost> { - @Override - public void registerInterfaces( - InterfaceRegistry registry, final RenderFrameHost renderFrameHost) { - registry.addInterface(Authenticator.MANAGER, new AuthenticatorFactory(renderFrameHost)); - registry.addInterface( - InstalledAppProvider.MANAGER, new InstalledAppProviderFactory(renderFrameHost)); - registry.addInterface( - PaymentRequest.MANAGER, new WebLayerPaymentRequestFactory(renderFrameHost)); - } - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java deleted file mode 100644 index f48210ef..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java +++ /dev/null
@@ -1,387 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; -import android.webkit.WebResourceResponse; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.embedder_support.util.WebResourceResponseInfo; -import org.chromium.weblayer_private.TabImpl.HeaderVerificationStatus; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IClientPage; -import org.chromium.weblayer_private.interfaces.INavigateParams; -import org.chromium.weblayer_private.interfaces.INavigationController; -import org.chromium.weblayer_private.interfaces.INavigationControllerClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.NavigateParams; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.util.HashMap; -import java.util.Map; - -/** - * Acts as the bridge between java and the C++ implementation of of NavigationController. - */ -@JNINamespace("weblayer") -public final class NavigationControllerImpl extends INavigationController.Stub { - private final TabImpl mTab; - private long mNativeNavigationController; - private INavigationControllerClient mNavigationControllerClient; - - private Map<Long, PageImpl> mPages = new HashMap<>(); - - public NavigationControllerImpl(TabImpl tab, INavigationControllerClient client) { - mTab = tab; - mNavigationControllerClient = client; - mNativeNavigationController = - NavigationControllerImplJni.get().getNavigationController(tab.getNativeTab()); - NavigationControllerImplJni.get().setNavigationControllerImpl( - mNativeNavigationController, NavigationControllerImpl.this); - } - - @Override - public void navigate(String uri, NavigateParams params) { - StrictModeWorkaround.apply(); - mTab.setHeaderVerification(HeaderVerificationStatus.PENDING); - if (WebLayerFactoryImpl.getClientMajorVersion() < 83) { - assert params == null; - } - NavigationControllerImplJni.get().navigate(mNativeNavigationController, uri, - params == null ? false : params.mShouldReplaceCurrentEntry, false, false, false, - false, null); - } - - @Override - public void navigate2(String uri, boolean shouldReplaceCurrentEntry, - boolean disableIntentProcessing, boolean disableNetworkErrorAutoReload, - boolean enableAutoPlay) { - StrictModeWorkaround.apply(); - NavigationControllerImplJni.get().navigate(mNativeNavigationController, uri, - shouldReplaceCurrentEntry, disableIntentProcessing, - /*allowIntentLaunchesInBackground=*/false, disableNetworkErrorAutoReload, - enableAutoPlay, null); - } - - @Override - public INavigateParams createNavigateParams() { - StrictModeWorkaround.apply(); - return new NavigateParamsImpl(); - } - - @Override - public void navigate3(String uri, INavigateParams iParams) { - StrictModeWorkaround.apply(); - NavigateParamsImpl params = (NavigateParamsImpl) iParams; - WebResourceResponseInfo responseInfo = null; - if (params.getResponse() != null) { - WebResourceResponse response = - ObjectWrapper.unwrap(params.getResponse(), WebResourceResponse.class); - responseInfo = new WebResourceResponseInfo(response.getMimeType(), - response.getEncoding(), response.getData(), response.getStatusCode(), - response.getReasonPhrase(), response.getResponseHeaders()); - } - - NavigationControllerImplJni.get().navigate(mNativeNavigationController, uri, - params.shouldReplaceCurrentEntry(), params.isIntentProcessingDisabled(), - params.areIntentLaunchesAllowedInBackground(), - params.isNetworkErrorAutoReloadDisabled(), params.isAutoPlayEnabled(), - responseInfo); - } - - @Override - public void goBack() { - StrictModeWorkaround.apply(); - NavigationControllerImplJni.get().goBack(mNativeNavigationController); - } - - @Override - public void goForward() { - StrictModeWorkaround.apply(); - NavigationControllerImplJni.get().goForward(mNativeNavigationController); - } - - @Override - public boolean canGoBack() { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().canGoBack(mNativeNavigationController); - } - - @Override - public boolean canGoForward() { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().canGoForward(mNativeNavigationController); - } - - @Override - public void goToIndex(int index) { - StrictModeWorkaround.apply(); - NavigationControllerImplJni.get().goToIndex(mNativeNavigationController, index); - } - - @Override - public void reload() { - StrictModeWorkaround.apply(); - NavigationControllerImplJni.get().reload(mNativeNavigationController); - } - - @Override - public void stop() { - StrictModeWorkaround.apply(); - NavigationControllerImplJni.get().stop(mNativeNavigationController); - } - - @Override - public int getNavigationListSize() { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().getNavigationListSize(mNativeNavigationController); - } - - @Override - public int getNavigationListCurrentIndex() { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().getNavigationListCurrentIndex( - mNativeNavigationController); - } - - @Override - public String getNavigationEntryDisplayUri(int index) { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().getNavigationEntryDisplayUri( - mNativeNavigationController, index); - } - - @Override - public String getNavigationEntryTitle(int index) { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().getNavigationEntryTitle( - mNativeNavigationController, index); - } - - @Override - public boolean isNavigationEntrySkippable(int index) { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().isNavigationEntrySkippable( - mNativeNavigationController, index); - } - - public NavigationImpl getNavigationImplFromId(long id) { - StrictModeWorkaround.apply(); - return NavigationControllerImplJni.get().getNavigationImplFromId( - mNativeNavigationController, id); - } - - public PageImpl getPage(long nativePageImpl) { - // Ensure that each C++ object has only one Java counterpart so that the embedder sees the - // same object for multiple navigations that have the same Page. - PageImpl page = mPages.get(nativePageImpl); - if (page == null) { - IClientPage clientPage = null; - if (WebLayerFactoryImpl.getClientMajorVersion() >= 90) { - try { - clientPage = mNavigationControllerClient.createClientPage(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - page = new PageImpl(clientPage, nativePageImpl, this); - mPages.put(nativePageImpl, page); - } - return page; - } - - public void onPageDestroyed(PageImpl page) { - mPages.remove(page.getNativePageImpl()); - if (WebLayerFactoryImpl.getClientMajorVersion() >= 90) { - try { - mNavigationControllerClient.onPageDestroyed(page.getClientPage()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - } - - @CalledByNative - private NavigationImpl createNavigation(long nativeNavigationImpl) { - return new NavigationImpl(mNavigationControllerClient, nativeNavigationImpl, this); - } - - @CalledByNative - private void navigationStarted(NavigationImpl navigation) throws RemoteException { - mTab.setHeaderVerification(HeaderVerificationStatus.PENDING); - mNavigationControllerClient.navigationStarted(navigation.getClientNavigation()); - } - - @CalledByNative - private void navigationRedirected(NavigationImpl navigation) throws RemoteException { - mNavigationControllerClient.navigationRedirected(navigation.getClientNavigation()); - } - - @CalledByNative - private void readyToCommitNavigation(NavigationImpl navigation) throws RemoteException { - mNavigationControllerClient.readyToCommitNavigation(navigation.getClientNavigation()); - } - - @CalledByNative - private void getOrCreatePageForNavigation(NavigationImpl navigation) throws RemoteException { - navigation.getPage(); - } - - @CalledByNative - private void navigationCompleted(NavigationImpl navigation) throws RemoteException { - if (navigation.getIsConsentingContent()) { - mTab.setHeaderVerification(HeaderVerificationStatus.VALIDATED); - } else { - mTab.setHeaderVerification(HeaderVerificationStatus.NOT_VALIDATED); - } - mNavigationControllerClient.navigationCompleted(navigation.getClientNavigation()); - } - - @CalledByNative - private void navigationFailed(NavigationImpl navigation) throws RemoteException { - mNavigationControllerClient.navigationFailed(navigation.getClientNavigation()); - } - - @CalledByNative - private void loadStateChanged(boolean isLoading, boolean shouldShowLoadingUi) - throws RemoteException { - mNavigationControllerClient.loadStateChanged(isLoading, shouldShowLoadingUi); - } - - @CalledByNative - private void loadProgressChanged(double progress) throws RemoteException { - mNavigationControllerClient.loadProgressChanged(progress); - } - - @CalledByNative - private void onFirstContentfulPaint() throws RemoteException { - mNavigationControllerClient.onFirstContentfulPaint(); - } - - @CalledByNative - private void onFirstContentfulPaint2( - long navigationStartMs, long firstContentfulPaintDurationMs) throws RemoteException { - if (WebLayerFactoryImpl.getClientMajorVersion() < 88) return; - - mNavigationControllerClient.onFirstContentfulPaint2( - navigationStartMs, firstContentfulPaintDurationMs); - } - - @CalledByNative - private void onLargestContentfulPaint( - long navigationStartMs, long largestContentfulPaintDurationMs) throws RemoteException { - if (WebLayerFactoryImpl.getClientMajorVersion() < 88) return; - - mNavigationControllerClient.onLargestContentfulPaint( - navigationStartMs, largestContentfulPaintDurationMs); - } - - @CalledByNative - private void onOldPageNoLongerRendered(String uri) throws RemoteException { - mNavigationControllerClient.onOldPageNoLongerRendered(uri); - } - - @CalledByNative - private void onPageLanguageDetermined(PageImpl page, String language) throws RemoteException { - if (WebLayerFactoryImpl.getClientMajorVersion() < 93) return; - - mNavigationControllerClient.onPageLanguageDetermined(page.getClientPage(), language); - } - - @CalledByNative - private boolean isUrlAllowed(String url) { - return mTab.getBrowser().isUrlAllowed(url); - } - - private static final class NavigateParamsImpl extends INavigateParams.Stub { - private boolean mReplaceCurrentEntry; - private boolean mIntentProcessingDisabled; - private boolean mIntentLaunchesAllowedInBackground; - private boolean mNetworkErrorAutoReloadDisabled; - private boolean mAutoPlayEnabled; - private IObjectWrapper mResponse; - - @Override - public void replaceCurrentEntry() { - mReplaceCurrentEntry = true; - } - - @Override - public void disableIntentProcessing() { - mIntentProcessingDisabled = true; - } - - @Override - public void allowIntentLaunchesInBackground() { - mIntentLaunchesAllowedInBackground = true; - } - - @Override - public void disableNetworkErrorAutoReload() { - mNetworkErrorAutoReloadDisabled = true; - } - - @Override - public void enableAutoPlay() { - mAutoPlayEnabled = true; - } - - @Override - public void setResponse(IObjectWrapper response) { - mResponse = response; - } - - public boolean shouldReplaceCurrentEntry() { - return mReplaceCurrentEntry; - } - - public boolean isIntentProcessingDisabled() { - return mIntentProcessingDisabled; - } - - public boolean areIntentLaunchesAllowedInBackground() { - return mIntentLaunchesAllowedInBackground; - } - - public boolean isNetworkErrorAutoReloadDisabled() { - return mNetworkErrorAutoReloadDisabled; - } - - public boolean isAutoPlayEnabled() { - return mAutoPlayEnabled; - } - - IObjectWrapper getResponse() { - return mResponse; - } - } - - @NativeMethods - interface Natives { - void setNavigationControllerImpl( - long nativeNavigationControllerImpl, NavigationControllerImpl caller); - long getNavigationController(long tab); - void navigate(long nativeNavigationControllerImpl, String uri, - boolean shouldReplaceCurrentEntry, boolean disableIntentProcessing, - boolean allowIntentLaunchesInBackground, boolean disableNetworkErrorAutoReload, - boolean enableAutoPlay, WebResourceResponseInfo response); - void goBack(long nativeNavigationControllerImpl); - void goForward(long nativeNavigationControllerImpl); - boolean canGoBack(long nativeNavigationControllerImpl); - boolean canGoForward(long nativeNavigationControllerImpl); - void goToIndex(long nativeNavigationControllerImpl, int index); - void reload(long nativeNavigationControllerImpl); - void stop(long nativeNavigationControllerImpl); - int getNavigationListSize(long nativeNavigationControllerImpl); - int getNavigationListCurrentIndex(long nativeNavigationControllerImpl); - String getNavigationEntryDisplayUri(long nativeNavigationControllerImpl, int index); - String getNavigationEntryTitle(long nativeNavigationControllerImpl, int index); - boolean isNavigationEntrySkippable(long nativeNavigationControllerImpl, int index); - NavigationImpl getNavigationImplFromId(long nativeNavigationControllerImpl, long id); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java deleted file mode 100644 index 87b9bdc..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java +++ /dev/null
@@ -1,350 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IClientNavigation; -import org.chromium.weblayer_private.interfaces.IClientPage; -import org.chromium.weblayer_private.interfaces.INavigation; -import org.chromium.weblayer_private.interfaces.INavigationControllerClient; -import org.chromium.weblayer_private.interfaces.LoadError; -import org.chromium.weblayer_private.interfaces.NavigationState; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.util.Arrays; -import java.util.List; - -/** - * Implementation of INavigation. - */ -@JNINamespace("weblayer") -public final class NavigationImpl extends INavigation.Stub { - private final IClientNavigation mClientNavigation; - private final NavigationControllerImpl mNavigationController; - // WARNING: NavigationImpl may outlive the native side, in which case this member is set to 0. - private long mNativeNavigationImpl; - - // Set to true if/when it is determined that an external intent was launched for this - // navigation. - private boolean mIntentLaunched; - - // Set to true if/when it is determined that this navigation result in UI being presented to the - // user via which the user will determine whether an intent should be launched. - private boolean mIsUserDecidingIntentLaunch; - - private PageImpl mPage; - - public NavigationImpl(INavigationControllerClient client, long nativeNavigationImpl, - NavigationControllerImpl navigationController) { - mNativeNavigationImpl = nativeNavigationImpl; - mNavigationController = navigationController; - try { - mClientNavigation = client.createClientNavigation(this); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public IClientNavigation getClientNavigation() { - return mClientNavigation; - } - - @NavigationState - private static int implTypeToJavaType(@ImplNavigationState int type) { - switch (type) { - case ImplNavigationState.WAITING_RESPONSE: - return NavigationState.WAITING_RESPONSE; - case ImplNavigationState.RECEIVING_BYTES: - return NavigationState.RECEIVING_BYTES; - case ImplNavigationState.COMPLETE: - return NavigationState.COMPLETE; - case ImplNavigationState.FAILED: - return NavigationState.FAILED; - } - assert false; - return NavigationState.FAILED; - } - - @Override - @NavigationState - public int getState() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return implTypeToJavaType(NavigationImplJni.get().getState(mNativeNavigationImpl)); - } - - @Override - public String getUri() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().getUri(mNativeNavigationImpl); - } - - @Override - public List<String> getRedirectChain() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return Arrays.asList(NavigationImplJni.get().getRedirectChain(mNativeNavigationImpl)); - } - - @Override - public int getHttpStatusCode() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().getHttpStatusCode(mNativeNavigationImpl); - } - - @Override - public List<String> getResponseHeaders() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return Arrays.asList(NavigationImplJni.get().getResponseHeaders(mNativeNavigationImpl)); - } - - public boolean getIsConsentingContent() { - return NavigationImplJni.get().getIsConsentingContent(mNativeNavigationImpl); - } - - @Override - public boolean isSameDocument() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isSameDocument(mNativeNavigationImpl); - } - - @Override - public boolean isErrorPage() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isErrorPage(mNativeNavigationImpl); - } - - @Override - public int getLoadError() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return implLoadErrorToLoadError( - NavigationImplJni.get().getLoadError(mNativeNavigationImpl)); - } - - @Override - public void setRequestHeader(String name, String value) { - if (!NavigationImplJni.get().isValidRequestHeaderName(name)) { - throw new IllegalArgumentException("Invalid header"); - } - if (!NavigationImplJni.get().isValidRequestHeaderValue(value)) { - throw new IllegalArgumentException("Invalid value"); - } - if (!NavigationImplJni.get().setRequestHeader(mNativeNavigationImpl, name, value)) { - throw new IllegalStateException(); - } - } - - @Override - public void setUserAgentString(String value) { - if (!NavigationImplJni.get().isValidRequestHeaderValue(value)) { - throw new IllegalArgumentException("Invalid value"); - } - if (!NavigationImplJni.get().setUserAgentString(mNativeNavigationImpl, value)) { - throw new IllegalStateException(); - } - } - - @Override - public boolean isDownload() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isDownload(mNativeNavigationImpl); - } - - @Override - public boolean isKnownProtocol() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isKnownProtocol(mNativeNavigationImpl); - } - - @Override - public boolean wasIntentLaunched() { - return mIntentLaunched; - } - - @Override - public boolean isUserDecidingIntentLaunch() { - return mIsUserDecidingIntentLaunch; - } - - @Override - public boolean wasStopCalled() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().wasStopCalled(mNativeNavigationImpl); - } - - @Override - public boolean isPageInitiated() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isPageInitiated(mNativeNavigationImpl); - } - - @Override - public boolean isReload() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isReload(mNativeNavigationImpl); - } - - @Override - public boolean isServedFromBackForwardCache() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isServedFromBackForwardCache(mNativeNavigationImpl); - } - - @Override - public void disableNetworkErrorAutoReload() { - if (!NavigationImplJni.get().disableNetworkErrorAutoReload(mNativeNavigationImpl)) { - throw new IllegalStateException(); - } - } - - @Override - public void disableIntentProcessing() { - if (!NavigationImplJni.get().disableIntentProcessing(mNativeNavigationImpl)) { - throw new IllegalStateException(); - } - } - - @Override - public boolean isFormSubmission() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().isFormSubmission(mNativeNavigationImpl); - } - - @Override - public String getReferrer() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().getReferrer(mNativeNavigationImpl); - } - - @Override - public IClientPage getPage() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - if (mPage == null) { - long nativePageImpl = NavigationImplJni.get().getPage(mNativeNavigationImpl); - if (nativePageImpl == -1) { - throw new IllegalStateException( - "Invoking Navigation#getPage() outside of valid calling context"); - } - - // There should always be a Page associated with the navigation within the valid - // calling contexts for Navigation#getPage(). - assert (nativePageImpl != 0); - - mPage = mNavigationController.getPage(nativePageImpl); - } - return mPage.getClientPage(); - } - - @Override - public int getNavigationEntryOffset() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().getNavigationEntryOffset(mNativeNavigationImpl); - } - - @Override - public boolean wasFetchedFromCache() { - StrictModeWorkaround.apply(); - throwIfNativeDestroyed(); - return NavigationImplJni.get().wasFetchedFromCache(mNativeNavigationImpl); - } - - public void setIntentLaunched() { - mIntentLaunched = true; - } - - public void setIsUserDecidingIntentLaunch() { - mIsUserDecidingIntentLaunch = true; - } - - public boolean areIntentLaunchesAllowedInBackground() { - return NavigationImplJni.get().areIntentLaunchesAllowedInBackground(mNativeNavigationImpl); - } - - private void throwIfNativeDestroyed() { - if (mNativeNavigationImpl == 0) { - throw new IllegalStateException("Using Navigation after native destroyed"); - } - } - - @LoadError - private static int implLoadErrorToLoadError(@ImplLoadError int loadError) { - switch (loadError) { - case ImplLoadError.NO_ERROR: - return LoadError.NO_ERROR; - case ImplLoadError.HTTP_CLIENT_ERROR: - return LoadError.HTTP_CLIENT_ERROR; - case ImplLoadError.HTTP_SERVER_ERROR: - return LoadError.HTTP_SERVER_ERROR; - case ImplLoadError.SSL_ERROR: - return LoadError.SSL_ERROR; - case ImplLoadError.CONNECTIVITY_ERROR: - return LoadError.CONNECTIVITY_ERROR; - case ImplLoadError.OTHER_ERROR: - return LoadError.OTHER_ERROR; - case ImplLoadError.SAFE_BROWSING_ERROR: - return LoadError.SAFE_BROWSING_ERROR; - default: - throw new IllegalArgumentException("Unexpected load error " + loadError); - } - } - - @CalledByNative - private void onNativeDestroyed() { - mNativeNavigationImpl = 0; - // TODO: this should likely notify delegate in some way. - } - - @NativeMethods - interface Natives { - int getState(long nativeNavigationImpl); - String getUri(long nativeNavigationImpl); - String[] getRedirectChain(long nativeNavigationImpl); - int getHttpStatusCode(long nativeNavigationImpl); - String[] getResponseHeaders(long nativeNavigationImpl); - boolean getIsConsentingContent(long nativeNavigationImpl); - boolean isSameDocument(long nativeNavigationImpl); - boolean isErrorPage(long nativeNavigationImpl); - boolean isDownload(long nativeNavigationImpl); - boolean isKnownProtocol(long nativeNavigationImpl); - boolean wasStopCalled(long nativeNavigationImpl); - int getLoadError(long nativeNavigationImpl); - boolean setRequestHeader(long nativeNavigationImpl, String name, String value); - boolean isValidRequestHeaderName(String name); - boolean isValidRequestHeaderValue(String value); - boolean setUserAgentString(long nativeNavigationImpl, String value); - boolean isPageInitiated(long nativeNavigationImpl); - boolean isReload(long nativeNavigationImpl); - boolean isServedFromBackForwardCache(long nativeNavigationImpl); - boolean disableNetworkErrorAutoReload(long nativeNavigationImpl); - boolean disableIntentProcessing(long nativeNavigationImpl); - boolean areIntentLaunchesAllowedInBackground(long nativeNavigationImpl); - boolean isFormSubmission(long nativeNavigationImpl); - String getReferrer(long nativeNavigationImpl); - long getPage(long nativeNavigationImpl); - int getNavigationEntryOffset(long nativeNavigationImpl); - boolean wasFetchedFromCache(long nativeNavigationImpl); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/NewTabCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/NewTabCallbackProxy.java deleted file mode 100644 index 194f71933..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/NewTabCallbackProxy.java +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.NewTabType; - -/** - * Owns the c++ NewTabCallback class, which is responsible for forwarding all - * NewTabCallback calls to this class, which in turn forwards to ITabClient. - */ -@JNINamespace("weblayer") -public final class NewTabCallbackProxy { - private long mNativeNewTabCallbackProxy; - private final TabImpl mTab; - - public NewTabCallbackProxy(TabImpl tab) { - mTab = tab; - mNativeNewTabCallbackProxy = - NewTabCallbackProxyJni.get().createNewTabCallbackProxy(this, tab.getNativeTab()); - } - - public void destroy() { - NewTabCallbackProxyJni.get().deleteNewTabCallbackProxy(mNativeNewTabCallbackProxy); - mNativeNewTabCallbackProxy = 0; - } - - @NewTabType - private static int implTypeToJavaType(@ImplNewTabType int type) { - switch (type) { - case ImplNewTabType.FOREGROUND: - return NewTabType.FOREGROUND_TAB; - case ImplNewTabType.BACKGROUND: - return NewTabType.BACKGROUND_TAB; - case ImplNewTabType.NEW_POPUP: - return NewTabType.NEW_POPUP; - case ImplNewTabType.NEW_WINDOW: - return NewTabType.NEW_WINDOW; - } - assert false; - return NewTabType.FOREGROUND_TAB; - } - - @CalledByNative - public void onNewTab(TabImpl tab, @ImplNewTabType int mode) throws RemoteException { - // This class should only be created while the tab is attached to a fragment. - assert mTab.getBrowser() != null; - assert mTab.getBrowser().equals(tab.getBrowser()); - mTab.getClient().onNewTab(tab.getId(), implTypeToJavaType(mode)); - } - - @NativeMethods - interface Natives { - long createNewTabCallbackProxy(NewTabCallbackProxy proxy, long tab); - void deleteNewTabCallbackProxy(long proxy); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/PageImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/PageImpl.java deleted file mode 100644 index d96598d..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/PageImpl.java +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.IClientPage; - -/** - * Implementation side of Page. - */ -@JNINamespace("weblayer") -public final class PageImpl { - // Will be null for clients libraries that are old and don't support this. - private final IClientPage mClientPage; - // WARNING: PageImpl may outlive the native side, in which case this member is set to 0. - private long mNativePageImpl; - private final NavigationControllerImpl mNavigationController; - - public PageImpl(IClientPage clientPage, long nativePageImpl, - NavigationControllerImpl navigationController) { - mClientPage = clientPage; - mNativePageImpl = nativePageImpl; - mNavigationController = navigationController; - PageImplJni.get().setJavaPage(mNativePageImpl, PageImpl.this); - } - - public IClientPage getClientPage() { - return mClientPage; - } - - long getNativePageImpl() { - return mNativePageImpl; - } - - @CalledByNative - private void onNativeDestroyed() { - mNavigationController.onPageDestroyed(this); - mNativePageImpl = 0; - } - - @NativeMethods - interface Natives { - void setJavaPage(long nativePageImpl, PageImpl caller); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/PrerenderControllerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/PrerenderControllerImpl.java deleted file mode 100644 index b49127e..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/PrerenderControllerImpl.java +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.LifetimeAssert; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.IPrerenderController; - -/** - * Implementation of {@link IPrerenderController}. - */ -@JNINamespace("weblayer") -public class PrerenderControllerImpl extends IPrerenderController.Stub { - private long mNativePrerenderController; - private final LifetimeAssert mLifetimeAssert = LifetimeAssert.create(this); - - void destroy() { - mNativePrerenderController = 0; - - // If mLifetimeAssert is GC'ed before this is called, it will throw an exception - // with a stack trace showing the stack during LifetimeAssert.create(). - LifetimeAssert.setSafeToGc(mLifetimeAssert, true); - } - - public PrerenderControllerImpl(long nativePrerenderController) { - mNativePrerenderController = nativePrerenderController; - } - - @Override - public void prerender(String url) { - PrerenderControllerImplJni.get().prerender(mNativePrerenderController, url); - } - - @NativeMethods() - interface Natives { - void prerender(long nativePrerenderControllerImpl, String url); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java deleted file mode 100644 index 17fbd48..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java +++ /dev/null
@@ -1,471 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Intent; -import android.graphics.Bitmap; -import android.os.RemoteException; -import android.text.TextUtils; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; - -import org.chromium.base.Callback; -import org.chromium.base.CollectionUtil; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.base.task.PostTask; -import org.chromium.base.task.TaskTraits; -import org.chromium.components.browser_ui.accessibility.FontSizePrefs; -import org.chromium.components.content_capture.PlatformContentCaptureController; -import org.chromium.content_public.browser.BrowserContextHandle; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.BrowsingDataType; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.ICookieManager; -import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient; -import org.chromium.weblayer_private.interfaces.IGoogleAccountAccessTokenFetcherClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IOpenUrlCallbackClient; -import org.chromium.weblayer_private.interfaces.IPrerenderController; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.IProfileClient; -import org.chromium.weblayer_private.interfaces.IUserIdentityCallbackClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.SettingType; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Implementation of IProfile. - */ -@JNINamespace("weblayer") -public final class ProfileImpl - extends IProfile.Stub implements BrowserContextHandle, BrowserListObserver { - private final String mName; - private final boolean mIsIncognito; - private long mNativeProfile; - private CookieManagerImpl mCookieManager; - private PrerenderControllerImpl mPrerenderController; - private Runnable mOnDestroyCallback; - private boolean mBeingDeleted; - private boolean mDownloadsInitialized; - private DownloadCallbackProxy mDownloadCallbackProxy; - private GoogleAccountAccessTokenFetcherProxy mAccessTokenFetcherProxy; - private IUserIdentityCallbackClient mUserIdentityCallbackClient; - private IOpenUrlCallbackClient mOpenUrlCallbackClient; - private List<Intent> mDownloadNotificationIntents = new ArrayList<>(); - - private IProfileClient mClient; - - // If non-null, indicates when no browsers reference this Profile the Profile is destroyed. The - // contents are the list of runnables supplied to destroyAndDeleteDataFromDiskSoon(). - private List<Runnable> mDelayedDestroyCallbacks; - - public static void enumerateAllProfileNames(ValueCallback<String[]> callback) { - final Callback<String[]> baseCallback = (String[] names) -> callback.onReceiveValue(names); - ProfileImplJni.get().enumerateAllProfileNames(baseCallback); - } - - ProfileImpl(String name, boolean isIncognito, Runnable onDestroyCallback) { - // Normal profiles have restrictions on the name. - if (!isIncognito && !name.matches("^\\w+$")) { - throw new IllegalArgumentException( - "Non-incognito profiles names can only contain words: " + name); - } - mIsIncognito = isIncognito; - mName = name; - mNativeProfile = ProfileImplJni.get().createProfile(name, ProfileImpl.this, mIsIncognito); - mCookieManager = new CookieManagerImpl( - ProfileImplJni.get().getCookieManager(mNativeProfile), ProfileImpl.this); - mPrerenderController = new PrerenderControllerImpl( - ProfileImplJni.get().getPrerenderController(mNativeProfile)); - mOnDestroyCallback = onDestroyCallback; - mDownloadCallbackProxy = new DownloadCallbackProxy(this); - mAccessTokenFetcherProxy = new GoogleAccountAccessTokenFetcherProxy(this); - } - - private void destroyDependentJavaObjects() { - if (mDownloadCallbackProxy != null) { - mDownloadCallbackProxy.destroy(); - mDownloadCallbackProxy = null; - } - - if (mAccessTokenFetcherProxy != null) { - mAccessTokenFetcherProxy.destroy(); - mAccessTokenFetcherProxy = null; - } - - if (mCookieManager != null) { - mCookieManager.destroy(); - mCookieManager = null; - } - - if (mPrerenderController != null) { - mPrerenderController.destroy(); - mPrerenderController = null; - } - FontSizePrefs.destroyInstance(); - } - - @Override - public void destroy() { - StrictModeWorkaround.apply(); - if (mBeingDeleted) return; - - destroyDependentJavaObjects(); - deleteNativeProfile(); - maybeRunDestroyCallback(); - } - - private void deleteNativeProfile() { - ProfileImplJni.get().deleteProfile(mNativeProfile); - mNativeProfile = 0; - } - - private void maybeRunDestroyCallback() { - if (mOnDestroyCallback == null) return; - mOnDestroyCallback.run(); - mOnDestroyCallback = null; - } - - @Override - public void destroyAndDeleteDataFromDisk(IObjectWrapper completionCallback) { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - assert mNativeProfile != 0; - if (!canDestroyNow()) { - throw new IllegalStateException("Profile still in use: " + mName); - } - - final Runnable callback = ObjectWrapper.unwrap(completionCallback, Runnable.class); - destroyAndDeleteDataFromDiskImpl(callback); - } - - private void destroyAndDeleteDataFromDiskImpl(Runnable callback) { - assert canDestroyNow(); - mBeingDeleted = true; - BrowserList.getInstance().removeObserver(this); - destroyDependentJavaObjects(); - if (mClient != null) { - try { - mClient.onProfileDestroyed(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - ProfileImplJni.get().destroyAndDeleteDataFromDisk(mNativeProfile, () -> { - if (callback != null) callback.run(); - if (mDelayedDestroyCallbacks != null) { - for (Runnable r : mDelayedDestroyCallbacks) r.run(); - mDelayedDestroyCallbacks = null; - } - }); - mNativeProfile = 0; - maybeRunDestroyCallback(); - } - - private boolean canDestroyNow() { - return ProfileImplJni.get().getNumBrowserImpl(mNativeProfile) == 0; - } - - @Override - public void destroyAndDeleteDataFromDiskSoon(IObjectWrapper completionCallback) { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - assert mNativeProfile != 0; - if (canDestroyNow()) { - destroyAndDeleteDataFromDisk(completionCallback); - return; - } - // The profile is still in use. Wait for all browsers to be destroyed before cleaning up. - if (mDelayedDestroyCallbacks == null) { - BrowserList.getInstance().addObserver(this); - mDelayedDestroyCallbacks = new ArrayList<>(); - ProfileImplJni.get().markAsDeleted(mNativeProfile); - } - final Runnable callback = ObjectWrapper.unwrap(completionCallback, Runnable.class); - if (callback != null) mDelayedDestroyCallbacks.add(callback); - } - - @Override - public void setClient(IProfileClient client) { - mClient = client; - } - - @Override - public String getName() { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - return mName; - } - - @Override - public long getNativeBrowserContextPointer() { - if (mNativeProfile == 0) { - return 0; - } - return ProfileImplJni.get().getBrowserContext(mNativeProfile); - } - - @Override - public void setUserIdentityCallbackClient(IUserIdentityCallbackClient client) { - StrictModeWorkaround.apply(); - mUserIdentityCallbackClient = client; - } - - public IUserIdentityCallbackClient getUserIdentityCallbackClient() { - return mUserIdentityCallbackClient; - } - - @Override - public void setGoogleAccountAccessTokenFetcherClient( - IGoogleAccountAccessTokenFetcherClient client) { - StrictModeWorkaround.apply(); - mAccessTokenFetcherProxy.setClient(client); - } - - @Override - public void setTablessOpenUrlCallbackClient(IOpenUrlCallbackClient client) { - StrictModeWorkaround.apply(); - mOpenUrlCallbackClient = client; - } - - @Override - public boolean isIncognito() { - return mIsIncognito; - } - - public boolean areDownloadsInitialized() { - return mDownloadsInitialized; - } - - public void addDownloadNotificationIntent(Intent intent) { - mDownloadNotificationIntents.add(intent); - ProfileImplJni.get().ensureBrowserContextInitialized(mNativeProfile); - } - - @Override - public void onBrowserCreated(BrowserImpl browser) {} - - @Override - public void onBrowserDestroyed(BrowserImpl browser) { - if (!canDestroyNow()) return; - - // onBrowserDestroyed() is called from the destructor of Browser. This is a rather fragile - // time to destroy the profile. Delay. - PostTask.postTask(TaskTraits.UI_DEFAULT, () -> { - if (!mBeingDeleted && canDestroyNow()) { - destroyAndDeleteDataFromDiskImpl(null); - } - }); - } - - @Override - public void clearBrowsingData(@NonNull @BrowsingDataType int[] dataTypes, long fromMillis, - long toMillis, @NonNull IObjectWrapper completionCallback) { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - // `toMillis` should be greater than `fromMillis` - assert fromMillis < toMillis; - // Handle ContentCapture data clearing. - PlatformContentCaptureController controller = - PlatformContentCaptureController.getInstance(); - if (controller != null) { - for (int type : dataTypes) { - if (type == BrowsingDataType.COOKIES_AND_SITE_DATA) { - controller.clearAllContentCaptureData(); - break; - } - } - } - Runnable callback = ObjectWrapper.unwrap(completionCallback, Runnable.class); - ProfileImplJni.get().clearBrowsingData( - mNativeProfile, mapBrowsingDataTypes(dataTypes), fromMillis, toMillis, callback); - } - - @Override - public void setDownloadDirectory(String directory) { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - ProfileImplJni.get().setDownloadDirectory(mNativeProfile, directory); - } - - @Override - public void setDownloadCallbackClient(IDownloadCallbackClient client) { - mDownloadCallbackProxy.setClient(client); - } - - @Override - public ICookieManager getCookieManager() { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - return mCookieManager; - } - - @Override - public IPrerenderController getPrerenderController() { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - return mPrerenderController; - } - - @Override - public void getBrowserPersistenceIds(@NonNull IObjectWrapper callback) { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - ValueCallback<Set<String>> valueCallback = - (ValueCallback<Set<String>>) ObjectWrapper.unwrap(callback, ValueCallback.class); - Callback<String[]> baseCallback = (String[] result) -> { - valueCallback.onReceiveValue(new HashSet<String>(Arrays.asList(result))); - }; - ProfileImplJni.get().getBrowserPersistenceIds(mNativeProfile, baseCallback); - } - - @Override - public void removeBrowserPersistenceStorage(String[] ids, @NonNull IObjectWrapper callback) { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - ValueCallback<Boolean> valueCallback = - (ValueCallback<Boolean>) ObjectWrapper.unwrap(callback, ValueCallback.class); - Callback<Boolean> baseCallback = valueCallback::onReceiveValue; - for (String id : ids) { - if (TextUtils.isEmpty(id)) { - throw new IllegalArgumentException("id must be non-null and non-empty"); - } - } - ProfileImplJni.get().removeBrowserPersistenceStorage(mNativeProfile, ids, baseCallback); - } - - @Override - public void prepareForPossibleCrossOriginNavigation() { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - ProfileImplJni.get().prepareForPossibleCrossOriginNavigation(mNativeProfile); - } - - @Override - public void getCachedFaviconForPageUri(@NonNull String uri, @NonNull IObjectWrapper callback) { - StrictModeWorkaround.apply(); - checkNotDestroyed(); - ValueCallback<Bitmap> valueCallback = - (ValueCallback<Bitmap>) ObjectWrapper.unwrap(callback, ValueCallback.class); - Callback<Bitmap> baseCallback = valueCallback::onReceiveValue; - ProfileImplJni.get().getCachedFaviconForPageUrl(mNativeProfile, uri, baseCallback); - } - - void checkNotDestroyed() { - if (!mBeingDeleted) return; - throw new IllegalArgumentException("Profile being destroyed: " + mName); - } - - private static @ImplBrowsingDataType int[] mapBrowsingDataTypes( - @NonNull @BrowsingDataType int[] dataTypes) { - // Convert data types coming from aidl to the ones accepted by C++ (ImplBrowsingDataType is - // generated from a C++ enum). - List<Integer> convertedTypes = new ArrayList<>(); - for (int aidlType : dataTypes) { - switch (aidlType) { - case BrowsingDataType.COOKIES_AND_SITE_DATA: - convertedTypes.add(ImplBrowsingDataType.COOKIES_AND_SITE_DATA); - break; - case BrowsingDataType.CACHE: - convertedTypes.add(ImplBrowsingDataType.CACHE); - break; - case BrowsingDataType.SITE_SETTINGS: - convertedTypes.add(ImplBrowsingDataType.SITE_SETTINGS); - break; - default: - break; // Skip unrecognized values for forward compatibility. - } - } - return CollectionUtil.integerCollectionToIntArray(convertedTypes); - } - - long getNativeProfile() { - return mNativeProfile; - } - - @CalledByNative - public void downloadsInitialized() { - mDownloadsInitialized = true; - - for (Intent intent : mDownloadNotificationIntents) { - DownloadImpl.handleIntent(intent); - } - mDownloadNotificationIntents.clear(); - } - - @CalledByNative - public long getBrowserForNewTab() throws RemoteException { - if (mOpenUrlCallbackClient == null) return 0; - - IBrowser browser = mOpenUrlCallbackClient.getBrowserForNewTab(); - if (browser == null) return 0; - - return ((BrowserImpl) browser).getNativeBrowser(); - } - - @CalledByNative - public void onTabAdded(TabImpl tab) throws RemoteException { - if (mOpenUrlCallbackClient == null) return; - - mOpenUrlCallbackClient.onTabAdded(tab.getId()); - } - - @Override - public void setBooleanSetting(@SettingType int type, boolean value) { - ProfileImplJni.get().setBooleanSetting(mNativeProfile, type, value); - } - - @Override - public boolean getBooleanSetting(@SettingType int type) { - return ProfileImplJni.get().getBooleanSetting(mNativeProfile, type); - } - - public void fetchAccessTokenForTesting(IObjectWrapper scopesWrapper, - IObjectWrapper onTokenFetchedWrapper) throws RemoteException { - mAccessTokenFetcherProxy.fetchAccessToken(ObjectWrapper.unwrap(scopesWrapper, Set.class), - ObjectWrapper.unwrap(onTokenFetchedWrapper, ValueCallback.class)); - } - - public void fireOnAccessTokenIdentifiedAsInvalidForTesting( - IObjectWrapper scopesWrapper, IObjectWrapper tokenWrapper) throws RemoteException { - mAccessTokenFetcherProxy.onAccessTokenIdentifiedAsInvalid( - ObjectWrapper.unwrap(scopesWrapper, Set.class), - ObjectWrapper.unwrap(tokenWrapper, String.class)); - } - - @NativeMethods - interface Natives { - void enumerateAllProfileNames(Callback<String[]> callback); - long createProfile(String name, ProfileImpl caller, boolean isIncognito); - void deleteProfile(long profile); - long getBrowserContext(long nativeProfileImpl); - int getNumBrowserImpl(long nativeProfileImpl); - void destroyAndDeleteDataFromDisk(long nativeProfileImpl, Runnable completionCallback); - void clearBrowsingData(long nativeProfileImpl, @ImplBrowsingDataType int[] dataTypes, - long fromMillis, long toMillis, Runnable callback); - void setDownloadDirectory(long nativeProfileImpl, String directory); - long getCookieManager(long nativeProfileImpl); - long getPrerenderController(long nativeProfileImpl); - void ensureBrowserContextInitialized(long nativeProfileImpl); - void setBooleanSetting(long nativeProfileImpl, int type, boolean value); - boolean getBooleanSetting(long nativeProfileImpl, int type); - void getBrowserPersistenceIds(long nativeProfileImpl, Callback<String[]> callback); - void removeBrowserPersistenceStorage( - long nativeProfileImpl, String[] ids, Callback<Boolean> callback); - void prepareForPossibleCrossOriginNavigation(long nativeProfileImpl); - void getCachedFaviconForPageUrl( - long nativeProfileImpl, String url, Callback<Bitmap> callback); - void markAsDeleted(long nativeProfileImpl); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ProfileManager.java b/weblayer/browser/java/org/chromium/weblayer_private/ProfileManager.java deleted file mode 100644 index 4ae3984..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/ProfileManager.java +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import java.util.HashMap; -import java.util.Map; - -/** - * Creates and maintains the active Profiles. - */ -public class ProfileManager { - private final Map<String, ProfileImpl> mProfiles = new HashMap<>(); - private final Map<String, ProfileImpl> mIncognitoProfiles = new HashMap<>(); - - /** Returns existing or new Profile associated with the given name. */ - public ProfileImpl getProfile(String name, boolean isIncognito) { - if (name == null) throw new IllegalArgumentException("Name shouldn't be null"); - Map<String, ProfileImpl> nameToProfileMap = getMapForProfileType(isIncognito); - ProfileImpl existingProfile = nameToProfileMap.get(name); - if (existingProfile != null) { - return existingProfile; - } - - ProfileImpl profile = - new ProfileImpl(name, isIncognito, () -> nameToProfileMap.remove(name)); - nameToProfileMap.put(name, profile); - return profile; - } - - private Map<String, ProfileImpl> getMapForProfileType(boolean isIncognito) { - return isIncognito ? mIncognitoProfiles : mProfiles; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/README.md b/weblayer/browser/java/org/chromium/weblayer_private/README.md deleted file mode 100644 index 3a262dfb..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/README.md +++ /dev/null
@@ -1,36 +0,0 @@ -# Which Context should I use? - -The code in this directory references different types of contexts. Please read about what each -represents before deciding which one you should use. - -## Embedder's Activity Context - -The fragment that WebLayer is loaded in holds a reference to the activity that it is currently -attached to. This is what's referred to by [`mEmbedderActivityContext`][link1] in BrowserImpl and -BrowserFragmentImpl. It should be used to reference anything associated with the activity. For -instance, embedder-specific resources, like Color resources which are resolved according to the -theme of the embedding activity. - -[link1]: https://source.chromium.org/chromium/chromium/src/+/6c336f4d55231595c038756f58a9e61d416a9c8f:weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java;bpv=1;bpt=1 - -## WebLayer's Activity Context - -WebLayer has a lot of resources of its own which need to be accessed by the implementation code. We -thus wrap the embedder's activity context so that resource and assert look-ups against the wrapped -context go to the WebView or WebLayer support APK and not the embedder's APK. This wrapped Context -is what's returned by [`BrowserImpl.getContext()`][link2]. Use this when referencing WebLayer specific -resources. This is expected to be the most common use case. - -[link2]: https://source.chromium.org/chromium/chromium/src/+/main:weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java?q=f:browserimpl%20getContext&ss=chromium%2Fchromium%2Fsrc - -## Embedder's Application Context - -Occasionally, we need the embedder's application context, as opposed to its activity context. For -instance, fetching the current locale which applies to the entire application. -Similar to WebLayer's Activity Context, this context is also wrapped in our implementation so we can -reference WebLayer-specific resources. This is what's returned by -[`ContextUtils.getApplicationContext()`][link3]. -It shouldn't be downcast to Application (or any subclass thereof) since it's wrapped in a -ContextWrapper. - -[link3]: https://source.chromium.org/chromium/chromium/src/+/main:base/android/java/src/org/chromium/base/ContextUtils.java?q=f:base%2FContextUtils%20getApplicationContext()&ss=chromium%2Fchromium%2Fsrc
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java deleted file mode 100644 index 515e67cc..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java +++ /dev/null
@@ -1,188 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.IntentSender; -import android.os.Build; -import android.os.Bundle; -import android.view.SurfaceControlViewHost; -import android.view.View; - -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.IRemoteFragmentClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -/** - * Base for the classes controlling a Fragment that exists in another ClassLoader. Extending this - * class is similar to extending Fragment: e.g. one can override lifecycle methods, not forgetting - * to call super, etc. - */ -public abstract class RemoteFragmentImpl extends IRemoteFragment.Stub { - @Nullable - protected IRemoteFragmentClient mClient; - - protected RemoteFragmentImpl() {} - - // TODO(swestphal): remove this. - protected final Activity getActivity() { - return null; - } - - protected final View getView() { - return null; - } - - protected void onCreate() {} - - protected void onAttach(Context context) {} - - protected void onStart() {} - - protected void onDestroy() {} - - protected void onDetach() {} - - protected void onResume() {} - - protected void onDestroyView() {} - - protected void onStop() {} - - protected void onPause() {} - - protected void onActivityResult(int requestCode, int resultCode, Intent data) {} - - protected void requestPermissions(String[] permissions, int requestCode) {} - - protected void onRequestPermissionsResult( - int requestCode, String[] permissions, int[] grantResults) {} - - @RequiresApi(Build.VERSION_CODES.R) - protected void setSurfaceControlViewHost(SurfaceControlViewHost host) {} - - protected View getContentViewRenderView() { - return null; - } - - protected void setMinimumSurfaceSize(int width, int height) {} - - // TODO(crbug/1378606): Either remove below methods together with callers or provide a client - // implementation on weblayer side. - protected boolean startActivityForResult(Intent intent, int requestCode, Bundle options) { - return false; - } - - protected boolean startIntentSenderForResult(IntentSender intent, int requestCode, - Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) { - return false; - } - - protected boolean shouldShowRequestPermissionRationale(String permission) { - return false; - } - - protected void removeFragmentFromFragmentManager() {} - - // IRemoteFragment implementation below. - - @Override - public void setClient(IRemoteFragmentClient client) { - mClient = client; - } - - @Override - public final void handleOnStart() { - StrictModeWorkaround.apply(); - onStart(); - } - - @Override - public final void handleOnCreate() { - StrictModeWorkaround.apply(); - onCreate(); - } - - @Override - public final void handleOnAttach(IObjectWrapper context) { - StrictModeWorkaround.apply(); - onAttach(ObjectWrapper.unwrap(context, Context.class)); - } - - @Override - public final void handleOnResume() { - StrictModeWorkaround.apply(); - onResume(); - } - - @Override - public final void handleOnPause() { - StrictModeWorkaround.apply(); - onPause(); - } - - @Override - public final void handleOnStop() { - StrictModeWorkaround.apply(); - onStop(); - } - - @Override - public final void handleOnDestroyView() { - StrictModeWorkaround.apply(); - onDestroyView(); - } - - @Override - public final void handleOnDetach() { - StrictModeWorkaround.apply(); - onDetach(); - } - - @Override - public final void handleOnDestroy() { - StrictModeWorkaround.apply(); - onDestroy(); - } - - @Override - public final void handleOnActivityResult(int requestCode, int resultCode, IObjectWrapper data) { - StrictModeWorkaround.apply(); - onActivityResult(requestCode, resultCode, ObjectWrapper.unwrap(data, Intent.class)); - } - - @Override - public final void handleOnRequestPermissionsResult( - int requestCode, String[] permissions, int[] grantResults) { - StrictModeWorkaround.apply(); - onRequestPermissionsResult(requestCode, permissions, grantResults); - } - - @RequiresApi(Build.VERSION_CODES.R) - @Override - public final void handleSetSurfaceControlViewHost(IObjectWrapper host) { - StrictModeWorkaround.apply(); - setSurfaceControlViewHost(ObjectWrapper.unwrap(host, SurfaceControlViewHost.class)); - } - - @Override - public final IObjectWrapper handleGetContentViewRenderView() { - StrictModeWorkaround.apply(); - return ObjectWrapper.wrap(getContentViewRenderView()); - } - - @Override - public final void handleSetMinimumSurfaceSize(int width, int height) { - StrictModeWorkaround.apply(); - setMinimumSurfaceSize(width, height); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabCallbackProxy.java b/weblayer/browser/java/org/chromium/weblayer_private/TabCallbackProxy.java deleted file mode 100644 index bcc792e..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabCallbackProxy.java +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.RemoteException; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.interfaces.ITabClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * Owns the C++ TabCallbackProxy class, which is responsible for forwarding all - * BrowserObserver calls to this class, which in turn forwards to the TabClient. - * To avoid unnecessary IPC only one TabCallbackProxy is created per Tab. - */ -@JNINamespace("weblayer") -public final class TabCallbackProxy { - private long mNativeTabCallbackProxy; - private ITabClient mClient; - - TabCallbackProxy(long tab, ITabClient client) { - mClient = client; - mNativeTabCallbackProxy = TabCallbackProxyJni.get().createTabCallbackProxy(this, tab); - } - - public void destroy() { - TabCallbackProxyJni.get().deleteTabCallbackProxy(mNativeTabCallbackProxy); - mNativeTabCallbackProxy = 0; - } - - @CalledByNative - private void visibleUriChanged(String string) throws RemoteException { - mClient.visibleUriChanged(string); - } - - @CalledByNative - private void onRenderProcessGone() throws RemoteException { - mClient.onRenderProcessGone(); - } - - @CalledByNative - private void onTitleUpdated(String title) throws RemoteException { - mClient.onTitleUpdated(ObjectWrapper.wrap(title)); - } - - @NativeMethods - interface Natives { - long createTabCallbackProxy(TabCallbackProxy proxy, long tab); - void deleteTabCallbackProxy(long proxy); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java deleted file mode 100644 index db9a596..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java +++ /dev/null
@@ -1,1262 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import static org.chromium.cc.mojom.RootScrollOffsetUpdateFrequency.ALL_UPDATES; - -import android.Manifest.permission; -import android.app.Activity; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.graphics.RectF; -import android.os.Build; -import android.os.Bundle; -import android.os.RemoteException; -import android.text.TextUtils; -import android.util.AndroidRuntimeException; -import android.util.Pair; -import android.util.SparseArray; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.ViewStructure; -import android.view.autofill.AutofillValue; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.Callback; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.components.autofill.AutofillProvider; -import org.chromium.components.autofill.AutofillSelectionMenuItemProvider; -import org.chromium.components.browser_ui.display_cutout.DisplayCutoutController; -import org.chromium.components.browser_ui.media.MediaSessionHelper; -import org.chromium.components.browser_ui.widget.InsetObserverView; -import org.chromium.components.embedder_support.contextmenu.ContextMenuParams; -import org.chromium.components.embedder_support.util.UrlUtilities; -import org.chromium.components.external_intents.InterceptNavigationDelegateImpl; -import org.chromium.components.find_in_page.FindInPageBridge; -import org.chromium.components.find_in_page.FindMatchRectsDetails; -import org.chromium.components.find_in_page.FindResultBar; -import org.chromium.components.infobars.InfoBar; -import org.chromium.components.url_formatter.UrlFormatter; -import org.chromium.components.webapps.AddToHomescreenCoordinator; -import org.chromium.components.webapps.AppBannerManager; -import org.chromium.content_public.browser.GestureListenerManager; -import org.chromium.content_public.browser.GestureStateListener; -import org.chromium.content_public.browser.LoadUrlParams; -import org.chromium.content_public.browser.MessagePayload; -import org.chromium.content_public.browser.MessagePayloadType; -import org.chromium.content_public.browser.MessagePort; -import org.chromium.content_public.browser.MessagePort.MessageCallback; -import org.chromium.content_public.browser.NavigationHandle; -import org.chromium.content_public.browser.SelectionClient; -import org.chromium.content_public.browser.SelectionPopupController; -import org.chromium.content_public.browser.ViewEventSink; -import org.chromium.content_public.browser.Visibility; -import org.chromium.content_public.browser.WebContents; -import org.chromium.content_public.browser.WebContentsObserver; -import org.chromium.ui.base.ViewAndroidDelegate; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.url.GURL; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.ExceptionType; -import org.chromium.weblayer_private.interfaces.IContextMenuParams; -import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient; -import org.chromium.weblayer_private.interfaces.IExternalIntentInIncognitoCallbackClient; -import org.chromium.weblayer_private.interfaces.IFaviconFetcher; -import org.chromium.weblayer_private.interfaces.IFaviconFetcherClient; -import org.chromium.weblayer_private.interfaces.IFindInPageCallbackClient; -import org.chromium.weblayer_private.interfaces.IFullscreenCallbackClient; -import org.chromium.weblayer_private.interfaces.IGoogleAccountsCallbackClient; -import org.chromium.weblayer_private.interfaces.IMediaCaptureCallbackClient; -import org.chromium.weblayer_private.interfaces.INavigationControllerClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IStringCallback; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.ITabClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.ScrollNotificationType; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; -import org.chromium.weblayer_private.media.MediaSessionManager; -import org.chromium.weblayer_private.media.MediaStreamManager; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Implementation of ITab. - */ -@JNINamespace("weblayer") -public final class TabImpl extends ITab.Stub { - private static int sNextId = 1; - // Map from id to TabImpl. - private static final Map<Integer, TabImpl> sTabMap = new HashMap<Integer, TabImpl>(); - private long mNativeTab; - - private ProfileImpl mProfile; - private WebContents mWebContents; - private WebContentsObserver mWebContentsObserver; - private TabCallbackProxy mTabCallbackProxy; - private NavigationControllerImpl mNavigationController; - private ErrorPageCallbackProxy mErrorPageCallbackProxy; - private FullscreenCallbackProxy mFullscreenCallbackProxy; - private TabViewAndroidDelegate mViewAndroidDelegate; - private GoogleAccountsCallbackProxy mGoogleAccountsCallbackProxy; - private ExternalIntentInIncognitoCallbackProxy mExternalIntentInIncognitoCallbackProxy; - private MessagePort[] mChannel; - // BrowserImpl this TabImpl is in. - @NonNull - private BrowserImpl mBrowser; - /** - * The AutofillProvider that integrates with system-level autofill. This is null until - * updateFromBrowser() is invoked. - */ - private AutofillProvider mAutofillProvider; - private MediaStreamManager mMediaStreamManager; - private NewTabCallbackProxy mNewTabCallbackProxy; - private ITabClient mClient; - private final int mId; - - private IFindInPageCallbackClient mFindInPageCallbackClient; - private FindInPageBridge mFindInPageBridge; - private FindResultBar mFindResultBar; - // See usage note in {@link #onFindResultAvailable}. - private boolean mWaitingForMatchRects; - private InterceptNavigationDelegateClientImpl mInterceptNavigationDelegateClient; - private InterceptNavigationDelegateImpl mInterceptNavigationDelegate; - private InfoBarContainer mInfoBarContainer; - private MediaSessionHelper mMediaSessionHelper; - private DisplayCutoutController mDisplayCutoutController; - - private boolean mPostContainerViewInitDone; - private WebLayerActionModeCallback mActionModeCallback; - - private Set<FaviconCallbackProxy> mFaviconCallbackProxies = new HashSet<>(); - - // Only non-null if scroll offsets have been requested. - private @Nullable GestureStateListener mGestureStateListener; - - private HeaderVerificationStatus mHeaderVerification; - - enum HeaderVerificationStatus { - PENDING, - NOT_VALIDATED, - VALIDATED, - } - - private static class InternalAccessDelegateImpl - implements ViewEventSink.InternalAccessDelegate { - @Override - public boolean super_onKeyUp(int keyCode, KeyEvent event) { - return false; - } - - @Override - public boolean super_dispatchKeyEvent(KeyEvent event) { - return false; - } - - @Override - public boolean super_onGenericMotionEvent(MotionEvent event) { - return false; - } - - @Override - public void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix) {} - } - - private class TabViewAndroidDelegate extends ViewAndroidDelegate { - private boolean mIgnoreRenderer; - - TabViewAndroidDelegate() { - super(null); - } - - /** - * Causes {@link onTopControlsChanged()} and {@link onBottomControlsChanged()} to be - * ignored. - * @param ignoreRenderer whether to ignore renderer-initiated updates to the controls state. - */ - public void setIgnoreRendererUpdates(boolean ignoreRenderer) { - mIgnoreRenderer = ignoreRenderer; - } - - @Override - public void onBackgroundColorChanged(int color) { - try { - mClient.onBackgroundColorChanged(color); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @Override - protected void onVerticalScrollDirectionChanged( - boolean directionUp, float currentScrollRatio) { - super.onVerticalScrollDirectionChanged(directionUp, currentScrollRatio); - try { - mClient.onScrollNotification(directionUp - ? ScrollNotificationType.DIRECTION_CHANGED_UP - : ScrollNotificationType.DIRECTION_CHANGED_DOWN, - currentScrollRatio); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - } - - class NativeStringCallback implements Callback<String> { - private IStringCallback mCallback; - - NativeStringCallback(IStringCallback callback) { - mCallback = callback; - } - - @Override - public void onResult(String result) { - try { - mCallback.onResult(result); - } catch (RemoteException e) { - } - } - } - - public static TabImpl fromWebContents(WebContents webContents) { - if (webContents == null || webContents.isDestroyed()) return null; - return TabImplJni.get().fromWebContents(webContents); - } - - public static TabImpl getTabById(int tabId) { - return sTabMap.get(tabId); - } - - public TabImpl(BrowserImpl browser, ProfileImpl profile, WindowAndroid windowAndroid) { - mBrowser = browser; - mId = ++sNextId; - init(profile, windowAndroid, TabImplJni.get().createTab(profile.getNativeProfile(), this)); - } - - /** - * This constructor is called when the native side triggers creation of a TabImpl - * (as happens with popups and other scenarios). - */ - public TabImpl( - BrowserImpl browser, ProfileImpl profile, WindowAndroid windowAndroid, long nativeTab) { - mId = ++sNextId; - mBrowser = browser; - TabImplJni.get().setJavaImpl(nativeTab, TabImpl.this); - init(profile, windowAndroid, nativeTab); - } - - private void init(ProfileImpl profile, WindowAndroid windowAndroid, long nativeTab) { - mProfile = profile; - mNativeTab = nativeTab; - mWebContents = TabImplJni.get().getWebContents(mNativeTab); - mViewAndroidDelegate = new TabViewAndroidDelegate(); - mWebContents.initialize("", mViewAndroidDelegate, new InternalAccessDelegateImpl(), - windowAndroid, WebContents.createDefaultInternalsHolder()); - - mWebContentsObserver = new WebContentsObserver() { - @Override - public void didStartNavigationInPrimaryMainFrame(NavigationHandle navigationHandle) { - if (!navigationHandle.isSameDocument()) { - hideFindInPageUiAndNotifyClient(); - } - } - - @Override - public void viewportFitChanged(@WebContentsObserver.ViewportFitType int value) { - ensureDisplayCutoutController(); - mDisplayCutoutController.setViewportFit(value); - } - }; - mWebContents.addObserver(mWebContentsObserver); - - mHeaderVerification = HeaderVerificationStatus.PENDING; - - mMediaStreamManager = new MediaStreamManager(this); - - mInterceptNavigationDelegateClient = new InterceptNavigationDelegateClientImpl(this); - mInterceptNavigationDelegate = - new InterceptNavigationDelegateImpl(mInterceptNavigationDelegateClient); - mInterceptNavigationDelegateClient.initializeWithDelegate(mInterceptNavigationDelegate); - sTabMap.put(mId, this); - - mInfoBarContainer = new InfoBarContainer(this); - - mMediaSessionHelper = new MediaSessionHelper( - mWebContents, MediaSessionManager.createMediaSessionHelperDelegate(this)); - - GestureListenerManager.fromWebContents(mWebContents) - .addListener(new GestureStateListener() { - @Override - public void didOverscroll( - float accumulatedOverscrollX, float accumulatedOverscrollY) { - if (WebLayerFactoryImpl.getClientMajorVersion() < 101) return; - try { - mClient.onVerticalOverscroll(accumulatedOverscrollY); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - }, ALL_UPDATES); - } - - private void doInitAfterSettingContainerView() { - if (mPostContainerViewInitDone) return; - - if (mBrowser.getBrowserFragment().getViewAndroidDelegateContainerView() != null) { - mPostContainerViewInitDone = true; - - SelectionPopupController selectionPopupController = - SelectionPopupController.fromWebContents(mWebContents); - mActionModeCallback = new WebLayerActionModeCallback(mWebContents); - mActionModeCallback.setTabClient(mClient); - selectionPopupController.setActionModeCallback(mActionModeCallback); - selectionPopupController.setSelectionClient( - SelectionClient.createSmartSelectionClient(mWebContents)); - } - } - - public ProfileImpl getProfile() { - return mProfile; - } - - public ITabClient getClient() { - return mClient; - } - - public void setHeaderVerification(HeaderVerificationStatus headerVerification) { - mHeaderVerification = headerVerification; - } - - /** - * Sets the BrowserImpl this TabImpl is contained in. - */ - public void attachToBrowser(BrowserImpl browser) { - // NOTE: during tab creation this is called with |browser| set to |mBrowser|. This happens - // because the tab is created with |mBrowser| already set (to avoid having a bunch of null - // checks). - mBrowser = browser; - updateFromBrowser(); - } - - public void updateFromBrowser() { - mViewAndroidDelegate.setContainerView( - mBrowser.getBrowserFragment().getViewAndroidDelegateContainerView()); - doInitAfterSettingContainerView(); - updateViewAttachedStateFromBrowser(); - - boolean attached = mBrowser.getBrowserFragment().isAttached(); - mInterceptNavigationDelegateClient.onActivityAttachmentChanged(attached); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - SelectionPopupController selectionController = - SelectionPopupController.fromWebContentsNoCreate(mWebContents); - if (!attached) { - // The Context and ViewContainer in which Autofill was previously operating have - // gone away, so tear down |mAutofillProvider|. - if (mAutofillProvider != null) { - mAutofillProvider.destroy(); - mAutofillProvider = null; - } - if (selectionController != null) { - selectionController.setNonSelectionAdditionalMenuItemProvider(null); - } - } else { - if (mAutofillProvider == null) { - // Set up |mAutofillProvider| to operate in the new Context. It's safe to assume - // the context won't change unless it is first nulled out, since the fragment - // must be detached before it can be reattached to a new Context. - mAutofillProvider = new AutofillProvider(mBrowser.getContext(), - mBrowser.getBrowserFragment().getViewAndroidDelegateContainerView(), - mWebContents, "WebLayer"); - TabImplJni.get().initializeAutofillIfNecessary(mNativeTab); - } - mAutofillProvider.onContainerViewChanged( - mBrowser.getBrowserFragment().getViewAndroidDelegateContainerView()); - mAutofillProvider.setWebContents(mWebContents); - if (selectionController != null) { - selectionController.setNonSelectionAdditionalMenuItemProvider( - new AutofillSelectionMenuItemProvider( - mBrowser.getContext(), mAutofillProvider)); - } - } - } - } - - public AutofillProvider getAutofillProviderForTesting() { - // The test needs to make sure the |mAutofillProvider| is not null. - return mAutofillProvider; - } - - public void updateViewAttachedStateFromBrowser() { - updateWebContentsVisibility(); - updateDisplayCutoutController(); - } - - public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) { - if (mAutofillProvider == null) return; - mAutofillProvider.onProvideAutoFillVirtualStructure(structure, flags); - } - - public void autofill(final SparseArray<AutofillValue> values) { - if (mAutofillProvider == null) return; - mAutofillProvider.autofill(values); - } - - public BrowserImpl getBrowser() { - return mBrowser; - } - - @Override - public void setNewTabsEnabled(boolean enable) { - StrictModeWorkaround.apply(); - if (enable && mNewTabCallbackProxy == null) { - mNewTabCallbackProxy = new NewTabCallbackProxy(this); - } else if (!enable && mNewTabCallbackProxy != null) { - mNewTabCallbackProxy.destroy(); - mNewTabCallbackProxy = null; - } - } - - @Override - public int getId() { - StrictModeWorkaround.apply(); - return mId; - } - - @Override - public String getUri() { - StrictModeWorkaround.apply(); - return mWebContents.getVisibleUrl().getSpec(); - } - - /** - * Called when this TabImpl is attached to the BrowserViewController. - */ - public void onAttachedToViewController() { - mWebContents.setTopLevelNativeWindow(mBrowser.getBrowserFragment().getWindowAndroid()); - doInitAfterSettingContainerView(); - mInfoBarContainer.onTabAttachedToViewController(); - updateWebContentsVisibility(); - updateDisplayCutoutController(); - } - - /** - * Called when this TabImpl is detached from the BrowserViewController. - */ - public void onDetachedFromViewController() { - mWebContents.setTopLevelNativeWindow(null); - if (mAutofillProvider != null) { - mAutofillProvider.hidePopup(); - } - - if (mFullscreenCallbackProxy != null) mFullscreenCallbackProxy.destroyToast(); - - hideFindInPageUiAndNotifyClient(); - updateWebContentsVisibility(); - updateDisplayCutoutController(); - - // This method is called as part of the final phase of TabImpl destruction, at which - // point mInfoBarContainer has already been destroyed. - if (mInfoBarContainer != null) { - mInfoBarContainer.onTabDetachedFromViewController(); - } - } - - /** - * Returns whether this Tab is visible. - */ - public boolean isVisible() { - return isActiveTab() && mBrowser.getBrowserFragment().isVisible(); - } - - @CalledByNative - public boolean willAutomaticallyReloadAfterCrashImpl() { - return !isVisible(); - } - - @Override - public boolean willAutomaticallyReloadAfterCrash() { - StrictModeWorkaround.apply(); - return willAutomaticallyReloadAfterCrashImpl(); - } - - public boolean isActiveTab() { - return mBrowser.getActiveTab() == this; - } - - private void updateWebContentsVisibility() { - if (SelectionPopupController.fromWebContentsNoCreate(mWebContents) == null) return; - boolean visibleNow = isVisible(); - boolean webContentsVisible = mWebContents.getVisibility() == Visibility.VISIBLE; - if (visibleNow) { - if (!webContentsVisible) mWebContents.onShow(); - } else { - if (webContentsVisible) mWebContents.onHide(); - } - } - - private void updateDisplayCutoutController() { - if (mDisplayCutoutController == null) return; - - mDisplayCutoutController.onActivityAttachmentChanged( - mBrowser.getBrowserFragment().getWindowAndroid()); - mDisplayCutoutController.maybeUpdateLayout(); - } - - public void loadUrl(LoadUrlParams loadUrlParams) { - String url = loadUrlParams.getUrl(); - if (url == null || url.isEmpty()) return; - - // TODO(https://crbug.com/783819): Don't fix up all URLs. Documentation on FixupURL - // explicitly says not to use it on URLs coming from untrustworthy sources, like other apps. - // Once migrations of Java code to GURL are complete and incoming URLs are converted to - // GURLs at their source, we can make decisions of whether or not to fix up GURLs on a - // case-by-case basis based on trustworthiness of the incoming URL. - GURL fixedUrl = UrlFormatter.fixupUrl(url); - if (!fixedUrl.isValid()) return; - - loadUrlParams.setUrl(fixedUrl.getSpec()); - getWebContents().getNavigationController().loadUrl(loadUrlParams); - } - - public WebContents getWebContents() { - return mWebContents; - } - - public NavigationControllerImpl getNavigationControllerImpl() { - return mNavigationController; - } - - // Public for tests. - @VisibleForTesting - public long getNativeTab() { - return mNativeTab; - } - - public InfoBarContainer getInfoBarContainerForTesting() { - return mInfoBarContainer; - } - - @Override - public NavigationControllerImpl createNavigationController(INavigationControllerClient client) { - StrictModeWorkaround.apply(); - // This should only be called once. - assert mNavigationController == null; - mNavigationController = new NavigationControllerImpl(this, client); - return mNavigationController; - } - - @Override - public void setClient(ITabClient client) { - StrictModeWorkaround.apply(); - mClient = client; - mTabCallbackProxy = new TabCallbackProxy(mNativeTab, client); - } - - @Override - public void setErrorPageCallbackClient(IErrorPageCallbackClient client) { - StrictModeWorkaround.apply(); - if (client != null) { - if (mErrorPageCallbackProxy == null) { - mErrorPageCallbackProxy = new ErrorPageCallbackProxy(mNativeTab, client); - } else { - mErrorPageCallbackProxy.setClient(client); - } - } else if (mErrorPageCallbackProxy != null) { - mErrorPageCallbackProxy.destroy(); - mErrorPageCallbackProxy = null; - } - } - - @Override - public void setFullscreenCallbackClient(IFullscreenCallbackClient client) { - StrictModeWorkaround.apply(); - if (client != null) { - if (mFullscreenCallbackProxy == null) { - mFullscreenCallbackProxy = new FullscreenCallbackProxy(this, mNativeTab, client); - } else { - mFullscreenCallbackProxy.setClient(client); - } - } else if (mFullscreenCallbackProxy != null) { - mFullscreenCallbackProxy.destroy(); - mFullscreenCallbackProxy = null; - } - } - - @Override - public void setGoogleAccountsCallbackClient(IGoogleAccountsCallbackClient client) { - StrictModeWorkaround.apply(); - if (client != null) { - if (mGoogleAccountsCallbackProxy == null) { - mGoogleAccountsCallbackProxy = new GoogleAccountsCallbackProxy(mNativeTab, client); - } else { - mGoogleAccountsCallbackProxy.setClient(client); - } - } else if (mGoogleAccountsCallbackProxy != null) { - mGoogleAccountsCallbackProxy.destroy(); - mGoogleAccountsCallbackProxy = null; - } - } - - public GoogleAccountsCallbackProxy getGoogleAccountsCallbackProxy() { - return mGoogleAccountsCallbackProxy; - } - - @Override - public IFaviconFetcher createFaviconFetcher(IFaviconFetcherClient client) { - StrictModeWorkaround.apply(); - FaviconCallbackProxy proxy = new FaviconCallbackProxy(this, mNativeTab, client); - mFaviconCallbackProxies.add(proxy); - return proxy; - } - - @Override - public void setTranslateTargetLanguage(String targetLanguage) { - StrictModeWorkaround.apply(); - TabImplJni.get().setTranslateTargetLanguage(mNativeTab, targetLanguage); - } - - @Override - public void setScrollOffsetsEnabled(boolean enabled) { - StrictModeWorkaround.apply(); - if (enabled) { - if (mGestureStateListener == null) { - mGestureStateListener = new GestureStateListener() { - @Override - public void onScrollOffsetOrExtentChanged( - int scrollOffsetY, int scrollExtentY) { - try { - mClient.onVerticalScrollOffsetChanged(scrollOffsetY); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - }; - GestureListenerManager.fromWebContents(mWebContents) - .addListener(mGestureStateListener, ALL_UPDATES); - } - } else if (mGestureStateListener != null) { - GestureListenerManager.fromWebContents(mWebContents) - .removeListener(mGestureStateListener); - mGestureStateListener = null; - } - } - - @Override - public void setFloatingActionModeOverride(int actionModeItemTypes) { - StrictModeWorkaround.apply(); - mActionModeCallback.setOverride(actionModeItemTypes); - } - - @Override - public void setDesktopUserAgentEnabled(boolean enable) { - StrictModeWorkaround.apply(); - TabImplJni.get().setDesktopUserAgentEnabled(mNativeTab, enable); - } - - @Override - public boolean isDesktopUserAgentEnabled() { - StrictModeWorkaround.apply(); - return TabImplJni.get().isDesktopUserAgentEnabled(mNativeTab); - } - - @Override - public void download(IContextMenuParams contextMenuParams) { - StrictModeWorkaround.apply(); - NativeContextMenuParamsHolder nativeContextMenuParamsHolder = - (NativeContextMenuParamsHolder) contextMenuParams; - - WindowAndroid window = getBrowser().getBrowserFragment().getWindowAndroid(); - if (window.hasPermission(permission.WRITE_EXTERNAL_STORAGE)) { - continueDownload(nativeContextMenuParamsHolder); - return; - } - - String[] requestPermissions = new String[] {permission.WRITE_EXTERNAL_STORAGE}; - window.requestPermissions(requestPermissions, (permissions, grantResults) -> { - if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - continueDownload(nativeContextMenuParamsHolder); - } - }); - } - - private void continueDownload(NativeContextMenuParamsHolder nativeContextMenuParamsHolder) { - TabImplJni.get().download( - mNativeTab, nativeContextMenuParamsHolder.mNativeContextMenuParams); - } - - @Override - public void addToHomescreen() { - StrictModeWorkaround.apply(); - // TODO(estade): should it be verified that |this| is the active tab? - - // This is used for UMA, and is only meaningful for Chrome. TODO(estade): remove. - Bundle menuItemData = new Bundle(); - menuItemData.putInt(AppBannerManager.MENU_TITLE_KEY, 0); - // TODO(estade): simplify these parameters. - AddToHomescreenCoordinator.showForAppMenu(mBrowser.getContext(), - mBrowser.getBrowserFragment().getWindowAndroid(), - mBrowser.getBrowserFragment().getWindowAndroid().getModalDialogManager(), - mWebContents, menuItemData); - } - - @Override - public void setExternalIntentInIncognitoCallbackClient( - IExternalIntentInIncognitoCallbackClient client) { - StrictModeWorkaround.apply(); - if (client != null) { - if (mExternalIntentInIncognitoCallbackProxy == null) { - mExternalIntentInIncognitoCallbackProxy = - new ExternalIntentInIncognitoCallbackProxy(client); - } else { - mExternalIntentInIncognitoCallbackProxy.setClient(client); - } - } else if (mExternalIntentInIncognitoCallbackProxy != null) { - mExternalIntentInIncognitoCallbackProxy = null; - } - } - - public ExternalIntentInIncognitoCallbackProxy getExternalIntentInIncognitoCallbackProxy() { - return mExternalIntentInIncognitoCallbackProxy; - } - - public void removeFaviconCallbackProxy(FaviconCallbackProxy proxy) { - mFaviconCallbackProxies.remove(proxy); - } - - @Override - public void executeScript(String script, boolean useSeparateIsolate, IStringCallback callback) { - StrictModeWorkaround.apply(); - if (mHeaderVerification == HeaderVerificationStatus.VALIDATED) { - TabImplJni.get().executeScript( - mNativeTab, script, useSeparateIsolate, new NativeStringCallback(callback)); - return; - } - - WebLayerOriginVerificationScheduler originVerifier = - WebLayerOriginVerificationScheduler.getInstance(); - String url = mWebContents.getVisibleUrl().getSpec(); - originVerifier.verify(url, (verified) -> { - // Make sure the page hasn't changed since we started verification. - if (!url.equals(mWebContents.getVisibleUrl().getSpec())) { - return; - } - - if (!verified) { - try { - callback.onException(ExceptionType.RESTRICTED_API, - "Application does not have permissions to modify " + url); - } catch (RemoteException e) { - } - } - TabImplJni.get().executeScript( - mNativeTab, script, useSeparateIsolate, new NativeStringCallback(callback)); - }); - } - - @Override - public boolean setFindInPageCallbackClient(IFindInPageCallbackClient client) { - StrictModeWorkaround.apply(); - if (client == null) { - // Null now to avoid calling onFindEnded. - mFindInPageCallbackClient = null; - hideFindInPageUiAndNotifyClient(); - return true; - } - - if (mFindInPageCallbackClient != null) return false; - - BrowserViewController controller = getViewController(); - if (controller == null) return false; - - mFindInPageCallbackClient = client; - assert mFindInPageBridge == null; - mFindInPageBridge = new FindInPageBridge(mWebContents); - assert mFindResultBar == null; - mFindResultBar = - new FindResultBar(mBrowser.getContext(), controller.getWebContentsOverlayView(), - mBrowser.getBrowserFragment().getWindowAndroid(), mFindInPageBridge); - return true; - } - - @Override - public void findInPage(String searchText, boolean forward) { - StrictModeWorkaround.apply(); - if (mFindInPageBridge == null) return; - - if (searchText.length() > 0) { - mFindInPageBridge.startFinding(searchText, forward, false); - } else { - mFindInPageBridge.stopFinding(true); - } - } - - private void hideFindInPageUiAndNotifyClient() { - if (mFindInPageBridge == null) return; - mFindInPageBridge.stopFinding(true); - - mFindResultBar.dismiss(); - mFindResultBar = null; - mFindInPageBridge.destroy(); - mFindInPageBridge = null; - - try { - if (mFindInPageCallbackClient != null) mFindInPageCallbackClient.onFindEnded(); - mFindInPageCallbackClient = null; - } catch (RemoteException e) { - throw new AndroidRuntimeException(e); - } - } - - @Override - public void dispatchBeforeUnloadAndClose() { - StrictModeWorkaround.apply(); - mWebContents.dispatchBeforeUnload(false); - } - - @Override - public boolean dismissTransientUi() { - StrictModeWorkaround.apply(); - BrowserViewController viewController = getViewController(); - if (viewController != null && viewController.dismissTabModalOverlay()) return true; - - if (mWebContents.isFullscreenForCurrentTab()) { - mWebContents.exitFullscreen(); - return true; - } - - SelectionPopupController popup = - SelectionPopupController.fromWebContentsNoCreate(mWebContents); - if (popup != null && popup.isSelectActionBarShowing()) { - popup.clearSelection(); - return true; - } - - return false; - } - - @Override - public String getGuid() { - StrictModeWorkaround.apply(); - return TabImplJni.get().getGuid(mNativeTab); - } - - @Override - public boolean setData(Map data) { - StrictModeWorkaround.apply(); - String[] flattenedMap = new String[data.size() * 2]; - int i = 0; - for (Map.Entry<String, String> entry : ((Map<String, String>) data).entrySet()) { - flattenedMap[i++] = entry.getKey(); - flattenedMap[i++] = entry.getValue(); - } - return TabImplJni.get().setData(mNativeTab, flattenedMap); - } - - @Override - public Map getData() { - StrictModeWorkaround.apply(); - String[] data = TabImplJni.get().getData(mNativeTab); - Map<String, String> map = new HashMap<>(); - for (int i = 0; i < data.length; i += 2) { - map.put(data[i], data[i + 1]); - } - return map; - } - - @Override - public void captureScreenShot(float scale, IObjectWrapper valueCallback) { - StrictModeWorkaround.apply(); - ValueCallback<Pair<Bitmap, Integer>> unwrappedCallback = - (ValueCallback<Pair<Bitmap, Integer>>) ObjectWrapper.unwrap( - valueCallback, ValueCallback.class); - TabImplJni.get().captureScreenShot(mNativeTab, scale, unwrappedCallback); - } - - @Override - public boolean canTranslate() { - StrictModeWorkaround.apply(); - return TabImplJni.get().canTranslate(mNativeTab); - } - - @Override - public void showTranslateUi() { - StrictModeWorkaround.apply(); - TabImplJni.get().showTranslateUi(mNativeTab); - } - - @CalledByNative - private static void runCaptureScreenShotCallback( - ValueCallback<Pair<Bitmap, Integer>> callback, Bitmap bitmap, int errorCode) { - callback.onReceiveValue(Pair.create(bitmap, errorCode)); - } - - @CalledByNative - private static RectF createRectF(float x, float y, float right, float bottom) { - return new RectF(x, y, right, bottom); - } - - @CalledByNative - private static FindMatchRectsDetails createFindMatchRectsDetails( - int version, int numRects, RectF activeRect) { - return new FindMatchRectsDetails(version, numRects, activeRect); - } - - @CalledByNative - private static void setMatchRectByIndex( - FindMatchRectsDetails findMatchRectsDetails, int index, RectF rect) { - findMatchRectsDetails.rects[index] = rect; - } - - @CalledByNative - private void onFindResultAvailable(int numberOfMatches, int activeMatchOrdinal, - boolean finalUpdate) throws RemoteException { - if (mFindInPageCallbackClient != null) { - // The WebLayer API deals in indices instead of ordinals. - mFindInPageCallbackClient.onFindResult( - numberOfMatches, activeMatchOrdinal - 1, finalUpdate); - } - - if (mFindResultBar != null) { - mFindResultBar.onFindResult(); - if (finalUpdate) { - if (numberOfMatches > 0) { - mWaitingForMatchRects = true; - mFindInPageBridge.requestFindMatchRects(mFindResultBar.getRectsVersion()); - } else { - // Match rects results that correlate to an earlier call to - // requestFindMatchRects might still come in, so set this sentinel to false to - // make sure we ignore them instead of showing stale results. - mWaitingForMatchRects = false; - mFindResultBar.clearMatchRects(); - } - } - } - } - - @CalledByNative - private void onFindMatchRectsAvailable(FindMatchRectsDetails matchRects) { - if (mFindResultBar != null && mWaitingForMatchRects) { - mFindResultBar.setMatchRects( - matchRects.version, matchRects.rects, matchRects.activeRect); - } - } - - @Override - public void setMediaCaptureCallbackClient(IMediaCaptureCallbackClient client) { - StrictModeWorkaround.apply(); - mMediaStreamManager.setClient(client); - } - - @Override - public void stopMediaCapturing() { - StrictModeWorkaround.apply(); - mMediaStreamManager.stopStreaming(); - } - - @CalledByNative - private void handleCloseFromWebContents() throws RemoteException { - if (getBrowser() == null) return; - getBrowser().destroyTab(this); - } - - private String getAppOrigin() { - // TODO(rayankans): Consider exposing the embedder app's fingerprints as well. - return "app://" + mBrowser.getContext().getPackageName(); - } - - @Override - public void postMessage(String message, String targetOrigin) { - StrictModeWorkaround.apply(); - - if (mChannel == null || mChannel[0].isClosed() || mChannel[0].isTransferred() - || mChannel[1].isClosed() || mChannel[1].isTransferred()) { - mChannel = mWebContents.createMessageChannel(); - mChannel[0].setMessageCallback(new MessageCallback() { - @Override - public void onMessage(MessagePayload messagePayload, MessagePort[] sentPorts) { - try { - if (messagePayload.getType() == MessagePayloadType.ARRAY_BUFFER) { - // TODO(rayankans): Consider supporting passing array buffers. - return; - } - mClient.onPostMessage(messagePayload.getAsString(), - mWebContents.getVisibleUrl().getOrigin().getSpec()); - } catch (RemoteException e) { - } - } - }, null); - } - - mWebContents.postMessageToMainFrame(new MessagePayload(message), getAppOrigin(), - targetOrigin, new MessagePort[] {mChannel[1]}); - } - - public void destroy() { - // Ensure that this method isn't called twice. - assert mInterceptNavigationDelegate != null; - - TabImplJni.get().removeTabFromBrowserBeforeDestroying(mNativeTab); - - // Notify the client that this instance is being destroyed to prevent it from calling - // back into this object if the embedder mistakenly tries to do so. - try { - mClient.onTabDestroyed(); - } catch (RemoteException e) { - throw new APICallException(e); - } - - if (mDisplayCutoutController != null) { - mDisplayCutoutController.destroy(); - mDisplayCutoutController = null; - } - - // This is called to ensure a listener is removed from the WebContents. - setScrollOffsetsEnabled(false); - - if (mTabCallbackProxy != null) { - mTabCallbackProxy.destroy(); - mTabCallbackProxy = null; - } - if (mErrorPageCallbackProxy != null) { - mErrorPageCallbackProxy.destroy(); - mErrorPageCallbackProxy = null; - } - if (mFullscreenCallbackProxy != null) { - mFullscreenCallbackProxy.destroy(); - mFullscreenCallbackProxy = null; - } - if (mNewTabCallbackProxy != null) { - mNewTabCallbackProxy.destroy(); - mNewTabCallbackProxy = null; - } - if (mGoogleAccountsCallbackProxy != null) { - mGoogleAccountsCallbackProxy.destroy(); - mGoogleAccountsCallbackProxy = null; - } - - mInterceptNavigationDelegateClient.destroy(); - mInterceptNavigationDelegateClient = null; - mInterceptNavigationDelegate = null; - - mInfoBarContainer.destroy(); - mInfoBarContainer = null; - - mMediaStreamManager.destroy(); - mMediaStreamManager = null; - - if (mMediaSessionHelper != null) { - mMediaSessionHelper.destroy(); - mMediaSessionHelper = null; - } - - if (mAutofillProvider != null) { - mAutofillProvider.destroy(); - mAutofillProvider = null; - } - - // Destroying FaviconCallbackProxy removes from mFaviconCallbackProxies. Copy to avoid - // problems. - Set<FaviconCallbackProxy> faviconCallbackProxies = mFaviconCallbackProxies; - mFaviconCallbackProxies = new HashSet<>(); - for (FaviconCallbackProxy proxy : faviconCallbackProxies) { - proxy.destroy(); - } - assert mFaviconCallbackProxies.isEmpty(); - - sTabMap.remove(mId); - - hideFindInPageUiAndNotifyClient(); - mFindInPageCallbackClient = null; - mNavigationController = null; - mWebContents.removeObserver(mWebContentsObserver); - TabImplJni.get().deleteTab(mNativeTab); - mNativeTab = 0; - } - - @CalledByNative - public void showRepostFormWarningDialog() { - BrowserViewController viewController = getViewController(); - if (viewController == null) { - mWebContents.getNavigationController().cancelPendingReload(); - } else { - viewController.showRepostFormWarningDialog(); - } - } - - private static String nonEmptyOrNull(String s) { - return TextUtils.isEmpty(s) ? null : s; - } - - private static class NativeContextMenuParamsHolder extends IContextMenuParams.Stub { - // Note: avoid adding more members since an object with a finalizer will delay GC of any - // object it references. - private final long mNativeContextMenuParams; - - NativeContextMenuParamsHolder(long nativeContextMenuParams) { - mNativeContextMenuParams = nativeContextMenuParams; - } - - /** - * A finalizer is required to ensure that the native object associated with - * this object gets destructed, otherwise there would be a memory leak. - * - * This is safe because it makes a simple call into C++ code that is both - * thread-safe and very fast. - * - * @see java.lang.Object#finalize() - */ - @Override - protected final void finalize() throws Throwable { - super.finalize(); - TabImplJni.get().destroyContextMenuParams(mNativeContextMenuParams); - } - } - - @CalledByNative - private void showContextMenu(ContextMenuParams params, long nativeContextMenuParams) - throws RemoteException { - if (WebLayerFactoryImpl.getClientMajorVersion() < 88) { - mClient.showContextMenu(ObjectWrapper.wrap(params.getPageUrl().getSpec()), - ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkUrl().getSpec())), - ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkText())), - ObjectWrapper.wrap(nonEmptyOrNull(params.getTitleText())), - ObjectWrapper.wrap(nonEmptyOrNull(params.getSrcUrl().getSpec()))); - return; - } - - boolean canDownload = - (params.isImage() && UrlUtilities.isDownloadableScheme(params.getSrcUrl())) - || (params.isVideo() && UrlUtilities.isDownloadableScheme(params.getSrcUrl()) - && params.canSaveMedia()) - || (params.isAnchor() && UrlUtilities.isDownloadableScheme(params.getLinkUrl())); - mClient.showContextMenu2(ObjectWrapper.wrap(params.getPageUrl().getSpec()), - ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkUrl().getSpec())), - ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkText())), - ObjectWrapper.wrap(nonEmptyOrNull(params.getTitleText())), - ObjectWrapper.wrap(nonEmptyOrNull(params.getSrcUrl().getSpec())), params.isImage(), - params.isVideo(), canDownload, - new NativeContextMenuParamsHolder(nativeContextMenuParams)); - } - - @VisibleForTesting - public boolean didShowFullscreenToast() { - return mFullscreenCallbackProxy != null - && mFullscreenCallbackProxy.didShowFullscreenToast(); - } - - private void ensureDisplayCutoutController() { - if (mDisplayCutoutController != null) return; - - mDisplayCutoutController = - new DisplayCutoutController(new DisplayCutoutController.Delegate() { - @Override - public Activity getAttachedActivity() { - WindowAndroid window = mBrowser.getBrowserFragment().getWindowAndroid(); - return window == null ? null : window.getActivity().get(); - } - - @Override - public WebContents getWebContents() { - return mWebContents; - } - - @Override - public InsetObserverView getInsetObserverView() { - BrowserViewController controller = - mBrowser.getBrowserFragment().getPossiblyNullViewController(); - return controller != null ? controller.getInsetObserverView() : null; - } - - @Override - public ObservableSupplier<Integer> getBrowserDisplayCutoutModeSupplier() { - // No activity-wide display cutout mode override. - return null; - } - - @Override - public boolean isInteractable() { - return isVisible(); - } - - @Override - public boolean isInBrowserFullscreen() { - return false; - } - }); - } - - /** - * Returns the BrowserViewController for this TabImpl, but only if this - * is the active TabImpl. Can also return null if in the middle of shutdown - * or Browser is not attached to any activity. - */ - @Nullable - private BrowserViewController getViewController() { - if (!isActiveTab()) return null; - // During rotation it's possible for this to be called before BrowserViewController has been - // updated. Verify BrowserViewController reflects this is the active tab before returning - // it. - BrowserViewController viewController = - mBrowser.getBrowserFragment().getPossiblyNullViewController(); - return viewController != null && viewController.getTab() == this ? viewController : null; - } - - public boolean canInfoBarContainerScrollForTesting() { - return mInfoBarContainer.getContainerViewForTesting().isAllowedToAutoHide(); - } - - public String getTranslateInfoBarTargetLanguageForTesting() { - if (!mInfoBarContainer.hasInfoBars()) return null; - - ArrayList<InfoBar> infobars = mInfoBarContainer.getInfoBarsForTesting(); - TranslateCompactInfoBar translateInfoBar = (TranslateCompactInfoBar) infobars.get(0); - - return translateInfoBar.getTargetLanguageForTesting(); - } - - /** Called by {@link FaviconCallbackProxy} when the favicon for the current page has changed. */ - public void onFaviconChanged(Bitmap bitmap) { - if (mMediaSessionHelper != null) { - mMediaSessionHelper.updateFavicon(bitmap); - } - } - - @NativeMethods - interface Natives { - TabImpl fromWebContents(WebContents webContents); - long createTab(long tab, TabImpl caller); - void removeTabFromBrowserBeforeDestroying(long nativeTabImpl); - void deleteTab(long tab); - void setJavaImpl(long nativeTabImpl, TabImpl impl); - void initializeAutofillIfNecessary(long nativeTabImpl); - WebContents getWebContents(long nativeTabImpl); - void executeScript(long nativeTabImpl, String script, boolean useSeparateIsolate, - Callback<String> callback); - String getGuid(long nativeTabImpl); - void captureScreenShot(long nativeTabImpl, float scale, - ValueCallback<Pair<Bitmap, Integer>> valueCallback); - boolean setData(long nativeTabImpl, String[] data); - String[] getData(long nativeTabImpl); - boolean canTranslate(long nativeTabImpl); - void showTranslateUi(long nativeTabImpl); - void setTranslateTargetLanguage(long nativeTabImpl, String targetLanguage); - void setDesktopUserAgentEnabled(long nativeTabImpl, boolean enable); - boolean isDesktopUserAgentEnabled(long nativeTabImpl); - void download(long nativeTabImpl, long nativeContextMenuParams); - void destroyContextMenuParams(long contextMenuParams); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java b/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java deleted file mode 100644 index dd42909e..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java +++ /dev/null
@@ -1,526 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnLayoutChangeListener; -import android.widget.ImageButton; -import android.widget.LinearLayout; - -import androidx.core.content.ContextCompat; - -import com.google.android.material.tabs.TabLayout; - -import org.chromium.base.StrictModeContext; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.chrome.browser.infobar.ActionType; -import org.chromium.chrome.browser.infobar.InfobarEvent; -import org.chromium.components.infobars.InfoBar; -import org.chromium.components.infobars.InfoBarCompactLayout; -import org.chromium.components.translate.TranslateMenu; -import org.chromium.components.translate.TranslateMenuHelper; -import org.chromium.components.translate.TranslateOption; -import org.chromium.components.translate.TranslateOptions; -import org.chromium.components.translate.TranslateTabLayout; -import org.chromium.ui.widget.Toast; - -/** - * Java version of the compact translate infobar. - */ -@JNINamespace("weblayer") -public class TranslateCompactInfoBar extends InfoBar - implements TabLayout.OnTabSelectedListener, TranslateMenuHelper.TranslateMenuListener { - public static final int TRANSLATING_INFOBAR = 1; - public static final int AFTER_TRANSLATING_INFOBAR = 2; - - private static final int SOURCE_TAB_INDEX = 0; - private static final int TARGET_TAB_INDEX = 1; - - // Action ID for Snackbar. - // Actions performed by clicking on on the overflow menu. - public static final int ACTION_OVERFLOW_ALWAYS_TRANSLATE = 0; - public static final int ACTION_OVERFLOW_NEVER_SITE = 1; - public static final int ACTION_OVERFLOW_NEVER_LANGUAGE = 2; - // Actions triggered automatically. (when translation or denied count reaches the threshold.) - public static final int ACTION_AUTO_ALWAYS_TRANSLATE = 3; - public static final int ACTION_AUTO_NEVER_LANGUAGE = 4; - - private final int mInitialStep; - private final int mDefaultTextColor; - private final TranslateOptions mOptions; - - private long mNativeTranslateInfoBarPtr; - private TranslateTabLayout mTabLayout; - - // Histogram names for logging metrics. - private static final String INFOBAR_HISTOGRAM = "Translate.CompactInfobar.Event"; - - // Need 2 instances of TranslateMenuHelper to prevent a race condition bug which happens when - // showing language menu after dismissing overflow menu. - private TranslateMenuHelper mOverflowMenuHelper; - private TranslateMenuHelper mLanguageMenuHelper; - - private ImageButton mMenuButton; - private InfoBarCompactLayout mParent; - - private boolean mMenuExpanded; - private boolean mIsFirstLayout = true; - private boolean mUserInteracted; - - @CalledByNative - private static InfoBar create(TabImpl tab, int initialStep, String sourceLanguageCode, - String targetLanguageCode, boolean neverLanguage, boolean neverDomain, - boolean alwaysTranslate, boolean triggeredFromMenu, String[] languages, - String[] languageCodes, int[] hashCodes, int tabTextColor) { - recordInfobarAction(InfobarEvent.INFOBAR_IMPRESSION); - return new TranslateCompactInfoBar(initialStep, sourceLanguageCode, targetLanguageCode, - neverLanguage, neverDomain, alwaysTranslate, triggeredFromMenu, languages, - languageCodes, hashCodes, tabTextColor); - } - - TranslateCompactInfoBar(int initialStep, String sourceLanguageCode, String targetLanguageCode, - boolean neverLanguage, boolean neverDomain, boolean alwaysTranslate, - boolean triggeredFromMenu, String[] languages, String[] languageCodes, int[] hashCodes, - int tabTextColor) { - super(R.drawable.infobar_translate_compact, 0, null, null); - - mInitialStep = initialStep; - mDefaultTextColor = tabTextColor; - mOptions = TranslateOptions.create(sourceLanguageCode, targetLanguageCode, languages, - languageCodes, neverLanguage, neverDomain, alwaysTranslate, triggeredFromMenu, - hashCodes, - /*contentLanguagesCodes*/ null); - } - - @Override - protected boolean usesCompactLayout() { - return true; - } - - @Override - protected void createCompactLayoutContent(InfoBarCompactLayout parent) { - LinearLayout content; - // LayoutInflater may trigger accessing the disk. - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - content = (LinearLayout) LayoutInflater.from(getContext()) - .inflate(R.layout.weblayer_infobar_translate_compact_content, parent, - false); - } - - // When parent tab is being switched out (view detached), dismiss all menus and snackbars. - content.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { - @Override - public void onViewAttachedToWindow(View view) {} - - @Override - public void onViewDetachedFromWindow(View view) { - dismissMenusAndSnackbars(); - } - }); - - mTabLayout = - (TranslateTabLayout) content.findViewById(R.id.weblayer_translate_infobar_tabs); - if (mDefaultTextColor > 0) { - mTabLayout.setTabTextColors( - ContextCompat.getColor(getContext(), R.color.default_text_color_baseline), - ContextCompat.getColor( - getContext(), R.color.weblayer_tab_layout_selected_tab_color)); - } - mTabLayout.addTabs(mOptions.sourceLanguageName(), mOptions.targetLanguageName()); - - if (mInitialStep == TRANSLATING_INFOBAR) { - // Set translating status in the beginning for pages translated automatically. - mTabLayout.getTabAt(TARGET_TAB_INDEX).select(); - mTabLayout.showProgressBarOnTab(TARGET_TAB_INDEX); - mUserInteracted = true; - } else if (mInitialStep == AFTER_TRANSLATING_INFOBAR) { - // Focus on target tab since we are after translation. - mTabLayout.getTabAt(TARGET_TAB_INDEX).select(); - } - - mTabLayout.addOnTabSelectedListener(this); - - // Dismiss all menus and end scrolling animation when there is layout changed. - mTabLayout.addOnLayoutChangeListener(new OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) { - // Dismiss all menus to prevent menu misplacement. - dismissMenus(); - - if (mIsFirstLayout) { - // Scrolls to the end to make sure the target language tab is visible when - // language tabs is too long. - mTabLayout.startScrollingAnimationIfNeeded(); - mIsFirstLayout = false; - return; - } - - // End scrolling animation when layout changed. - mTabLayout.endScrollingAnimationIfPlaying(); - } - } - }); - - mMenuButton = content.findViewById(R.id.weblayer_translate_infobar_menu_button); - mMenuButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mTabLayout.endScrollingAnimationIfPlaying(); - recordInfobarAction(InfobarEvent.INFOBAR_OPTIONS); - initMenuHelper(TranslateMenu.MENU_OVERFLOW); - mOverflowMenuHelper.show(TranslateMenu.MENU_OVERFLOW, getParentWidth()); - mMenuExpanded = true; - } - }); - - parent.addContent(content, 1.0f); - mParent = parent; - } - - private void initMenuHelper(int menuType) { - boolean isIncognito = TranslateCompactInfoBarJni.get().isIncognito( - mNativeTranslateInfoBarPtr, TranslateCompactInfoBar.this); - boolean isSourceLangUnknown = mOptions.sourceLanguageCode().equals("und"); - switch (menuType) { - case TranslateMenu.MENU_OVERFLOW: - mOverflowMenuHelper = new TranslateMenuHelper(getContext(), mMenuButton, mOptions, - this, isIncognito, isSourceLangUnknown); - return; - case TranslateMenu.MENU_TARGET_LANGUAGE: - case TranslateMenu.MENU_SOURCE_LANGUAGE: - if (mLanguageMenuHelper == null) { - mLanguageMenuHelper = new TranslateMenuHelper(getContext(), mMenuButton, - mOptions, this, isIncognito, isSourceLangUnknown); - } - return; - default: - assert false : "Unsupported Menu Item Id"; - } - } - - private void startTranslating(int tabPosition) { - if (TARGET_TAB_INDEX == tabPosition) { - // Already on the target tab. - mTabLayout.showProgressBarOnTab(TARGET_TAB_INDEX); - onButtonClicked(ActionType.TRANSLATE); - mUserInteracted = true; - } else { - mTabLayout.getTabAt(TARGET_TAB_INDEX).select(); - } - } - - @CalledByNative - private void onPageTranslated(int errorType) { - if (mTabLayout != null) { - mTabLayout.hideProgressBar(); - if (errorType != 0) { - Toast.makeText(getContext(), R.string.translate_infobar_error, Toast.LENGTH_SHORT) - .show(); - // Disable OnTabSelectedListener then revert selection. - mTabLayout.removeOnTabSelectedListener(this); - mTabLayout.getTabAt(SOURCE_TAB_INDEX).select(); - // Add OnTabSelectedListener back. - mTabLayout.addOnTabSelectedListener(this); - } - } - } - - @CalledByNative - private void setNativePtr(long nativePtr) { - mNativeTranslateInfoBarPtr = nativePtr; - } - - @CalledByNative - private void setAutoAlwaysTranslate() { - createAndShowSnackbar(ACTION_AUTO_ALWAYS_TRANSLATE); - } - - @Override - protected void resetNativeInfoBar() { - mNativeTranslateInfoBarPtr = 0; - super.resetNativeInfoBar(); - } - - private void closeInfobar(boolean explicitly) { - if (isDismissed()) return; - - if (!mUserInteracted) { - recordInfobarAction(InfobarEvent.INFOBAR_DECLINE); - } - - // NOTE: In Chrome there is a check for whether auto "never translate" should be triggered - // via a snackbar here. However, WebLayer does not have snackbars and thus does not have - // this check as there would be no way to inform the user of the functionality being - // triggered. The user of course has the option of choosing "never translate" from the - // overflow menu. - - // This line will dismiss this infobar. - super.onCloseButtonClicked(); - } - - @Override - public void onCloseButtonClicked() { - mTabLayout.endScrollingAnimationIfPlaying(); - closeInfobar(true); - } - - @Override - public void onTabSelected(TabLayout.Tab tab) { - switch (tab.getPosition()) { - case SOURCE_TAB_INDEX: - recordInfobarAction(InfobarEvent.INFOBAR_REVERT); - onButtonClicked(ActionType.TRANSLATE_SHOW_ORIGINAL); - return; - case TARGET_TAB_INDEX: - recordInfobarAction(InfobarEvent.INFOBAR_TARGET_TAB_TRANSLATE); - startTranslating(TARGET_TAB_INDEX); - return; - default: - assert false : "Unexpected Tab Index"; - } - } - - @Override - public void onTabUnselected(TabLayout.Tab tab) {} - - @Override - public void onTabReselected(TabLayout.Tab tab) {} - - @Override - public void onOverflowMenuItemClicked(int itemId) { - switch (itemId) { - case TranslateMenu.ID_OVERFLOW_MORE_LANGUAGE: - recordInfobarAction(InfobarEvent.INFOBAR_MORE_LANGUAGES); - initMenuHelper(TranslateMenu.MENU_TARGET_LANGUAGE); - mLanguageMenuHelper.show(TranslateMenu.MENU_TARGET_LANGUAGE, getParentWidth()); - return; - case TranslateMenu.ID_OVERFLOW_ALWAYS_TRANSLATE: - // Only show snackbar when "Always Translate" is enabled. - if (!mOptions.getTranslateState(TranslateOptions.Type.ALWAYS_LANGUAGE)) { - recordInfobarAction(InfobarEvent.INFOBAR_ALWAYS_TRANSLATE); - createAndShowSnackbar(ACTION_OVERFLOW_ALWAYS_TRANSLATE); - } else { - recordInfobarAction(InfobarEvent.INFOBAR_ALWAYS_TRANSLATE_UNDO); - handleTranslateOverflowOption(ACTION_OVERFLOW_ALWAYS_TRANSLATE); - } - return; - case TranslateMenu.ID_OVERFLOW_NEVER_LANGUAGE: - // Only show snackbar when "Never Translate" is enabled. - if (!mOptions.getTranslateState(TranslateOptions.Type.NEVER_LANGUAGE)) { - recordInfobarAction(InfobarEvent.INFOBAR_NEVER_TRANSLATE); - createAndShowSnackbar(ACTION_OVERFLOW_NEVER_LANGUAGE); - } else { - recordInfobarAction(InfobarEvent.INFOBAR_NEVER_TRANSLATE_UNDO); - handleTranslateOverflowOption(ACTION_OVERFLOW_NEVER_LANGUAGE); - } - return; - case TranslateMenu.ID_OVERFLOW_NEVER_SITE: - // Only show snackbar when "Never Translate Site" is enabled. - if (!mOptions.getTranslateState(TranslateOptions.Type.NEVER_DOMAIN)) { - recordInfobarAction(InfobarEvent.INFOBAR_NEVER_TRANSLATE_SITE); - createAndShowSnackbar(ACTION_OVERFLOW_NEVER_SITE); - } else { - recordInfobarAction(InfobarEvent.INFOBAR_NEVER_TRANSLATE_SITE_UNDO); - handleTranslateOverflowOption(ACTION_OVERFLOW_NEVER_SITE); - } - return; - case TranslateMenu.ID_OVERFLOW_NOT_THIS_LANGUAGE: - recordInfobarAction(InfobarEvent.INFOBAR_PAGE_NOT_IN); - initMenuHelper(TranslateMenu.MENU_SOURCE_LANGUAGE); - mLanguageMenuHelper.show(TranslateMenu.MENU_SOURCE_LANGUAGE, getParentWidth()); - return; - default: - assert false : "Unexpected overflow menu code"; - } - } - - @Override - public void onTargetMenuItemClicked(String code) { - // Reset target code in both UI and native. - if (mNativeTranslateInfoBarPtr != 0 && mOptions.setTargetLanguage(code)) { - recordInfobarAction(InfobarEvent.INFOBAR_MORE_LANGUAGES_TRANSLATE); - TranslateCompactInfoBarJni.get().applyStringTranslateOption(mNativeTranslateInfoBarPtr, - TranslateCompactInfoBar.this, TranslateOption.TARGET_CODE, code); - // Adjust UI. - mTabLayout.replaceTabTitle(TARGET_TAB_INDEX, mOptions.getRepresentationFromCode(code)); - startTranslating(mTabLayout.getSelectedTabPosition()); - } - } - - @Override - public void onSourceMenuItemClicked(String code) { - // Reset source code in both UI and native. - if (mNativeTranslateInfoBarPtr != 0 && mOptions.setSourceLanguage(code)) { - TranslateCompactInfoBarJni.get().applyStringTranslateOption(mNativeTranslateInfoBarPtr, - TranslateCompactInfoBar.this, TranslateOption.SOURCE_CODE, code); - // Adjust UI. - mTabLayout.replaceTabTitle(SOURCE_TAB_INDEX, mOptions.getRepresentationFromCode(code)); - startTranslating(mTabLayout.getSelectedTabPosition()); - } - } - - // Dismiss all overflow menus that remains open. - // This is called when infobar started hiding or layout changed. - private void dismissMenus() { - if (mOverflowMenuHelper != null) mOverflowMenuHelper.dismiss(); - if (mLanguageMenuHelper != null) mLanguageMenuHelper.dismiss(); - } - - // Dismiss all overflow menus and snackbars that belong to this infobar and remain open. - private void dismissMenusAndSnackbars() { - dismissMenus(); - } - - @Override - protected void onStartedHiding() { - dismissMenusAndSnackbars(); - } - - @Override - protected CharSequence getAccessibilityMessage(CharSequence defaultMessage) { - return getContext().getString(R.string.translate_button); - } - - /** - * Returns true if overflow menu is showing. This is only used for automation testing. - */ - public boolean isShowingOverflowMenuForTesting() { - if (mOverflowMenuHelper == null) return false; - return mOverflowMenuHelper.isShowing(); - } - - /** - * Returns true if language menu is showing. This is only used for automation testing. - */ - public boolean isShowingLanguageMenuForTesting() { - if (mLanguageMenuHelper == null) return false; - return mLanguageMenuHelper.isShowing(); - } - - /** - * Returns true if the tab at the given |tabIndex| is selected. This is only used for automation - * testing. - */ - private boolean isTabSelectedForTesting(int tabIndex) { - return mTabLayout.getTabAt(tabIndex).isSelected(); - } - - /** - * Returns true if the target tab is selected. This is only used for automation testing. - */ - public boolean isSourceTabSelectedForTesting() { - return this.isTabSelectedForTesting(SOURCE_TAB_INDEX); - } - - /** - * Returns true if the target tab is selected. This is only used for automation testing. - */ - public boolean isTargetTabSelectedForTesting() { - return this.isTabSelectedForTesting(TARGET_TAB_INDEX); - } - - /** - * Returns the name of the target language. This is only used for automation testing. - */ - public String getTargetLanguageForTesting() { - return mOptions.targetLanguageName(); - } - - private void createAndShowSnackbar(int actionId) { - // NOTE: WebLayer doesn't have snackbars, so the relevant action is just taken directly. - // TODO(blundell): If WebLayer ends up staying with this implementation long-term, update - // the nomenclature of this file to avoid any references to snackbars. - handleTranslateOverflowOption(actionId); - } - - private void handleTranslateOverflowOption(int actionId) { - // Quit if native is destroyed. - if (mNativeTranslateInfoBarPtr == 0) return; - - switch (actionId) { - case ACTION_OVERFLOW_ALWAYS_TRANSLATE: - toggleAlwaysTranslate(); - // Start translating if always translate is selected and if page is not already - // translated to the target language. - if (mOptions.getTranslateState(TranslateOptions.Type.ALWAYS_LANGUAGE) - && mTabLayout.getSelectedTabPosition() == SOURCE_TAB_INDEX) { - startTranslating(mTabLayout.getSelectedTabPosition()); - } - return; - case ACTION_AUTO_ALWAYS_TRANSLATE: - toggleAlwaysTranslate(); - return; - case ACTION_OVERFLOW_NEVER_LANGUAGE: - mUserInteracted = true; - // Fallthrough intentional. - case ACTION_AUTO_NEVER_LANGUAGE: - mOptions.toggleNeverTranslateLanguageState( - !mOptions.getTranslateState(TranslateOptions.Type.NEVER_LANGUAGE)); - TranslateCompactInfoBarJni.get().applyBoolTranslateOption( - mNativeTranslateInfoBarPtr, TranslateCompactInfoBar.this, - TranslateOption.NEVER_TRANSLATE, - mOptions.getTranslateState(TranslateOptions.Type.NEVER_LANGUAGE)); - return; - case ACTION_OVERFLOW_NEVER_SITE: - mUserInteracted = true; - mOptions.toggleNeverTranslateDomainState( - !mOptions.getTranslateState(TranslateOptions.Type.NEVER_DOMAIN)); - TranslateCompactInfoBarJni.get().applyBoolTranslateOption( - mNativeTranslateInfoBarPtr, TranslateCompactInfoBar.this, - TranslateOption.NEVER_TRANSLATE_SITE, - mOptions.getTranslateState(TranslateOptions.Type.NEVER_DOMAIN)); - return; - default: - assert false : "Unsupported Menu Item Id, in handle post snackbar"; - } - } - - private void toggleAlwaysTranslate() { - mOptions.toggleAlwaysTranslateLanguageState( - !mOptions.getTranslateState(TranslateOptions.Type.ALWAYS_LANGUAGE)); - TranslateCompactInfoBarJni.get().applyBoolTranslateOption(mNativeTranslateInfoBarPtr, - TranslateCompactInfoBar.this, TranslateOption.ALWAYS_TRANSLATE, - mOptions.getTranslateState(TranslateOptions.Type.ALWAYS_LANGUAGE)); - } - - private static void recordInfobarAction(int action) { - RecordHistogram.recordEnumeratedHistogram( - INFOBAR_HISTOGRAM, action, InfobarEvent.INFOBAR_HISTOGRAM_BOUNDARY); - } - - // Return the width of parent in pixels. Return 0 if there is no parent. - private int getParentWidth() { - return mParent != null ? mParent.getWidth() : 0; - } - - // Selects the tab corresponding to |actionType| to simulate the user pressing on this tab. - void selectTabForTesting(int actionType) { - if (actionType == ActionType.TRANSLATE) { - mTabLayout.getTabAt(TARGET_TAB_INDEX).select(); - } else if (actionType == ActionType.TRANSLATE_SHOW_ORIGINAL) { - mTabLayout.getTabAt(SOURCE_TAB_INDEX).select(); - } else { - assert false; - } - } - - @NativeMethods - interface Natives { - void applyStringTranslateOption(long nativeTranslateCompactInfoBar, - TranslateCompactInfoBar caller, int option, String value); - void applyBoolTranslateOption(long nativeTranslateCompactInfoBar, - TranslateCompactInfoBar caller, int option, boolean value); - boolean shouldAutoNeverTranslate(long nativeTranslateCompactInfoBar, - TranslateCompactInfoBar caller, boolean menuExpanded); - boolean isIncognito(long nativeTranslateCompactInfoBar, TranslateCompactInfoBar caller); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java b/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java deleted file mode 100644 index 648ca0ec0..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.graphics.Bitmap; - -import org.chromium.base.Callback; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.webapps.WebApkInstallResult; - -/** - * Java counterpart to webapk_install_scheduler_bridge. - * Contains functionality to schedule WebAPK installs with the {@link - * WebApkInstallCoordinatorService} in Chrome. This Java object is created by and owned by the - * native WebApkInstallSchedulerBridge. - */ -@JNINamespace("weblayer") -public class WebApkInstallSchedulerBridge { - // Raw pointer to the native WebApkInstallSchedulerBridge that is cleared when the native object - // destroys this object. - private long mNativePointer; - - /** - * This callback is passed via the {@link WebApkInstallSchedulerClient} to the Chrome - * {@link WebApkInstallCoordinatorService} and will be called from there with the result - * of the install. This result is passed along to the native side. - */ - Callback<Integer> mOnInstallCompleteCallback = (result) -> { - if (mNativePointer != 0) { - WebApkInstallSchedulerBridgeJni.get().onInstallFinished( - mNativePointer, WebApkInstallSchedulerBridge.this, result); - } - }; - - private WebApkInstallSchedulerBridge(long nativePtr) { - mNativePointer = nativePtr; - } - - @CalledByNative - private static WebApkInstallSchedulerBridge create(long nativePtr) { - return new WebApkInstallSchedulerBridge(nativePtr); - } - - @CalledByNative - public void scheduleInstall( - byte[] apkProto, Bitmap primaryIcon, boolean isPrimaryIconMaskable) { - WebApkInstallSchedulerClient.scheduleInstall( - apkProto, primaryIcon, isPrimaryIconMaskable, mOnInstallCompleteCallback); - } - - /** - * Returns if the {@link WebApkInstallCoordinatorService} is available. - */ - @CalledByNative - public static boolean isInstallServiceAvailable() { - return WebApkInstallSchedulerClient.isInstallServiceAvailable(); - } - - @CalledByNative - private void destroy() { - // Remove the reference to the native side. - mNativePointer = 0; - } - - @NativeMethods - interface Natives { - void onInstallFinished(long nativeWebApkInstallSchedulerBridge, - WebApkInstallSchedulerBridge caller, @WebApkInstallResult int result); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerClient.java b/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerClient.java deleted file mode 100644 index 1a17e270..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerClient.java +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.graphics.Bitmap; -import android.os.RemoteException; - -import androidx.annotation.BinderThread; -import androidx.annotation.MainThread; - -import org.chromium.base.Callback; -import org.chromium.base.Log; -import org.chromium.base.Promise; -import org.chromium.base.task.PostTask; -import org.chromium.base.task.TaskTraits; -import org.chromium.components.webapk_install.IOnFinishInstallCallback; -import org.chromium.components.webapk_install.IWebApkInstallCoordinatorService; -import org.chromium.components.webapps.WebApkInstallResult; - -/** - * Contains functionality to connect to the {@link WebApkInstallCoordinatorService} in Chrome using - * the {@link WebApkServiceConnection}, schedule the install of one WebAPK and receive the install - * result via the {@link IOnFinishInstallCallback}. - */ -public class WebApkInstallSchedulerClient { - private static final String TAG = "WebApkInstallClient"; - - /** - * Casts an int to {@link WebApkInstallResult}. - */ - public @WebApkInstallResult static int asWebApkInstallResult(int webApkInstallResult) { - return webApkInstallResult; - } - - @MainThread - Promise<Integer> startInstallTask(byte[] apkProto, Bitmap primaryIcon, - boolean isPrimaryIconMaskable, IWebApkInstallCoordinatorService serviceInterface) { - Promise<Integer> whenInstallTaskCompleted = new Promise<>(); - IOnFinishInstallCallback.Stub serviceCallback = new IOnFinishInstallCallback.Stub() { - @Override - @BinderThread - public void handleOnFinishInstall(int result) { - // Post the task back to the main thread as promises have to be accessed from a - // single thread. - PostTask.postTask( - TaskTraits.UI_DEFAULT, () -> { whenInstallTaskCompleted.fulfill(result); }); - } - }; - - try { - serviceInterface.scheduleInstallAsync( - apkProto, primaryIcon, isPrimaryIconMaskable, serviceCallback); - } catch (RemoteException e) { - Log.w(TAG, "Failed to schedule install with Chrome WebAPK install service.", e); - whenInstallTaskCompleted.reject(); - } - - return whenInstallTaskCompleted; - } - - /** - * Schedules the install of one WebAPK with Chrome's {@link WebApkInstallCoordinatorService}. - * The {@code onInstallFinishedCallback} is triggered when the install finished or failed. - */ - @MainThread - public static void scheduleInstall(byte[] apkProto, Bitmap primaryIcon, - boolean isPrimaryIconMaskable, Callback<Integer> onInstallFinishedCallback) { - WebApkInstallSchedulerClient client = new WebApkInstallSchedulerClient(); - - WebApkServiceConnection webApkServiceConnection = new WebApkServiceConnection(); - Promise<IWebApkInstallCoordinatorService> whenServiceConnected = - webApkServiceConnection.connect(); - whenServiceConnected - .then( - /*fulfilled */ - (IWebApkInstallCoordinatorService serviceInterface) - -> client.startInstallTask(apkProto, primaryIcon, - isPrimaryIconMaskable, serviceInterface)) - .then( - /*fulfilled */ - installResult - -> { - webApkServiceConnection.unbindIfNeeded(); - onInstallFinishedCallback.onResult( - asWebApkInstallResult(installResult)); - }, - /*rejected*/ - err -> { - webApkServiceConnection.unbindIfNeeded(); - onInstallFinishedCallback.onResult(WebApkInstallResult.FAILURE); - }); - } - - /** - * Returns if the {@link WebApkInstallCoordinatorService} is available. - */ - public static boolean isInstallServiceAvailable() { - return WebApkServiceConnection.isInstallServiceAvailable(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebApkServiceConnection.java b/weblayer/browser/java/org/chromium/weblayer_private/WebApkServiceConnection.java deleted file mode 100644 index 30add23..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebApkServiceConnection.java +++ /dev/null
@@ -1,107 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.ResolveInfo; -import android.os.IBinder; - -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.Promise; -import org.chromium.components.webapk_install.IWebApkInstallCoordinatorService; - -/** - * Service Connection to the {@link WebApkInstallCoordinatorService} in Chrome. - */ -class WebApkServiceConnection implements ServiceConnection { - private static final String TAG = "WebApkServiceConn"; - - private static final String BIND_WEBAPK_SCHEDULE_INSTALL_INTENT_ACTION = - "org.chromium.intent.action.INSTALL_WEB_APK"; - - // TODO(swestphal): set package name of production chrome apk - private static final String CHROME_PACKAGE_NAME = "com.google.android.apps.chrome"; - - private Context mContext; - private boolean mIsBound; - // The promise is fulfilled as soon as the connection is established, it will then provide the - // {@link IWebApkInstallCoordinatorService}. It will be rejected if the connection to the - // service cannot be established. Retrieve the {@code mPromiseServiceInterface} by calling - // {@link connect()}. - Promise<IWebApkInstallCoordinatorService> mPromiseServiceInterface; - - WebApkServiceConnection() { - mContext = ContextUtils.getApplicationContext(); - mPromiseServiceInterface = new Promise<>(); - } - - private static Intent createChromeInstallServiceIntent() { - Intent intent = new Intent(BIND_WEBAPK_SCHEDULE_INSTALL_INTENT_ACTION); - intent.setPackage(CHROME_PACKAGE_NAME); - return intent; - } - - /** - * Tries to bind to the service, returns a promise which will be fulfilled as - * soon as the connection is established or rejected in the failure case. - * This function must only be called once. - */ - Promise<IWebApkInstallCoordinatorService> connect() { - Intent intent = createChromeInstallServiceIntent(); - - try { - mIsBound = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); - if (!mIsBound) { - Log.w(TAG, "Failed to bind to Chrome install service."); - mPromiseServiceInterface.reject(); - } - } catch (SecurityException e) { - Log.w(TAG, "SecurityException while binding to Chrome install service.", e); - mPromiseServiceInterface.reject(); - } - - return mPromiseServiceInterface; - } - - /** - * Unbinds the service connection if it is currently bound. - */ - void unbindIfNeeded() { - if (mIsBound) { - mContext.unbindService(this); - } - mIsBound = false; - } - - /** - * Returns if the {@link WebApkInstallCoordinatorService} is available. - */ - public static boolean isInstallServiceAvailable() { - ResolveInfo info = ContextUtils.getApplicationContext().getPackageManager().resolveService( - createChromeInstallServiceIntent(), 0); - return info != null; - } - - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - IWebApkInstallCoordinatorService serviceInterface = - IWebApkInstallCoordinatorService.Stub.asInterface(service); - - mPromiseServiceInterface.fulfill(serviceInterface); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - if (!mPromiseServiceInterface.isFulfilled() && !mPromiseServiceInterface.isRejected()) { - mPromiseServiceInterface.reject(); - } - // Called when the Service closes the connection so we still might need to unbind. - unbindIfNeeded(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java b/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java deleted file mode 100644 index d61a6850..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java +++ /dev/null
@@ -1,112 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.view.MotionEvent; -import android.view.View; - -import org.chromium.content_public.browser.GestureListenerManager; -import org.chromium.content_public.browser.GestureStateListener; -import org.chromium.content_public.browser.WebContents; - -/** - * WebContentsGestureStateTracker is responsible for tracking when a scroll/gesture is in progress - * and notifying when the state changes. - */ -// TODO(sky): refactor TabGestureStateListener and this to a common place. -public final class WebContentsGestureStateTracker { - private GestureListenerManager mGestureListenerManager; - private GestureStateListener mGestureListener; - private final OnGestureStateChangedListener mListener; - private boolean mScrolling; - private boolean mIsInGesture; - - /** - * The View events are tracked on. - */ - private View mContentView; - - /** - * Notified when the gesture state changes. - */ - public interface OnGestureStateChangedListener { - /** - * Called when the value of isInGestureOrScroll() changes. - */ - public void onGestureStateChanged(); - } - - public WebContentsGestureStateTracker( - View contentView, WebContents webContents, OnGestureStateChangedListener listener) { - mListener = listener; - mGestureListenerManager = GestureListenerManager.fromWebContents(webContents); - mContentView = contentView; - mContentView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View view, MotionEvent event) { - final int eventAction = event.getActionMasked(); - final boolean oldState = isInGestureOrScroll(); - if (eventAction == MotionEvent.ACTION_DOWN - || eventAction == MotionEvent.ACTION_POINTER_DOWN) { - mIsInGesture = true; - } else if (eventAction == MotionEvent.ACTION_CANCEL - || eventAction == MotionEvent.ACTION_UP) { - mIsInGesture = false; - } - if (isInGestureOrScroll() != oldState) { - mListener.onGestureStateChanged(); - } - return false; - } - }); - - mGestureListener = new GestureStateListener() { - @Override - public void onFlingStartGesture( - int scrollOffsetY, int scrollExtentY, boolean isDirectionUp) { - onScrollingStateChanged(); - } - - @Override - public void onFlingEndGesture(int scrollOffsetY, int scrollExtentY) { - onScrollingStateChanged(); - } - - @Override - public void onScrollStarted( - int scrollOffsetY, int scrollExtentY, boolean isDirectionUp) { - onScrollingStateChanged(); - } - - @Override - public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { - onScrollingStateChanged(); - } - - private void onScrollingStateChanged() { - final boolean oldState = isInGestureOrScroll(); - mScrolling = mGestureListenerManager.isScrollInProgress(); - if (oldState != isInGestureOrScroll()) { - mListener.onGestureStateChanged(); - } - } - }; - mGestureListenerManager.addListener(mGestureListener); - } - - public void destroy() { - mGestureListenerManager.removeListener(mGestureListener); - mGestureListener = null; - mGestureListenerManager = null; - mContentView.setOnTouchListener(null); - } - - /** - * Returns true if the user has touched the target view, or is scrolling. - */ - public boolean isInGestureOrScroll() { - return mIsInGesture || mScrolling; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerAccessibilityUtil.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerAccessibilityUtil.java deleted file mode 100644 index bbf0f38..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerAccessibilityUtil.java +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.components.browser_ui.accessibility.FontSizePrefs; -import org.chromium.ui.accessibility.AccessibilityState; -import org.chromium.ui.util.AccessibilityUtil; - -/** - * Exposes information about the current accessibility state. - */ -public class WebLayerAccessibilityUtil extends AccessibilityUtil { - private static WebLayerAccessibilityUtil sInstance; - - public static WebLayerAccessibilityUtil get() { - if (sInstance == null) { - sInstance = new WebLayerAccessibilityUtil(); - AccessibilityState.addListener(sInstance); - } - return sInstance; - } - - private WebLayerAccessibilityUtil() {} - - public void onBrowserResumed(ProfileImpl profile) { - // When a browser is resumed the cached state may have be stale and needs to be - // recalculated. - FontSizePrefs.getInstance(profile).onSystemFontScaleChanged(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerActionModeCallback.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerActionModeCallback.java deleted file mode 100644 index 0ef6b94..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerActionModeCallback.java +++ /dev/null
@@ -1,135 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.SearchManager; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.graphics.Rect; -import android.os.RemoteException; -import android.view.ActionMode; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; - -import androidx.annotation.Nullable; - -import org.chromium.base.PackageManagerUtils; -import org.chromium.content_public.browser.ActionModeCallback; -import org.chromium.content_public.browser.ActionModeCallbackHelper; -import org.chromium.content_public.browser.SelectionPopupController; -import org.chromium.content_public.browser.WebContents; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.ActionModeItemType; -import org.chromium.weblayer_private.interfaces.ITabClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * A class that handles selection action mode for WebLayer. - */ -public final class WebLayerActionModeCallback extends ActionModeCallback { - private final ActionModeCallbackHelper mHelper; - // Can be null during init. - private @Nullable ITabClient mTabClient; - - // Bitfield of @ActionModeItemType values. - private int mActionModeOverride; - - // Convert from content ActionModeCallbackHelper.MENU_ITEM_* values to - // @ActionModeItemType values. - private static int contentToWebLayerType(int contentType) { - switch (contentType) { - case ActionModeCallbackHelper.MENU_ITEM_SHARE: - return ActionModeItemType.SHARE; - case ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH: - return ActionModeItemType.WEB_SEARCH; - case ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT: - case 0: - return 0; - default: - assert false; - return 0; - } - } - - public WebLayerActionModeCallback(WebContents webContents) { - mHelper = - SelectionPopupController.fromWebContents(webContents).getActionModeCallbackHelper(); - } - - public void setTabClient(ITabClient tabClient) { - mTabClient = tabClient; - } - - public void setOverride(int actionModeItemTypes) { - mActionModeOverride = actionModeItemTypes; - } - - @Override - public final boolean onCreateActionMode(ActionMode mode, Menu menu) { - int allowedActionModes = ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT - | ActionModeCallbackHelper.MENU_ITEM_SHARE; - if ((mActionModeOverride & ActionModeItemType.WEB_SEARCH) != 0 || isWebSearchAvailable()) { - allowedActionModes |= ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH; - } - mHelper.setAllowedMenuItems(allowedActionModes); - mHelper.onCreateActionMode(mode, menu); - return true; - } - - private boolean isWebSearchAvailable() { - Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); - intent.putExtra(SearchManager.EXTRA_NEW_SEARCH, true); - return PackageManagerUtils.canResolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); - } - - @Override - public final boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return mHelper.onPrepareActionMode(mode, menu); - } - - @Override - public final boolean onActionItemClicked(ActionMode mode, MenuItem item) { - int menuItemType = contentToWebLayerType(mHelper.getAllowedMenuItemIfAny(mode, item)); - if ((menuItemType & mActionModeOverride) == 0) { - return mHelper.onActionItemClicked(mode, item); - } - handleMenuItemClick(menuItemType); - mode.finish(); - return true; - } - - @Override - public boolean onDropdownItemClicked(int groupId, int id, @Nullable Intent intent, - @Nullable View.OnClickListener clickListener) { - int menuItemType = contentToWebLayerType(mHelper.getAllowedMenuItemIfAny(groupId, id)); - if ((menuItemType & mActionModeOverride) == 0) { - return mHelper.onDropdownItemClicked(groupId, id, intent, clickListener); - } - handleMenuItemClick(menuItemType); - mHelper.dismissMenu(); - return true; - } - - private void handleMenuItemClick(int menuItemType) { - assert WebLayerFactoryImpl.getClientMajorVersion() >= 88; - try { - mTabClient.onActionItemClicked( - menuItemType, ObjectWrapper.wrap(mHelper.getSelectedText())); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @Override - public final void onDestroyActionMode(ActionMode mode) { - mHelper.onDestroyActionMode(); - } - - @Override - public void onGetContentRect(ActionMode mode, View view, Rect outRect) { - mHelper.onGetContentRect(mode, view, outRect); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerExceptionFilter.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerExceptionFilter.java deleted file mode 100644 index ef0654d..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerExceptionFilter.java +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; - -/** - * A helper class to determine if an exception is relevant to WebLayer. Called if an uncaught - * exception is detected. - */ -@JNINamespace("weblayer") -public final class WebLayerExceptionFilter { - // The filename prefix used by Chromium proguarding, which we use to - // recognise stack frames that reference WebLayer. - private static final String CHROMIUM_PREFIX = "chromium-"; - - @CalledByNative - private static boolean stackTraceContainsWebLayerCode(Throwable t) { - for (StackTraceElement frame : t.getStackTrace()) { - if (frame.getClassName().startsWith("org.chromium.") - || (frame.getFileName() != null - && frame.getFileName().startsWith(CHROMIUM_PREFIX))) { - return true; - } - } - return false; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java deleted file mode 100644 index f2f51ce..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java +++ /dev/null
@@ -1,98 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.os.IBinder; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.build.annotations.UsedByReflection; -import org.chromium.components.version_info.VersionConstants; -import org.chromium.weblayer_private.interfaces.IWebLayer; -import org.chromium.weblayer_private.interfaces.IWebLayerFactory; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; -import org.chromium.weblayer_private.interfaces.WebLayerVersionConstants; - -/** - * Factory used to create WebLayer as well as verify compatibility. - * This is constructed by the client library using reflection. - */ -@UsedByReflection("WebLayer") -public final class WebLayerFactoryImpl extends IWebLayerFactory.Stub { - private static int sClientMajorVersion; - private static String sClientVersion; - - /** - * This function is called by the client using reflection. - * - * @param clientVersion The full version string the client was compiled from. - * @param clientMajorVersion The major version number the client was compiled from. This is also - * contained in clientVersion. - * @param clientWebLayerVersion The version from interfaces.WebLayerVersion the client was - * compiled with. - */ - @UsedByReflection("WebLayer") - public static IBinder create( - String clientVersion, int clientMajorVersion, int clientWebLayerVersion) { - return new WebLayerFactoryImpl(clientVersion, clientMajorVersion); - } - - private WebLayerFactoryImpl(String clientVersion, int clientMajorVersion) { - sClientMajorVersion = clientMajorVersion; - sClientVersion = clientVersion; - } - - /** - * Returns true if the client compiled with the specific version is compatible with this - * implementation. The client library calls this exactly once. - */ - @Override - public boolean isClientSupported() { - StrictModeWorkaround.apply(); - if (sClientMajorVersion < WebLayerVersionConstants.MIN_VERSION) { - return false; - } - int implMajorVersion = getImplementationMajorVersion(); - // While the client always calls this method, the most recently shipped product gets to - // decide compatibility. If we instead let the implementation always decide, then we would - // not be able to change the allowed skew of older implementations, even if the client could - // support it. - if (sClientMajorVersion > implMajorVersion) return true; - return implMajorVersion - sClientMajorVersion <= WebLayerVersionConstants.MAX_SKEW; - } - - /** - * Returns the major version of the implementation. - */ - @Override - public int getImplementationMajorVersion() { - StrictModeWorkaround.apply(); - return VersionConstants.PRODUCT_MAJOR_VERSION; - } - - @CalledByNative - public static int getClientMajorVersion() { - if (sClientMajorVersion == 0) { - throw new IllegalStateException( - "This should only be called once WebLayer is initialized"); - } - return sClientMajorVersion; - } - - /** - * Returns the full version string of the implementation. - */ - @Override - public String getImplementationVersion() { - StrictModeWorkaround.apply(); - return VersionConstants.PRODUCT_VERSION; - } - - @Override - public IWebLayer createWebLayer() { - StrictModeWorkaround.apply(); - assert isClientSupported(); - return new WebLayerImpl(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java deleted file mode 100644 index f6bf7bf..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java +++ /dev/null
@@ -1,966 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.annotation.SuppressLint; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.text.TextUtils; -import android.util.AndroidRuntimeException; -import android.util.SparseArray; -import android.webkit.ValueCallback; -import android.webkit.WebViewDelegate; -import android.webkit.WebViewFactory; - -import androidx.annotation.Nullable; -import androidx.core.content.FileProvider; - -import dalvik.system.DexFile; - -import org.chromium.base.BuildInfo; -import org.chromium.base.BundleUtils; -import org.chromium.base.CommandLine; -import org.chromium.base.ContentUriUtils; -import org.chromium.base.ContextUtils; -import org.chromium.base.FileUtils; -import org.chromium.base.Log; -import org.chromium.base.PathUtils; -import org.chromium.base.StrictModeContext; -import org.chromium.base.TraceEvent; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.base.library_loader.LibraryLoader; -import org.chromium.base.library_loader.LibraryProcessType; -import org.chromium.base.task.AsyncTask; -import org.chromium.base.task.BackgroundOnlyAsyncTask; -import org.chromium.base.task.PostTask; -import org.chromium.base.task.TaskTraits; -import org.chromium.build.annotations.DoNotInline; -import org.chromium.components.browser_ui.contacts_picker.ContactsPickerDialog; -import org.chromium.components.browser_ui.photo_picker.DecoderServiceHost; -import org.chromium.components.browser_ui.photo_picker.ImageDecoder; -import org.chromium.components.browser_ui.photo_picker.PhotoPickerDelegateBase; -import org.chromium.components.browser_ui.photo_picker.PhotoPickerDialog; -import org.chromium.components.browser_ui.share.ClipboardImageFileProvider; -import org.chromium.components.browser_ui.share.ShareImageFileUtils; -import org.chromium.components.component_updater.ComponentLoaderPolicyBridge; -import org.chromium.components.component_updater.EmbeddedComponentLoader; -import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory; -import org.chromium.components.payments.PaymentDetailsUpdateService; -import org.chromium.components.webapk.lib.client.ChromeWebApkHostSignature; -import org.chromium.components.webapk.lib.client.WebApkValidator; -import org.chromium.content_public.browser.BrowserStartupController; -import org.chromium.content_public.browser.ChildProcessCreationParams; -import org.chromium.content_public.browser.ChildProcessLauncherHelper; -import org.chromium.content_public.browser.ContactsPicker; -import org.chromium.content_public.browser.ContactsPickerListener; -import org.chromium.content_public.browser.DeviceUtils; -import org.chromium.content_public.browser.SelectionPopupController; -import org.chromium.net.NetworkChangeNotifier; -import org.chromium.ui.base.Clipboard; -import org.chromium.ui.base.PhotoPicker; -import org.chromium.ui.base.PhotoPickerListener; -import org.chromium.ui.base.ResourceBundle; -import org.chromium.ui.base.SelectFileDialog; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.IWebLayer; -import org.chromium.weblayer_private.interfaces.IWebLayerClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; -import org.chromium.weblayer_private.media.MediaRouterClientImpl; -import org.chromium.weblayer_private.media.MediaSessionManager; -import org.chromium.weblayer_private.media.MediaStreamManager; -import org.chromium.weblayer_private.metrics.MetricsServiceClient; -import org.chromium.weblayer_private.metrics.UmaUtils; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Root implementation class for WebLayer. - */ -@JNINamespace("weblayer") -public final class WebLayerImpl extends IWebLayer.Stub { - // TODO: should there be one tag for all this code? - private static final String TAG = "WebLayer"; - private static final String PRIVATE_DIRECTORY_SUFFIX = "weblayer"; - // Command line flags are only read in debug builds. - // WARNING: this file is written to by testing code in chrome (see - // "//chrome/test/chromedriver/chrome/device_manager.cc"). If you change this variable, update - // "device_manager.cc" too. If the command line file exists in the app's private files - // directory, it will be read from there, otherwise it will be read from - // PUBLIC_COMMAND_LINE_FILE. - private static final String COMMAND_LINE_FILE = "weblayer-command-line"; - private static final String PUBLIC_COMMAND_LINE_FILE = "/data/local/tmp/" + COMMAND_LINE_FILE; - // This metadata key, if defined, overrides the default behaviour of loading WebLayer from the - // current WebView implementation. This is only intended for testing, and does not enforce any - // signature requirements on the implementation, nor does it use the production code path to - // load the code. Do not set this in production APKs! - private static final String PACKAGE_MANIFEST_KEY = "org.chromium.weblayer.WebLayerPackage"; - // SharedPreferences key storing the versionCode of the most recently loaded WebLayer library. - public static final String PREF_LAST_VERSION_CODE = - "org.chromium.weblayer.last_version_code_used"; - - // The required package ID for WebLayer when loaded as a shared library, hardcoded in the - // resources. If this value changes make sure to change _SHARED_LIBRARY_HARDCODED_ID in - // //build/android/gyp/util/protoresources.py and WebViewChromiumFactoryProvider.java. - private static final int REQUIRED_PACKAGE_IDENTIFIER = 36; - - // 0 results in using the default value. - private static int sMaxNavigationsForInstanceState = 0; - - private final ProfileManager mProfileManager = new ProfileManager(); - - private boolean mInited; - private static IWebLayerClient sClient; - - // Whether WebView is running in process. Set in init(). - private boolean mIsWebViewCompatMode; - - private boolean mOnNativeLoadedCalled; - - private static class FileProviderHelper implements ContentUriUtils.FileProviderUtil { - // Keep this variable in sync with the value defined in AndroidManifest.xml. - private static final String API_AUTHORITY_SUFFIX = - ".org.chromium.weblayer.client.FileProvider"; - - @Override - public Uri getContentUriFromFile(File file) { - Context appContext = ContextUtils.getApplicationContext(); - return FileProvider.getUriForFile( - appContext, appContext.getPackageName() + API_AUTHORITY_SUFFIX, file); - } - } - - WebLayerImpl() {} - - @Override - public void loadAsync(IObjectWrapper appContextWrapper, IObjectWrapper remoteContextWrapper, - IObjectWrapper loadedCallbackWrapper) { - StrictModeWorkaround.apply(); - - Context appContext = ObjectWrapper.unwrap(appContextWrapper, Context.class); - Context remoteContext = ObjectWrapper.unwrap(remoteContextWrapper, Context.class); - init(appContext, remoteContext); - - final ValueCallback<Boolean> loadedCallback = (ValueCallback<Boolean>) ObjectWrapper.unwrap( - loadedCallbackWrapper, ValueCallback.class); - // WARNING: Ensure any method calls from this guard against the possibility of being called - // multiple times (see comment in loadSync()). - BrowserStartupController.getInstance().startBrowserProcessesAsync( - LibraryProcessType.PROCESS_WEBLAYER, - /* startGpu */ true, /* startMinimalBrowser */ false, - new BrowserStartupController.StartupCallback() { - @Override - public void onSuccess() { - onNativeLoaded(appContext); - loadedCallback.onReceiveValue(true); - } - @Override - public void onFailure() { - loadedCallback.onReceiveValue(false); - } - }); - } - - @Override - public void loadSync(IObjectWrapper appContextWrapper, IObjectWrapper remoteContextWrapper) { - StrictModeWorkaround.apply(); - - Context appContext = ObjectWrapper.unwrap(appContextWrapper, Context.class); - Context remoteContext = ObjectWrapper.unwrap(remoteContextWrapper, Context.class); - init(appContext, remoteContext); - - BrowserStartupController.getInstance().startBrowserProcessesSync( - LibraryProcessType.PROCESS_WEBLAYER, - /*singleProcess=*/false, /*startGpuProcess=*/true); - - onNativeLoaded(appContext); - // WARNING: loadAsync() may be in progress, and may call methods that this does as well. - // Ensure any method calls from this guard against the possibility of being called multiple - // times. - } - - private void onNativeLoaded(Context appContext) { - // This may be called multiple times, ensure processing only happens once. - if (mOnNativeLoadedCalled) return; - mOnNativeLoadedCalled = true; - - // TODO(swestphal): Move this earlier when it is not depending on native code being loaded. - ChildProcessLauncherHelper.warmUp(appContext, true); - - CrashReporterController.getInstance().notifyNativeInitialized(); - NetworkChangeNotifier.init(); - NetworkChangeNotifier.registerToReceiveNotificationsAlways(); - - // Native and variations has to be loaded before this. - loadComponents(); - - // This issues JNI calls which require native code to be loaded. - MetricsServiceClient.init(); - - WebLayerOriginVerificationScheduler.init(appContext.getPackageName(), - mProfileManager.getProfile(/* name= */ "", true), appContext); - - assert mInited; - WebLayerImplJni.get().setIsWebViewCompatMode(mIsWebViewCompatMode); - } - - private void init(Context appContext, Context remoteContext) { - if (mInited) { - return; - } - mInited = true; - - UmaUtils.recordMainEntryPointTime(); - - LibraryLoader.getInstance().setLibraryProcessType(LibraryProcessType.PROCESS_WEBLAYER); - - // The remote context will have a different class loader than WebLayerImpl here if we are in - // WebView compat mode, since WebView compat mode creates it's own class loader. The class - // loader from remoteContext will actually never be used, since - // ClassLoaderContextWrapperFactory will override the class loader, and all contexts used in - // WebLayer should come from ClassLoaderContextWrapperFactory. - mIsWebViewCompatMode = remoteContext != null - && !remoteContext.getClassLoader().equals(WebLayerImpl.class.getClassLoader()); - if (mIsWebViewCompatMode) { - notifyWebViewRunningInProcess(remoteContext.getClassLoader()); - } - - Context wrappedAppContext = minimalInitForContext(appContext, remoteContext); - - GmsBridge.getInstance().checkClientAppContext(wrappedAppContext); - - // Load library in the background since it may be expensive. - // TODO(crbug.com/1146438): Look into enabling relro sharing in browser process. It seems to - // crash when WebView is loaded in the same process. - new BackgroundOnlyAsyncTask<Void>() { - @Override - protected Void doInBackground() { - LibraryLoader.getInstance().loadNow(); - return null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - - PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo(); - - if (!CommandLine.isInitialized()) { - if (BuildInfo.isDebugAndroid()) { - // This disk read in the critical path is for development purposes only. - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - File localCommandLineFile = - new File(wrappedAppContext.getFilesDir(), COMMAND_LINE_FILE); - if (localCommandLineFile.exists()) { - CommandLine.initFromFile(localCommandLineFile.getPath()); - } else { - CommandLine.initFromFile(PUBLIC_COMMAND_LINE_FILE); - } - } - } else { - CommandLine.init(null); - } - } - - TraceEvent.maybeEnableEarlyTracing(/*readCommandLine=*/true); - TraceEvent.begin("WebLayer init"); - - WebApkValidator.init( - ChromeWebApkHostSignature.EXPECTED_SIGNATURE, ChromeWebApkHostSignature.PUBLIC_KEY); - - BuildInfo.setBrowserPackageInfo(packageInfo); - - SelectionPopupController.setMustUseWebContentsContext(); - SelectionPopupController.setShouldGetReadbackViewFromWindowAndroid(); - - ResourceBundle.setAvailablePakLocales(ProductConfig.LOCALES); - BundleUtils.setIsBundle(ProductConfig.IS_BUNDLE); - - setChildProcessCreationParams(wrappedAppContext, packageInfo.packageName); - - // Creating the Android shared preferences object causes I/O. - try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) { - SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); - deleteDataIfPackageDowngrade(prefs, packageInfo); - } - - DeviceUtils.addDeviceSpecificUserAgentSwitch(); - ContentUriUtils.setFileProviderUtil(new FileProviderHelper()); - - GmsBridge.getInstance().setSafeBrowsingHandler(); - GmsBridge.getInstance().initializeBuiltInPaymentApps(); - - MediaStreamManager.onWebLayerInit(); - WebLayerNotificationChannels.updateChannelsIfNecessary(); - - ContactsPicker.setContactsPickerDelegate( - (WindowAndroid windowAndroid, ContactsPickerListener listener, - boolean allowMultiple, boolean includeNames, boolean includeEmails, - boolean includeTel, boolean includeAddresses, boolean includeIcons, - String formattedOrigin) -> { - ContactsPickerDialog dialog = new ContactsPickerDialog(windowAndroid, - new ContactsPickerAdapter(windowAndroid), listener, allowMultiple, - includeNames, includeEmails, includeTel, includeAddresses, includeIcons, - formattedOrigin); - dialog.show(); - return dialog; - }); - - DecoderServiceHost.setIntentSupplier(() -> { return createImageDecoderServiceIntent(); }); - SelectFileDialog.setPhotoPickerDelegate(new PhotoPickerDelegateBase() { - @Override - public PhotoPicker showPhotoPicker(WindowAndroid windowAndroid, - PhotoPickerListener listener, boolean allowMultiple, List<String> mimeTypes) { - PhotoPickerDialog dialog = new PhotoPickerDialog(windowAndroid, - windowAndroid.getContext().get().getContentResolver(), listener, - allowMultiple, mimeTypes); - dialog.show(); - return dialog; - } - }); - - Clipboard.getInstance().setImageFileProvider(new ClipboardImageFileProvider()); - - // Clear previously shared images from disk in the background. - new BackgroundOnlyAsyncTask<Void>() { - @Override - protected Void doInBackground() { - ShareImageFileUtils.clearSharedImages(); - return null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - - performDexFixIfNecessary(packageInfo); - - TraceEvent.end("WebLayer init"); - } - - @Override - public IBrowser createBrowser(IObjectWrapper serviceContext, IObjectWrapper fragmentArgs) { - StrictModeWorkaround.apply(); - Bundle unwrappedFragmentArgs = ObjectWrapper.unwrap(fragmentArgs, Bundle.class); - Context unwrappedServiceContext = ObjectWrapper.unwrap(serviceContext, Context.class); - BrowserImpl browser = - new BrowserImpl(unwrappedServiceContext, mProfileManager, unwrappedFragmentArgs); - return browser; - } - - @Override - public IProfile getProfile(String profileName) { - StrictModeWorkaround.apply(); - boolean isIncognito = "".equals(profileName); - return mProfileManager.getProfile(profileName, isIncognito); - } - - @Override - public IProfile getIncognitoProfile(String profileName) { - StrictModeWorkaround.apply(); - return mProfileManager.getProfile(profileName, true); - } - - @Override - public void setRemoteDebuggingEnabled(boolean enabled) { - StrictModeWorkaround.apply(); - WebLayerImplJni.get().setRemoteDebuggingEnabled(enabled); - } - - @Override - public boolean isRemoteDebuggingEnabled() { - StrictModeWorkaround.apply(); - return WebLayerImplJni.get().isRemoteDebuggingEnabled(); - } - - @Override - public void onReceivedBroadcast(IObjectWrapper appContextWrapper, Intent intent) { - StrictModeWorkaround.apply(); - Context context = ObjectWrapper.unwrap(appContextWrapper, Context.class); - - if (IntentUtils.handleIntent(intent)) return; - - if (intent.getAction().startsWith(DownloadImpl.getIntentPrefix())) { - DownloadImpl.forwardIntent(context, intent, mProfileManager); - } - } - - @Override - public void onMediaSessionServiceStarted(IObjectWrapper sessionService, Intent intent) { - StrictModeWorkaround.apply(); - MediaSessionManager.serviceStarted( - ObjectWrapper.unwrap(sessionService, Service.class), intent); - } - - @Override - public void onMediaSessionServiceDestroyed() { - StrictModeWorkaround.apply(); - MediaSessionManager.serviceDestroyed(); - } - - @Override - public void onRemoteMediaServiceStarted(IObjectWrapper sessionService, Intent intent) { - StrictModeWorkaround.apply(); - MediaRouterClientImpl.serviceStarted( - ObjectWrapper.unwrap(sessionService, Service.class), intent); - } - - @Override - public void onRemoteMediaServiceDestroyed(int id) { - StrictModeWorkaround.apply(); - MediaRouterClientImpl.serviceDestroyed(id); - } - - @Override - public IBinder initializeImageDecoder(IObjectWrapper appContext, IObjectWrapper remoteContext) { - StrictModeWorkaround.apply(); - - assert ContextUtils.getApplicationContext() == null; - CommandLine.init(null); - minimalInitForContext(ObjectWrapper.unwrap(appContext, Context.class), - ObjectWrapper.unwrap(remoteContext, Context.class)); - LibraryLoader.getInstance().setLibraryProcessType( - LibraryProcessType.PROCESS_WEBLAYER_CHILD); - LibraryLoader.getInstance().ensureInitialized(); - - ImageDecoder imageDecoder = new ImageDecoder(); - imageDecoder.initializeSandbox(); - return imageDecoder; - } - - @Override - public IObjectWrapper createGooglePayDataCallbacksService() { - StrictModeWorkaround.apply(); - return ObjectWrapper.wrap(GmsBridge.getInstance().createGooglePayDataCallbacksService()); - } - - @Override - public IObjectWrapper createPaymentDetailsUpdateService() { - StrictModeWorkaround.apply(); - return ObjectWrapper.wrap(new PaymentDetailsUpdateService()); - } - - @Override - public void enumerateAllProfileNames(IObjectWrapper valueCallback) { - StrictModeWorkaround.apply(); - final ValueCallback<String[]> callback = - (ValueCallback<String[]>) ObjectWrapper.unwrap(valueCallback, ValueCallback.class); - ProfileImpl.enumerateAllProfileNames(callback); - } - - @Override - public void setClient(IWebLayerClient client) { - StrictModeWorkaround.apply(); - sClient = client; - } - - @Override - public String getUserAgentString() { - StrictModeWorkaround.apply(); - return WebLayerImplJni.get().getUserAgentString(); - } - - @Override - public void registerExternalExperimentIDs(String trialName, int[] experimentIDs) { - StrictModeWorkaround.apply(); - WebLayerImplJni.get().registerExternalExperimentIDs(experimentIDs); - } - - @Override - public String getXClientDataHeader() { - StrictModeWorkaround.apply(); - return WebLayerImplJni.get().getXClientDataHeader(); - } - - @Override - public IObjectWrapper getApplicationContext() { - StrictModeWorkaround.apply(); - return ObjectWrapper.wrap(ContextUtils.getApplicationContext()); - } - - public static int getMaxNavigationsPerTabForInstanceState() { - try { - return (WebLayerFactoryImpl.getClientMajorVersion() >= 98) - ? sClient.getMaxNavigationsPerTabForInstanceState() - : 0; - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static Intent createIntent() { - if (sClient == null) { - throw new IllegalStateException("WebLayer should have been initialized already."); - } - - try { - return sClient.createIntent(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static Intent createMediaSessionServiceIntent() { - if (sClient == null) { - throw new IllegalStateException("WebLayer should have been initialized already."); - } - - try { - return sClient.createMediaSessionServiceIntent(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static Intent createImageDecoderServiceIntent() { - if (sClient == null) { - throw new IllegalStateException("WebLayer should have been initialized already."); - } - - try { - return sClient.createImageDecoderServiceIntent(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static int getMediaSessionNotificationId() { - if (sClient == null) { - throw new IllegalStateException("WebLayer should have been initialized already."); - } - - try { - return sClient.getMediaSessionNotificationId(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static Intent createRemoteMediaServiceIntent() { - if (sClient == null) { - throw new IllegalStateException("WebLayer should have been initialized already."); - } - - try { - return sClient.createRemoteMediaServiceIntent(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static int getPresentationApiNotificationId() { - if (sClient == null) { - throw new IllegalStateException("WebLayer should have been initialized already."); - } - - try { - return sClient.getPresentationApiNotificationId(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static int getRemotePlaybackApiNotificationId() { - if (sClient == null) { - throw new IllegalStateException("WebLayer should have been initialized already."); - } - - try { - return sClient.getRemotePlaybackApiNotificationId(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static String getClientApplicationName() { - Context context = ContextUtils.getApplicationContext(); - return new StringBuilder() - .append(context.getPackageManager().getApplicationLabel( - context.getApplicationInfo())) - .toString(); - } - - /** - * Converts the given id into a resource ID that can be shown in system UI, such as - * notifications. - */ - public static int getResourceIdForSystemUi(int id) { - if (isAndroidResource(id)) { - return id; - } - - Context context = ContextUtils.getApplicationContext(); - try { - // String may be missing translations, since they are loaded at a different package ID - // by default in standalone WebView. - assert !context.getResources().getResourceTypeName(id).equals("string"); - } catch (Resources.NotFoundException e) { - } - id &= 0x00ffffff; - id |= (0x01000000 - * getPackageId(context, WebViewFactory.getLoadedPackageInfo().packageName)); - return id; - } - - /** Returns whether this ID is from the android system package. */ - public static boolean isAndroidResource(int id) { - try { - return ContextUtils.getApplicationContext() - .getResources() - .getResourcePackageName(id) - .equals("android"); - } catch (Resources.NotFoundException e) { - return false; - } - } - - private static Context minimalInitForContext(Context appContext, Context remoteContext) { - if (ContextUtils.getApplicationContext() != null) { - return ContextUtils.getApplicationContext(); - } - - assert remoteContext != null; - Context lightContext = createContextForMode(remoteContext, Configuration.UI_MODE_NIGHT_NO); - Context darkContext = createContextForMode(remoteContext, Configuration.UI_MODE_NIGHT_YES); - ClassLoaderContextWrapperFactory.setLightDarkResourceOverrideContext( - lightContext, darkContext); - - int lightPackageId = forceCorrectPackageId(lightContext); - int darkPackageId = forceCorrectPackageId(darkContext); - assert lightPackageId == darkPackageId; - - // TODO: The call to onResourcesLoaded() can be slow, we may need to parallelize this with - // other expensive startup tasks. - R.onResourcesLoaded(lightPackageId); - - // Wrap the app context so that it can be used to load WebLayer implementation classes. - appContext = ClassLoaderContextWrapperFactory.get(appContext); - ContextUtils.initApplicationContext(appContext); - PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DIRECTORY_SUFFIX, PRIVATE_DIRECTORY_SUFFIX); - return appContext; - } - - /** Forces the correct package ID or dies with a runtime exception. */ - private static int forceCorrectPackageId(Context remoteContext) { - int packageId = getPackageId(remoteContext, remoteContext.getPackageName()); - // This is using app_as_shared_lib, no change needed. - if (packageId >= 0x7f) { - return packageId; - } - - if (packageId > REQUIRED_PACKAGE_IDENTIFIER) { - throw new AndroidRuntimeException( - "WebLayer can't be used with other shared libraries. Package ID: " + packageId - + ", Loaded packages: " + getLoadedPackageNames(remoteContext)); - } - - forceAddAssetPaths(remoteContext, packageId); - - return REQUIRED_PACKAGE_IDENTIFIER; - } - - /** Forces adding entries to the package identifiers array until we hit the required ID. */ - private static void forceAddAssetPaths(Context remoteContext, int packageId) { - try { - Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class); - String path = remoteContext.getApplicationInfo().sourceDir; - // Add enough paths to make sure we reach the required ID. - for (int i = packageId; i < REQUIRED_PACKAGE_IDENTIFIER; i++) { - // Change the path to ensure the asset path is re-added and grabs a new package ID. - path = "/." + path; - addAssetPath.invoke(remoteContext.getAssets(), path); - } - } catch (ReflectiveOperationException e) { - throw new AndroidRuntimeException(e); - } - } - - /** - * Returns the package ID to use when calling R.onResourcesLoaded(). - */ - private static int getPackageId(Context appContext, String implPackageName) { - try { - Constructor<WebViewDelegate> constructor = - WebViewDelegate.class.getDeclaredConstructor(); - constructor.setAccessible(true); - WebViewDelegate delegate = constructor.newInstance(); - return delegate.getPackageId(appContext.getResources(), implPackageName); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - /** Gets a string with all the loaded package names in this context. */ - private static String getLoadedPackageNames(Context appContext) { - try { - Method getAssignedPackageIdentifiers = - AssetManager.class.getMethod("getAssignedPackageIdentifiers"); - SparseArray<String> packageIdentifiers = - (SparseArray) getAssignedPackageIdentifiers.invoke( - appContext.getResources().getAssets()); - List<String> packageNames = new ArrayList<>(); - for (int i = 0; i < packageIdentifiers.size(); i++) { - String name = packageIdentifiers.valueAt(i); - int key = packageIdentifiers.keyAt(i); - // This is the android package. - if (key == 1) { - continue; - } - - // Make sure this doesn't look like a URL so it doesn't get removed from crashes. - packageNames.add(name.replace(".", "_") + " -> " + key); - } - return TextUtils.join(",", packageNames); - } catch (ReflectiveOperationException e) { - return "unknown"; - } - } - - private void setChildProcessCreationParams(Context appContext, String implPackageName) { - final boolean bindToCaller = true; - final boolean ignoreVisibilityForImportance = false; - final String privilegedServicesPackageName = appContext.getPackageName(); - final String privilegedServicesName = - "org.chromium.weblayer.ChildProcessService$Privileged"; - - String sandboxedServicesPackageName = appContext.getPackageName(); - String sandboxedServicesName = "org.chromium.weblayer.ChildProcessService$Sandboxed"; - boolean isExternalService = false; - boolean loadedFromWebView = wasLoadedFromWebView(appContext); - if (loadedFromWebView && supportsBindingToWebViewService(appContext, implPackageName)) { - // When loading from a WebView implementation, use WebView's declared external services - // as our renderers. This means on O+ we benefit from the webview zygote process, and on - // other versions we ensure the client app doesn't slow down isolated process startup. - // We still need to use the client's privileged services, as only isolated services can - // be external. - isExternalService = true; - sandboxedServicesPackageName = implPackageName; - sandboxedServicesName = null; - } - - ChildProcessCreationParams.set(privilegedServicesPackageName, privilegedServicesName, - sandboxedServicesPackageName, sandboxedServicesName, isExternalService, - LibraryProcessType.PROCESS_WEBLAYER_CHILD, bindToCaller, - ignoreVisibilityForImportance); - } - - private static boolean supportsBindingToWebViewService(Context context, String packageName) { - // Android N has issues with WebView with the non-system user. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - try { - PackageInfo packageInfo = - context.getPackageManager().getPackageInfo(packageName, 0); - // Package may be disabled for non-system users. - if (!packageInfo.applicationInfo.enabled) { - return false; - } - } catch (PackageManager.NameNotFoundException e) { - // Package may be uninstalled for non-system users. - return false; - } - } - return true; - } - - private static boolean wasLoadedFromWebView(Context appContext) { - try { - Bundle metaData = appContext.getPackageManager() - .getApplicationInfo(appContext.getPackageName(), - PackageManager.GET_META_DATA) - .metaData; - if (metaData != null && metaData.getString(PACKAGE_MANIFEST_KEY) != null) { - return false; - } - return true; - } catch (PackageManager.NameNotFoundException e) { - // This would indicate the client app doesn't exist; - // just return true as there's nothing sensible to do here. - return true; - } - } - - private static void deleteDataIfPackageDowngrade( - SharedPreferences prefs, PackageInfo packageInfo) { - int previousVersion = prefs.getInt(PREF_LAST_VERSION_CODE, 0); - int currentVersion = packageInfo.versionCode; - if (getBranchFromVersionCode(currentVersion) < getBranchFromVersionCode(previousVersion)) { - // WebLayer was downgraded since the last run. Delete the data and cache directories. - File dataDir = new File(PathUtils.getDataDirectory()); - Log.i(TAG, - "WebLayer package downgraded from " + previousVersion + " to " + currentVersion - + "; deleting contents of " + dataDir); - deleteDirectoryContents(dataDir); - } - if (previousVersion != currentVersion) { - prefs.edit().putInt(PREF_LAST_VERSION_CODE, currentVersion).apply(); - } - } - - /** - * Chromium versionCodes follow the scheme "BBBBPPPAX": - * BBBB: 4 digit branch number. It monotonically increases over time. - * PPP: Patch number in the branch. It is padded with zeroes to the left. These three digits - * may change their meaning in the future. - * A: Architecture digit. - * X: A digit to differentiate APKs for other reasons. - * - * @return The branch number of versionCode. - */ - private static int getBranchFromVersionCode(int versionCode) { - return versionCode / 1_000_00; - } - - private static void deleteDirectoryContents(File directory) { - File[] files = directory.listFiles(); - if (files == null) { - return; - } - for (File file : files) { - if (!FileUtils.recursivelyDeleteFile(file, FileUtils.DELETE_ALL)) { - Log.w(TAG, "Failed to delete " + file); - } - } - } - - private static void notifyWebViewRunningInProcess(ClassLoader webViewClassLoader) { - // TODO(crbug.com/1112001): Investigate why loading classes causes strict mode - // violations in some situations. - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - Class<?> webViewChromiumFactoryProviderClass = - Class.forName("com.android.webview.chromium.WebViewChromiumFactoryProvider", - true, webViewClassLoader); - Method setter = webViewChromiumFactoryProviderClass.getDeclaredMethod( - "setWebLayerRunningInSameProcess"); - setter.invoke(null); - } catch (Exception e) { - Log.w(TAG, "Unable to notify WebView running in process."); - } - } - - @SuppressLint("DiscouragedPrivateApi") - private static Context createContextForMode(Context remoteContext, int uiMode) { - Configuration configuration = new Configuration(); - configuration.uiMode = uiMode; - Context context = remoteContext.createConfigurationContext(configuration); - // DrawableInflater uses the ClassLoader from the Resources object. We need to make sure - // this ClassLoader is correct. See crbug.com/1287000 and crbug.com/1293849 for more - // details. - try { - Field classLoaderField = Resources.class.getDeclaredField("mClassLoader"); - classLoaderField.setAccessible(true); - classLoaderField.set(context.getResources(), WebLayerImpl.class.getClassLoader()); - } catch (ReflectiveOperationException e) { - Log.e(TAG, "Error setting Resources ClassLoader.", e); - } - return context; - } - - @CalledByNative - @Nullable - private static String getEmbedderName() { - return getClientApplicationName(); - } - - /* - * Android O MR1 has a bug where bg-dexopt-job will break optimized dex files for isolated - * splits. This leads to *very* slow startup on those devices. To mitigate this, we attempt - * to force a dex compile if necessary. - */ - private static void performDexFixIfNecessary(PackageInfo packageInfo) { - if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) { - return; - } - - PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> { - ApplicationInfo appInfo = packageInfo.applicationInfo; - String[] splitNames = appInfo.splitNames; - if (splitNames == null) { - return; - } - - for (int i = 0; i < splitNames.length; i++) { - String splitName = splitNames[i]; - // WebLayer depends on the "weblayer" split and "chrome" split (if running in - // Monochrome). - if (!splitName.equals("chrome") && !splitName.equals("weblayer")) { - continue; - } - String splitDir = appInfo.splitSourceDirs[i]; - try { - if (DexFile.isDexOptNeeded(splitDir)) { - String cmd = String.format("cmd package compile -r shared --split %s %s", - new File(splitDir).getName(), packageInfo.packageName); - Runtime.getRuntime().exec(cmd); - } - } catch (IOException e) { - Log.e(TAG, "Error fixing dex files.", e); - } - } - }); - } - - /** - * Load components files from {@link - * org.chromium.android_webview.services.ComponentsProviderService}. - */ - private static void loadComponents() { - ComponentLoaderPolicyBridge[] componentPolicies = - WebLayerImplJni.get().getComponentLoaderPolicies(); - // Don't connect to the service if there are no components to load. - if (componentPolicies.length == 0) { - return; - } - final Intent intent = new Intent(); - intent.setClassName(getWebViewFactoryPackageName(), - EmbeddedComponentLoader.AW_COMPONENTS_PROVIDER_SERVICE); - new EmbeddedComponentLoader(Arrays.asList(componentPolicies)).connect(intent); - } - - /** - * WebViewFactory is not a public android API so R8 is unable to compute its - * API level. This causes R8 to not be able to inline WebLayerImplJni#get - * into WebLayerImpl#loadComponents. - - * References to WebViewFactory are in a separate method to avoid this issue - * and allow WebLayerImplJni#get to be inlined into WebLayerImpl#loadComponents. - * @DoNotInline is to avoid any similar inlining issues whenever this method - * is referenced. - */ - @DoNotInline - private static String getWebViewFactoryPackageName() { - return WebViewFactory.getLoadedPackageInfo().packageName; - } - - @NativeMethods - interface Natives { - void setRemoteDebuggingEnabled(boolean enabled); - boolean isRemoteDebuggingEnabled(); - void setIsWebViewCompatMode(boolean value); - String getUserAgentString(); - void registerExternalExperimentIDs(int[] experimentIDs); - String getXClientDataHeader(); - ComponentLoaderPolicyBridge[] getComponentLoaderPolicies(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationChannels.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationChannels.java deleted file mode 100644 index d9bb590..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationChannels.java +++ /dev/null
@@ -1,174 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.NotificationManager; -import android.content.SharedPreferences; -import android.os.Build; - -import androidx.annotation.RequiresApi; -import androidx.annotation.StringDef; - -import org.chromium.base.ContextUtils; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; -import org.chromium.components.browser_ui.notifications.channels.ChannelDefinitions; -import org.chromium.components.browser_ui.notifications.channels.ChannelDefinitions.PredefinedChannel; -import org.chromium.components.browser_ui.notifications.channels.ChannelsInitializer; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** Defines notification channels for WebLayer. */ -@RequiresApi(Build.VERSION_CODES.O) -public class WebLayerNotificationChannels extends ChannelDefinitions { - /** - * Version number identifying the current set of channels. This must be incremented whenever the - * set of channels returned by {@link #getStartupChannelIds()} or {@link #getLegacyChannelIds()} - * changes. - */ - static final int sChannelsVersion = 0; - static final String sChannelsVersionKey = "org.chromium.weblayer.notification_channels_version"; - - private static class LazyHolder { - private static WebLayerNotificationChannels sInstance = new WebLayerNotificationChannels(); - } - - public static WebLayerNotificationChannels getInstance() { - return LazyHolder.sInstance; - } - - private WebLayerNotificationChannels() {} - - /** - * To define a new channel, add the channel ID to this StringDef and add a new entry to - * PredefinedChannels.MAP below with the appropriate channel parameters. To remove an existing - * channel, remove the ID from this StringDef, remove its entry from Predefined Channels.MAP, - * and add it to the return value of {@link #getLegacyChannelIds()}. - */ - @StringDef({ChannelId.ACTIVE_DOWNLOADS, ChannelId.COMPLETED_DOWNLOADS, ChannelId.MEDIA_PLAYBACK, - ChannelId.WEBRTC_CAM_AND_MIC}) - @Retention(RetentionPolicy.SOURCE) - public @interface ChannelId { - String ACTIVE_DOWNLOADS = "org.chromium.weblayer.active_downloads"; - String COMPLETED_DOWNLOADS = "org.chromium.weblayer.completed_downloads"; - String MEDIA_PLAYBACK = "org.chromium.weblayer.media_playback"; - String WEBRTC_CAM_AND_MIC = "org.chromium.weblayer.webrtc_cam_and_mic"; - } - - @StringDef({ChannelGroupId.WEBLAYER}) - @Retention(RetentionPolicy.SOURCE) - public @interface ChannelGroupId { - String WEBLAYER = "org.chromium.weblayer"; - } - - // Map defined in static inner class so it's only initialized lazily. - private static class PredefinedChannels { - static final Map<String, PredefinedChannel> MAP; - - static { - Map<String, PredefinedChannel> map = new HashMap<>(); - map.put(ChannelId.ACTIVE_DOWNLOADS, - PredefinedChannel.create(ChannelId.ACTIVE_DOWNLOADS, - R.string.notification_category_downloads, - NotificationManager.IMPORTANCE_LOW, ChannelGroupId.WEBLAYER)); - map.put(ChannelId.COMPLETED_DOWNLOADS, - PredefinedChannel.create(ChannelId.COMPLETED_DOWNLOADS, - R.string.notification_category_completed_downloads, - NotificationManager.IMPORTANCE_LOW, ChannelGroupId.WEBLAYER)); - map.put(ChannelId.MEDIA_PLAYBACK, - PredefinedChannel.create(ChannelId.MEDIA_PLAYBACK, - R.string.notification_category_media_playback, - NotificationManager.IMPORTANCE_LOW, ChannelGroupId.WEBLAYER)); - map.put(ChannelId.WEBRTC_CAM_AND_MIC, - PredefinedChannel.create(ChannelId.WEBRTC_CAM_AND_MIC, - R.string.notification_category_webrtc_cam_and_mic, - NotificationManager.IMPORTANCE_LOW, ChannelGroupId.WEBLAYER)); - MAP = Collections.unmodifiableMap(map); - } - } - - // Map defined in static inner class so it's only initialized lazily. - private static class PredefinedChannelGroups { - static final Map<String, PredefinedChannelGroup> MAP; - static { - Map<String, PredefinedChannelGroup> map = new HashMap<>(); - map.put(ChannelGroupId.WEBLAYER, - new PredefinedChannelGroup(ChannelGroupId.WEBLAYER, - R.string.weblayer_notification_channel_group_name)); - MAP = Collections.unmodifiableMap(map); - } - } - - @Override - public Set<String> getAllChannelGroupIds() { - return PredefinedChannelGroups.MAP.keySet(); - } - - @Override - public Set<String> getAllChannelIds() { - return PredefinedChannels.MAP.keySet(); - } - - @Override - public Set<String> getStartupChannelIds() { - return Collections.emptySet(); - } - - @Override - public List<String> getLegacyChannelIds() { - return Collections.emptyList(); - } - - @Override - public PredefinedChannelGroup getChannelGroup(@ChannelGroupId String groupId) { - return PredefinedChannelGroups.MAP.get(groupId); - } - - @Override - public PredefinedChannel getChannelFromId(@ChannelId String channelId) { - return PredefinedChannels.MAP.get(channelId); - } - - /** - * Updates the user-facing channel names after a locale switch. - */ - public static void onLocaleChanged() { - if (!isAtLeastO()) return; - - getChannelsInitializer().updateLocale(ContextUtils.getApplicationContext().getResources()); - } - - /** - * Updates the registered channels based on {@link sChannelsVersion}. - */ - public static void updateChannelsIfNecessary() { - if (!isAtLeastO()) return; - - SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); - if (prefs.getInt(sChannelsVersionKey, -1) == sChannelsVersion) return; - - ChannelsInitializer initializer = getChannelsInitializer(); - initializer.deleteLegacyChannels(); - initializer.initializeStartupChannels(); - prefs.edit().putInt(sChannelsVersionKey, sChannelsVersion).apply(); - } - - private static boolean isAtLeastO() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; - } - - private static ChannelsInitializer getChannelsInitializer() { - assert isAtLeastO(); - - return new ChannelsInitializer( - new NotificationManagerProxyImpl(ContextUtils.getApplicationContext()), - getInstance(), ContextUtils.getApplicationContext().getResources()); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java deleted file mode 100644 index 2ebd28d..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.graphics.drawable.Icon; -import android.webkit.WebViewFactory; - -import androidx.annotation.NonNull; - -import org.chromium.base.ContextUtils; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; -import org.chromium.components.browser_ui.notifications.NotificationMetadata; -import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder; -import org.chromium.components.browser_ui.notifications.NotificationWrapperStandardBuilder; -import org.chromium.components.browser_ui.notifications.channels.ChannelsInitializer; - -/** A notification builder for WebLayer which has extra logic to make icons work correctly. */ -public final class WebLayerNotificationWrapperBuilder extends NotificationWrapperStandardBuilder { - /** Creates a notification builder. */ - public static WebLayerNotificationWrapperBuilder create( - @WebLayerNotificationChannels.ChannelId String channelId, - @NonNull NotificationMetadata metadata) { - Context appContext = ContextUtils.getApplicationContext(); - ChannelsInitializer initializer = - new ChannelsInitializer(new NotificationManagerProxyImpl(appContext), - WebLayerNotificationChannels.getInstance(), appContext.getResources()); - return new WebLayerNotificationWrapperBuilder(appContext, channelId, initializer, metadata); - } - - private WebLayerNotificationWrapperBuilder(Context context, String channelId, - ChannelsInitializer channelsInitializer, NotificationMetadata metadata) { - super(context, channelId, channelsInitializer, metadata); - } - - @Override - public NotificationWrapperBuilder setSmallIcon(int icon) { - if (WebLayerImpl.isAndroidResource(icon)) { - super.setSmallIcon(icon); - } else { - super.setSmallIcon(createIcon(icon)); - } - return this; - } - - @Override - @SuppressWarnings("deprecation") - public NotificationWrapperBuilder addAction( - int icon, CharSequence title, PendingIntent intent) { - if (WebLayerImpl.isAndroidResource(icon)) { - super.addAction(icon, title, intent); - } else { - super.addAction( - new Notification.Action.Builder(createIcon(icon), title, intent).build()); - } - return this; - } - - private Icon createIcon(int resId) { - return Icon.createWithResource(WebViewFactory.getLoadedPackageInfo().packageName, - WebLayerImpl.getResourceIdForSystemUi(resId)); - } - - /** - * Finds a reasonable replacement for the given app-defined resource from among stock android - * resources. This is useful when {@link Icon} is not available. - */ - private int getFallbackAndroidResource(int appResourceId) { - if (appResourceId == R.drawable.ic_play_arrow_white_24dp) { - return android.R.drawable.ic_media_play; - } - if (appResourceId == R.drawable.ic_pause_white_24dp) { - return android.R.drawable.ic_media_pause; - } - if (appResourceId == R.drawable.ic_stop_white_24dp) { - // There's no ic_media_stop. This standin is at least a square. In practice this - // shouldn't ever come up as stop is only used in (Chrome) cast notifications. - return android.R.drawable.checkbox_off_background; - } - if (appResourceId == R.drawable.ic_skip_previous_white_24dp) { - return android.R.drawable.ic_media_previous; - } - if (appResourceId == R.drawable.ic_skip_next_white_24dp) { - return android.R.drawable.ic_media_next; - } - if (appResourceId == R.drawable.ic_fast_forward_white_24dp) { - return android.R.drawable.ic_media_ff; - } - if (appResourceId == R.drawable.ic_fast_rewind_white_24dp) { - return android.R.drawable.ic_media_rew; - } - if (appResourceId == R.drawable.audio_playing) { - return android.R.drawable.ic_lock_silent_mode_off; - } - - return android.R.drawable.radiobutton_on_background; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerificationScheduler.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerificationScheduler.java deleted file mode 100644 index c937b3c8..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerificationScheduler.java +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; - -import org.chromium.base.Callback; -import org.chromium.base.ThreadUtils; -import org.chromium.components.content_relationship_verification.OriginVerificationScheduler; -import org.chromium.components.content_relationship_verification.OriginVerifier; -import org.chromium.components.content_relationship_verification.OriginVerifierHelper; -import org.chromium.components.embedder_support.util.Origin; -import org.chromium.content_public.browser.BrowserContextHandle; - -import java.util.Set; - -/** - * Singleton. - * WebLayerOriginVerificationScheduler provides a WebLayer specific implementation of {@link - * OriginVerificationScheduler}. - * - * Call {@link WebLayerOriginVerificationScheduler#init} to initialize the statement list and call - * {@link WebLayerOriginVerificationScheduler#verify} to perform an origin validation. - */ -public class WebLayerOriginVerificationScheduler extends OriginVerificationScheduler { - private static final String TAG = "WLOriginVerification"; - - private static WebLayerOriginVerificationScheduler sInstance; - - private WebLayerOriginVerifier mOriginVerifier; - - private WebLayerOriginVerificationScheduler( - WebLayerOriginVerifier originVerifier, Set<Origin> pendingOrigins) { - super(originVerifier, pendingOrigins); - mOriginVerifier = originVerifier; - } - - /** - * Initializes the WebLayerOriginVerificationScheduler. - * This should be called exactly only once as it parses the AndroidManifest and statement list. - * - * @param packageName the package name of the host application. - * @param profile the profile to use for the simpleUrlLoader to download the asset links file. - * @param context a context associated with an Activity/Service to load resources. - */ - static void init(String packageName, BrowserContextHandle profile, Context context) { - ThreadUtils.assertOnUiThread(); - assert sInstance - == null : "`init(String packageName, Context context)` must only be called once"; - - sInstance = new WebLayerOriginVerificationScheduler( - new WebLayerOriginVerifier(packageName, OriginVerifier.HANDLE_ALL_URLS, profile, - WebLayerVerificationResultStore.getInstance()), - OriginVerifierHelper.getClaimedOriginsFromManifest(packageName, context)); - } - - static WebLayerOriginVerificationScheduler getInstance() { - assert sInstance != null : "Call to `init(String packageName, Context context)` missing"; - - return sInstance; - } - - @Override - public void verify(String url, Callback<Boolean> callback) { - if (mOriginVerifier.skipOriginVerification()) { - callback.onResult(true); - return; - } - super.verify(url, callback); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerifier.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerifier.java deleted file mode 100644 index 04709e7..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerifier.java +++ /dev/null
@@ -1,134 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.Bundle; - -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.ContextUtils; -import org.chromium.components.content_relationship_verification.OriginVerifier; -import org.chromium.components.content_relationship_verification.Relationship; -import org.chromium.components.embedder_support.util.Origin; -import org.chromium.components.embedder_support.util.UrlConstants; -import org.chromium.content_public.browser.BrowserContextHandle; - -import java.util.List; -import java.util.Locale; - -/** - * WebLayerOriginVerifier performs OriginVerifications for Weblayer. - * It uses the WebLayerVerificationResultStore to cache validations. - */ -public class WebLayerOriginVerifier extends OriginVerifier { - private static final String METADATA_SKIP_ORIGIN_VERIFICATION_KEY = - "org.chromium.weblayer.skipOriginVerification"; - private static final String METADATA_STRICT_LOCALHOST_VERIFICATION_KEY = - "org.chromium.weblayer.strictLocalhostVerification"; - private final boolean mSkipOriginVerification = getSkipOriginVerificationFromManifest(); - private final boolean mStrictLocalhostVerification = - getStrictLocalhostVerificationFromManifest(); - - /** - * Main constructor. - * Use {@link WebLayerOriginVerifier#start}. - * @param packageName The package for the Android application for verification. - * @param relationship Digital Asset Links relationship to use during verification. - * @param profile profile to retrieve the browser context for creating the url - * loader factory. - * @param verificationResultStore The {@link ChromeVerificationResultStore} for persisting - * results. - * - */ - public WebLayerOriginVerifier(String packageName, String relationship, - BrowserContextHandle profile, - @Nullable WebLayerVerificationResultStore verificationResultStore) { - super(packageName, relationship, null, profile, verificationResultStore); - } - - @Override - public boolean isAllowlisted(String packageName, Origin origin, String relation) { - String host = origin.uri().getHost(); - - if (UrlConstants.LOCALHOST.equals(host.toLowerCase(Locale.US))) { - return !mStrictLocalhostVerification; - } - - return false; - } - - @Override - public boolean wasPreviouslyVerified(Origin origin) { - return wasPreviouslyVerified(mPackageName, mSignatureFingerprints, origin, mRelation); - } - - /** - * Returns whether an origin is first-party relative to a given package name. - * - * This only returns data from previously cached relations, and does not trigger an asynchronous - * validation. - * - * @param packageName The package name. - * @param signatureFingerprint The signatures of the package. - * @param origin The origin to verify. - * @param relation The Digital Asset Links relation to verify for. - */ - private static boolean wasPreviouslyVerified(String packageName, - List<String> signatureFingerprints, Origin origin, String relation) { - WebLayerVerificationResultStore resultStore = WebLayerVerificationResultStore.getInstance(); - return resultStore.shouldOverride(packageName, origin, relation) - || resultStore.isRelationshipSaved( - new Relationship(packageName, signatureFingerprints, origin, relation)); - } - - // TODO(swestphal): Only for testing during development, remove again eventually. - boolean skipOriginVerification() { - return mSkipOriginVerification; - } - - private boolean getSkipOriginVerificationFromManifest() { - try { - Context context = ContextUtils.getApplicationContext(); - Bundle metaData = context.getPackageManager() - .getApplicationInfo(context.getPackageName(), - PackageManager.GET_META_DATA) - .metaData; - if (metaData != null) { - return metaData.getBoolean(METADATA_SKIP_ORIGIN_VERIFICATION_KEY); - } - } catch (PackageManager.NameNotFoundException e) { - } - return false; - } - - @VisibleForTesting - boolean getStrictLocalhostVerificationFromManifest() { - try { - Context context = ContextUtils.getApplicationContext(); - Bundle metaData = context.getPackageManager() - .getApplicationInfo(context.getPackageName(), - PackageManager.GET_META_DATA) - .metaData; - if (metaData != null) { - return metaData.getBoolean(METADATA_STRICT_LOCALHOST_VERIFICATION_KEY); - } - } catch (PackageManager.NameNotFoundException e) { - } - return false; - } - - @Override - public void recordResultMetrics(OriginVerifier.VerifierResult result) { - // TODO(swestphal): Implement UMA logging. - } - - @Override - public void recordVerificationTimeMetrics(long duration, boolean online) { - // TODO(swestphal): Implement UMA logging. - } -} \ No newline at end of file
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerifierTest.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerifierTest.java deleted file mode 100644 index a73b234..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerOriginVerifierTest.java +++ /dev/null
@@ -1,231 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import static org.robolectric.Shadows.shadowOf; - -import android.os.Process; - -import androidx.test.core.app.ApplicationProvider; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentMatchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.mockito.quality.Strictness; - -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.base.test.util.Batch; -import org.chromium.base.test.util.JniMocker; -import org.chromium.components.content_relationship_verification.OriginVerifier; -import org.chromium.components.content_relationship_verification.OriginVerifier.OriginVerificationListener; -import org.chromium.components.content_relationship_verification.OriginVerifierJni; -import org.chromium.components.content_relationship_verification.OriginVerifierUnitTestSupport; -import org.chromium.components.content_relationship_verification.RelationshipCheckResult; -import org.chromium.components.embedder_support.util.Origin; -import org.chromium.content_public.browser.BrowserContextHandle; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -import java.util.concurrent.CountDownLatch; - -/** Tests for WebLayerOriginVerifier. */ -@RunWith(BaseRobolectricTestRunner.class) -@Batch(WebLayerOriginVerifierTest.TEST_BATCH_NAME) -public class WebLayerOriginVerifierTest { - public static final String TEST_BATCH_NAME = "weblayer_origin_verifier"; - - private static final String PACKAGE_NAME = "org.chromium.weblayer_private"; - private int mUid = Process.myUid(); - private Origin mHttpsOrigin = Origin.create("https://www.example.com"); - private Origin mHttpOrigin = Origin.create("http://www.android.com"); - private Origin mHttpLocalhostOrigin = Origin.create("http://localhost:1234/"); - private boolean mStrictLocalhostVerification; - - private WebLayerOriginVerifier mHandleAllUrlsVerifier; - - @Rule - public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.WARN); - - @Rule - public JniMocker mJniMocker = new JniMocker(); - - @Mock - private OriginVerifier.Natives mMockOriginVerifierJni; - - private CountDownLatch mVerificationResultLatch = new CountDownLatch(1); - private CountDownLatch mVerificationResultLatch2 = new CountDownLatch(1); - - private static class TestOriginVerificationListener implements OriginVerificationListener { - private CountDownLatch mLatch; - private boolean mVerified; - - TestOriginVerificationListener(CountDownLatch latch) { - mLatch = latch; - } - - @Override - public void onOriginVerified( - String packageName, Origin origin, boolean verified, Boolean online) { - mVerified = verified; - mLatch.countDown(); - } - - public boolean isVerified() { - return mVerified; - } - } - - private class TestWebLayerOriginVerifier extends WebLayerOriginVerifier { - public TestWebLayerOriginVerifier(String packageName, String relationship, - WebLayerVerificationResultStore verificationResultStore) { - super(packageName, relationship, Mockito.mock(BrowserContextHandle.class), - verificationResultStore); - } - - @Override - boolean getStrictLocalhostVerificationFromManifest() { - return mStrictLocalhostVerification; - } - } - - @Before - public void setUp() throws Exception { - OriginVerifierUnitTestSupport.registerPackageWithSignature( - shadowOf(ApplicationProvider.getApplicationContext().getPackageManager()), - PACKAGE_NAME, mUid); - - mJniMocker.mock(OriginVerifierJni.TEST_HOOKS, mMockOriginVerifierJni); - Mockito.doAnswer(args -> { return 100L; }) - .when(mMockOriginVerifierJni) - .init(Mockito.any(), Mockito.any()); - Mockito.doAnswer(args -> { - mHandleAllUrlsVerifier.onOriginVerificationResult( - args.getArgument(4), RelationshipCheckResult.SUCCESS); - return true; - }) - .when(mMockOriginVerifierJni) - .verifyOrigin(ArgumentMatchers.anyLong(), Mockito.any(), - ArgumentMatchers.anyString(), Mockito.any(), ArgumentMatchers.anyString(), - ArgumentMatchers.anyString(), Mockito.any()); - - mHandleAllUrlsVerifier = new TestWebLayerOriginVerifier(PACKAGE_NAME, - "delegate_permission/common.handle_all_urls", - WebLayerVerificationResultStore.getInstance()); - } - - @Test - public void testHttpsVerification() throws Exception { - TestOriginVerificationListener resultListener = - new TestOriginVerificationListener(mVerificationResultLatch); - TestThreadUtils.runOnUiThreadBlocking( - () -> mHandleAllUrlsVerifier.start(resultListener, mHttpsOrigin)); - mVerificationResultLatch.await(); - Assert.assertTrue(resultListener.isVerified()); - } - - @Test - public void testHttpVerificationNotAllowed() throws Exception { - TestOriginVerificationListener resultListener = - new TestOriginVerificationListener(mVerificationResultLatch); - TestThreadUtils.runOnUiThreadBlocking( - () -> mHandleAllUrlsVerifier.start(resultListener, mHttpOrigin)); - mVerificationResultLatch.await(); - Assert.assertFalse(resultListener.isVerified()); - } - - @Test - public void testHttpLocalhostVerificationAllowed() throws Exception { - Mockito.doAnswer(args -> { - Assert.fail("verifyOrigin was unexpectedly called."); - return true; - }) - .when(mMockOriginVerifierJni) - .verifyOrigin(ArgumentMatchers.anyLong(), Mockito.any(), - ArgumentMatchers.anyString(), Mockito.any(), ArgumentMatchers.anyString(), - ArgumentMatchers.anyString(), Mockito.any()); - TestOriginVerificationListener resultListener = - new TestOriginVerificationListener(mVerificationResultLatch); - TestThreadUtils.runOnUiThreadBlocking( - () -> mHandleAllUrlsVerifier.start(resultListener, mHttpLocalhostOrigin)); - mVerificationResultLatch.await(); - Assert.assertTrue(resultListener.isVerified()); - } - - @Test - public void testHttpLocalhostVerificationNotSkippedWithFlag() throws Exception { - mStrictLocalhostVerification = true; - Mockito.doAnswer(args -> { - mHandleAllUrlsVerifier.onOriginVerificationResult( - args.getArgument(4), RelationshipCheckResult.SUCCESS); - return true; - }) - .when(mMockOriginVerifierJni) - .verifyOrigin(ArgumentMatchers.anyLong(), Mockito.any(), - ArgumentMatchers.anyString(), Mockito.any(), ArgumentMatchers.anyString(), - ArgumentMatchers.anyString(), Mockito.any()); - - TestOriginVerificationListener resultListener = - new TestOriginVerificationListener(mVerificationResultLatch); - TestThreadUtils.runOnUiThreadBlocking( - () -> mHandleAllUrlsVerifier.start(resultListener, mHttpLocalhostOrigin)); - mVerificationResultLatch.await(); - Assert.assertTrue(resultListener.isVerified()); - } - - @Test - public void testConcurrentVerifications() throws Exception { - Mockito.doAnswer(args -> { - // Don't call onOriginVerificationResult to simulate a long request. - return true; - }) - .when(mMockOriginVerifierJni) - .verifyOrigin(ArgumentMatchers.anyLong(), Mockito.any(), - ArgumentMatchers.anyString(), Mockito.any(), ArgumentMatchers.anyString(), - ArgumentMatchers.anyString(), Mockito.any()); - TestOriginVerificationListener verificationResult1 = - new TestOriginVerificationListener(mVerificationResultLatch); - TestThreadUtils.runOnUiThreadBlocking( - () -> mHandleAllUrlsVerifier.start(verificationResult1, mHttpsOrigin)); - Assert.assertFalse(verificationResult1.isVerified()); - Assert.assertEquals(mHandleAllUrlsVerifier.getNumListeners(mHttpsOrigin), 1); - - // Never called, but if it was called, the following asserts would break. - Mockito.doAnswer(args -> { - mHandleAllUrlsVerifier.onOriginVerificationResult( - args.getArgument(4), RelationshipCheckResult.SUCCESS); - return true; - }) - .when(mMockOriginVerifierJni) - .verifyOrigin(ArgumentMatchers.anyLong(), Mockito.any(), - ArgumentMatchers.anyString(), Mockito.any(), ArgumentMatchers.anyString(), - ArgumentMatchers.anyString(), Mockito.any()); - - TestOriginVerificationListener verificationResult2 = - new TestOriginVerificationListener(mVerificationResultLatch2); - TestThreadUtils.runOnUiThreadBlocking( - () -> mHandleAllUrlsVerifier.start(verificationResult2, mHttpsOrigin)); - - Assert.assertFalse(verificationResult2.isVerified()); - // Check that both requests are registered as Listeners. - Assert.assertEquals(mHandleAllUrlsVerifier.getNumListeners(mHttpsOrigin), 2); - - // Call the {@link OriginVerifier#onOriginVerificationResult} callback and verify that - // both listeners receive the result. - mHandleAllUrlsVerifier.onOriginVerificationResult( - mHttpsOrigin.toString(), RelationshipCheckResult.SUCCESS); - - mVerificationResultLatch.await(); - mVerificationResultLatch2.await(); - - Assert.assertTrue(verificationResult1.isVerified()); - Assert.assertTrue(verificationResult2.isVerified()); - } -} \ No newline at end of file
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerTabModalPresenter.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerTabModalPresenter.java deleted file mode 100644 index 9fd4a2cc3..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerTabModalPresenter.java +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; - -import org.chromium.components.browser_ui.modaldialog.TabModalPresenter; -import org.chromium.content_public.browser.WebContents; -import org.chromium.ui.LayoutInflaterUtils; -import org.chromium.ui.modelutil.PropertyModel; - -/** - * The presenter that displays a single tab modal dialog. - * - * TODO(estade): any tab modal dialog should be dismissed on system back (currently, system back - * will navigate). - */ -public class WebLayerTabModalPresenter extends TabModalPresenter { - private final BrowserViewController mBrowserView; - private final Context mContext; - - /** - * Constructor for initializing dialog container. - * @param browserView the BrowserViewController that hosts the dialog container. - * @param context the context used for layout inflation. - */ - public WebLayerTabModalPresenter(BrowserViewController browserView, Context context) { - super(context); - mBrowserView = browserView; - mContext = context; - } - - @Override - protected void showDialogContainer() { - mBrowserView.setWebContentIsObscured(true); - // TODO(estade): to match Chrome, don't show the dialog container before browser controls - // are guaranteed fully visible. - runEnterAnimation(); - } - - @Override - protected void removeDialogView(PropertyModel model) { - mBrowserView.setWebContentIsObscured(false); - super.removeDialogView(model); - } - - private FrameLayout loadDialogContainer() { - return (FrameLayout) LayoutInflaterUtils.inflate( - mContext, R.layout.modal_dialog_container, null); - } - - @Override - protected ViewGroup createDialogContainer() { - FrameLayout dialogContainer = loadDialogContainer(); - dialogContainer.setVisibility(View.GONE); - dialogContainer.setClickable(true); - - mBrowserView.getWebContentsOverlayView().addView(dialogContainer, - new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - return dialogContainer; - } - - @Override - protected void setBrowserControlsAccess(boolean restricted) { - TabImpl tab = mBrowserView.getTab(); - WebContents webContents = tab.getWebContents(); - if (restricted) { - if (webContents.isFullscreenForCurrentTab()) webContents.exitFullscreen(); - - saveOrRestoreTextSelection(webContents, true); - } else { - saveOrRestoreTextSelection(webContents, false); - } - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerVerificationResultStore.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerVerificationResultStore.java deleted file mode 100644 index 49b04eb..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerVerificationResultStore.java +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.components.content_relationship_verification.VerificationResultStore; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * WebLayerVerificationResultStore stores relationships in a local variable. - */ -public class WebLayerVerificationResultStore extends VerificationResultStore { - private static final WebLayerVerificationResultStore sInstance = - new WebLayerVerificationResultStore(); - - private Set<String> mVerifiedOrigins = Collections.synchronizedSet(new HashSet<>()); - - private WebLayerVerificationResultStore() {} - - public static WebLayerVerificationResultStore getInstance() { - return sInstance; - } - - @Override - protected Set<String> getRelationships() { - return mVerifiedOrigins; - } - - @Override - protected void setRelationships(Set<String> relationships) { - mVerifiedOrigins = relationships; - } -} \ No newline at end of file
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebShareServiceFactory.java b/weblayer/browser/java/org/chromium/weblayer_private/WebShareServiceFactory.java deleted file mode 100644 index 7bc39c4..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebShareServiceFactory.java +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.components.browser_ui.share.ShareHelper; -import org.chromium.components.browser_ui.share.ShareParams; -import org.chromium.components.browser_ui.webshare.ShareServiceImpl; -import org.chromium.content_public.browser.WebContents; -import org.chromium.services.service_manager.InterfaceFactory; -import org.chromium.webshare.mojom.ShareService; - -/** - * Factory that creates instances of ShareService. - */ -public class WebShareServiceFactory implements InterfaceFactory<ShareService> { - private final WebContents mWebContents; - - public WebShareServiceFactory(WebContents webContents) { - mWebContents = webContents; - } - - @Override - public ShareService createImpl() { - ShareServiceImpl.WebShareDelegate delegate = new ShareServiceImpl.WebShareDelegate() { - @Override - public boolean canShare() { - return mWebContents.getTopLevelNativeWindow().getActivity() != null; - } - - @Override - public void share(ShareParams params) { - ShareHelper.shareWithSystemShareSheetUi(params); - } - }; - - return new ShareServiceImpl(mWebContents, delegate); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebappsHelper.java b/weblayer/browser/java/org/chromium/weblayer_private/WebappsHelper.java deleted file mode 100644 index e3646bba..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebappsHelper.java +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Intent; -import android.graphics.Bitmap; -import android.net.Uri; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.components.webapps.WebappsUtils; - -class WebappsHelper { - private WebappsHelper() {} - - @CalledByNative - public static void addShortcutToHomescreen( - String id, String url, String userTitle, Bitmap icon, boolean isIconAdaptive) { - Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - WebappsUtils.addShortcutToHomescreen(id, userTitle, icon, isIconAdaptive, shortcutIntent); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/bluetooth/WebLayerBluetoothChooserAndroidDelegate.java b/weblayer/browser/java/org/chromium/weblayer_private/bluetooth/WebLayerBluetoothChooserAndroidDelegate.java deleted file mode 100644 index fcec20e..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/bluetooth/WebLayerBluetoothChooserAndroidDelegate.java +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.bluetooth; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.components.omnibox.AutocompleteSchemeClassifier; -import org.chromium.components.permissions.BluetoothChooserAndroidDelegate; -import org.chromium.weblayer_private.AutocompleteSchemeClassifierImpl; - -/** - * The implementation of {@link BluetoothChooserAndroidDelegate} for WebLayer. - */ -@JNINamespace("weblayer") -public class WebLayerBluetoothChooserAndroidDelegate implements BluetoothChooserAndroidDelegate { - /** - * {@inheritDoc} - */ - @Override - public AutocompleteSchemeClassifier createAutocompleteSchemeClassifier() { - return new AutocompleteSchemeClassifierImpl(); - } - - @CalledByNative - private static WebLayerBluetoothChooserAndroidDelegate create() { - return new WebLayerBluetoothChooserAndroidDelegate(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/bluetooth/WebLayerBluetoothScanningPromptAndroidDelegate.java b/weblayer/browser/java/org/chromium/weblayer_private/bluetooth/WebLayerBluetoothScanningPromptAndroidDelegate.java deleted file mode 100644 index 10d617e..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/bluetooth/WebLayerBluetoothScanningPromptAndroidDelegate.java +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.bluetooth; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.components.omnibox.AutocompleteSchemeClassifier; -import org.chromium.components.permissions.BluetoothScanningPromptAndroidDelegate; -import org.chromium.weblayer_private.AutocompleteSchemeClassifierImpl; - -/** - * The implementation of {@link BluetoothScanningPromptAndroidDelegate} for WebLayer. - */ -@JNINamespace("weblayer") -public class WebLayerBluetoothScanningPromptAndroidDelegate - implements BluetoothScanningPromptAndroidDelegate { - /** - * {@inheritDoc} - */ - @Override - public AutocompleteSchemeClassifier createAutocompleteSchemeClassifier() { - return new AutocompleteSchemeClassifierImpl(); - } - - @CalledByNative - private static WebLayerBluetoothScanningPromptAndroidDelegate create() { - return new WebLayerBluetoothScanningPromptAndroidDelegate(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/APICallException.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/APICallException.java deleted file mode 100644 index ecbdb0a..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/APICallException.java +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.util.AndroidRuntimeException; - -/** - * Error thrown if there is an error communicating over the AIDL boundary. - */ -public class APICallException extends AndroidRuntimeException { - /** - * Constructs a new exception with the specified cause. - */ - public APICallException(Exception cause) { - super(cause); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java deleted file mode 100644 index d1b4d21..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ActionModeItemType.SHARE, ActionModeItemType.WEB_SEARCH}) -@Retention(RetentionPolicy.SOURCE) -public @interface ActionModeItemType { - int SHARE = 1 << 0; - int WEB_SEARCH = 1 << 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/BrowserFragmentArgs.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/BrowserFragmentArgs.java deleted file mode 100644 index 1b728846..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/BrowserFragmentArgs.java +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** Keys for the Bundle of arguments with which BrowserFragments are created. */ -public interface BrowserFragmentArgs { - String PROFILE_NAME = "profile_name"; - String PERSISTENCE_ID = "persistence_id"; - /** - * A boolean value indicating whether the profile is incognito. - */ - String IS_INCOGNITO = "is_incognito"; - String IS_EXTERNAL_INTENTS_ENABLED = "is_external_intents_enabled"; - String USE_VIEW_MODEL = "use_view_model"; - String ALLOWED_ORIGINS = "allowed_origins"; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/BrowsingDataType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/BrowsingDataType.java deleted file mode 100644 index 3a01bb6..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/BrowsingDataType.java +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({BrowsingDataType.COOKIES_AND_SITE_DATA, BrowsingDataType.CACHE, - BrowsingDataType.SITE_SETTINGS}) -@Retention(RetentionPolicy.SOURCE) -public @interface BrowsingDataType { - int COOKIES_AND_SITE_DATA = 0; - int CACHE = 1; - int SITE_SETTINGS = 2; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/CookieChangeCause.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/CookieChangeCause.java deleted file mode 100644 index 387e1d9f..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/CookieChangeCause.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({CookieChangeCause.INSERTED, CookieChangeCause.EXPLICIT, CookieChangeCause.UNKNOWN_DELETION, - CookieChangeCause.OVERWRITE, CookieChangeCause.EXPIRED, CookieChangeCause.EVICTED, - CookieChangeCause.EXPIRED_OVERWRITE}) -@Retention(RetentionPolicy.SOURCE) -public @interface CookieChangeCause { - int INSERTED = 0; - int EXPLICIT = 1; - int UNKNOWN_DELETION = 2; - int OVERWRITE = 3; - int EXPIRED = 4; - int EVICTED = 5; - int EXPIRED_OVERWRITE = 6; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DarkModeStrategy.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DarkModeStrategy.java deleted file mode 100644 index e022776..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DarkModeStrategy.java +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({DarkModeStrategy.PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING, - DarkModeStrategy.WEB_THEME_DARKENING_ONLY, DarkModeStrategy.USER_AGENT_DARKENING_ONLY}) -@Retention(RetentionPolicy.SOURCE) -public @interface DarkModeStrategy { - int WEB_THEME_DARKENING_ONLY = 0; - int USER_AGENT_DARKENING_ONLY = 1; - int PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DownloadError.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DownloadError.java deleted file mode 100644 index 42507f2..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DownloadError.java +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({DownloadError.NO_ERROR, DownloadError.SERVER_ERROR, DownloadError.SSL_ERROR, - DownloadError.CONNECTIVITY_ERROR, DownloadError.NO_SPACE, DownloadError.FILE_ERROR, - DownloadError.CANCELLED, DownloadError.OTHER_ERROR}) -@Retention(RetentionPolicy.SOURCE) -public @interface DownloadError { - int NO_ERROR = 0; - int SERVER_ERROR = 1; - int SSL_ERROR = 2; - int CONNECTIVITY_ERROR = 3; - int NO_SPACE = 4; - int FILE_ERROR = 5; - int CANCELLED = 6; - int OTHER_ERROR = 7; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DownloadState.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DownloadState.java deleted file mode 100644 index 926f4a0..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/DownloadState.java +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({DownloadState.IN_PROGRESS, DownloadState.COMPLETE, DownloadState.PAUSED, - DownloadState.CANCELLED, DownloadState.FAILED}) -@Retention(RetentionPolicy.SOURCE) -public @interface DownloadState { - int IN_PROGRESS = 0; - int COMPLETE = 1; - int PAUSED = 2; - int CANCELLED = 3; - int FAILED = 4; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ExceptionType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ExceptionType.java deleted file mode 100644 index bea3a2d6..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ExceptionType.java +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ExceptionType.RESTRICTED_API, ExceptionType.UNKNOWN}) -@Retention(RetentionPolicy.SOURCE) -public @interface ExceptionType { - int UNKNOWN = 0; - int RESTRICTED_API = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ExternalIntentInIncognitoUserDecision.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ExternalIntentInIncognitoUserDecision.java deleted file mode 100644 index 3f24b63..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ExternalIntentInIncognitoUserDecision.java +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ExternalIntentInIncognitoUserDecision.ALLOW, ExternalIntentInIncognitoUserDecision.DENY}) -@Retention(RetentionPolicy.SOURCE) -public @interface ExternalIntentInIncognitoUserDecision { - int ALLOW = 0; - int DENY = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/GoogleAccountServiceType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/GoogleAccountServiceType.java deleted file mode 100644 index ed58a5d3..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/GoogleAccountServiceType.java +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({GoogleAccountServiceType.SIGNOUT, GoogleAccountServiceType.ADD_SESSION, - GoogleAccountServiceType.DEFAULT}) -@Retention(RetentionPolicy.SOURCE) -public @interface GoogleAccountServiceType { - int SIGNOUT = 0; - int ADD_SESSION = 1; - int DEFAULT = 2; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBooleanCallback.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBooleanCallback.aidl deleted file mode 100644 index 52b8c9b..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBooleanCallback.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -oneway interface IBooleanCallback { - void onResult(in boolean result) = 1; - - // TODO(swestphal): Replace parameters with actual Exception when supported to also propagate stacktrace. - void onException(in int type, in String msg) = 2; -} \ No newline at end of file
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl deleted file mode 100644 index dc308144..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IBrowserClient; -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.IMediaRouteDialogFragment; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.ITab; - -import java.util.List; - -interface IBrowser { - IProfile getProfile() = 0; - - // Sets the active tab, returns false if tab is not attached to this fragment. - boolean setActiveTab(in ITab tab) = 3; - - int getActiveTabId() = 4; - List getTabs() = 5; - - void setClient(in IBrowserClient client) = 6; - - void addTab(in ITab tab) = 7; - void destroyTab(in ITab tab) = 8; - - ITab createTab() = 11; - - boolean isRestoringPreviousState() = 14; - - // Added in 90. - void setDarkModeStrategy(in int strategy) = 16; - - // Added in 105 - int[] getTabIds() = 20; - - void shutdown() = 22; - - IRemoteFragment createBrowserFragmentImpl() = 23; - IMediaRouteDialogFragment createMediaRouteDialogFragmentImpl() = 24; - -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl deleted file mode 100644 index 370a4b1..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.ITab; - -interface IBrowserClient { - void onActiveTabChanged(in int activeTabId) = 0; - void onTabAdded(in ITab tab) = 1; - void onTabRemoved(in int tabId) = 2; - IRemoteFragment createMediaRouteDialogFragment() = 3; - void onTabInitializationCompleted() = 5; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IChildProcessService.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IChildProcessService.aidl deleted file mode 100644 index 56d48f22..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IChildProcessService.aidl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -/** Interface to forward service calls to the service implementation. */ -interface IChildProcessService { - void onCreate() = 0; - - void onDestroy() = 1; - - IObjectWrapper onBind(IObjectWrapper intent) = 2; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientDownload.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientDownload.aidl deleted file mode 100644 index af70759..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientDownload.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * Represents a download on the *client* side. - */ -interface IClientDownload { -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientNavigation.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientNavigation.aidl deleted file mode 100644 index 9369138f..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientNavigation.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * Represents a navigation on the *client* side. - */ -interface IClientNavigation { -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientPage.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientPage.aidl deleted file mode 100644 index 4d9df7fb..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IClientPage.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * Represents a page on the *client* side. - */ -interface IClientPage { -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl deleted file mode 100644 index 9544d48b..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * Holds on to the native ContextMenuParams object. - */ -interface IContextMenuParams { -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ICookieChangedCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ICookieChangedCallbackClient.aidl deleted file mode 100644 index 6c195303..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ICookieChangedCallbackClient.aidl +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -interface ICookieChangedCallbackClient { - void onCookieChanged(in String cookie, int cause); -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ICookieManager.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ICookieManager.aidl deleted file mode 100644 index 8144aae..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ICookieManager.aidl +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IBooleanCallback; -import org.chromium.weblayer_private.interfaces.ICookieChangedCallbackClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IStringCallback; - -interface ICookieManager { - void setCookie(in String url, in String value, in IBooleanCallback callback) = 0; - - void getCookie(in String url, in IStringCallback callback) = 1; - - IObjectWrapper addCookieChangedCallback(in String url, in String name, ICookieChangedCallbackClient callback) = 2; - - // Added in 101. - void getResponseCookies(in String url, in IObjectWrapper callback) = 3; - -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IDownload.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IDownload.aidl deleted file mode 100644 index d77035163..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IDownload.aidl +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * Contains information about a single download that's in progress. - */ -interface IDownload { - int getState() = 0; - long getTotalBytes() = 1; - long getReceivedBytes() = 2; - void pause() = 3; - void resume() = 4; - void cancel() = 5; - String getLocation() = 6; - int getError() = 7; - String getMimeType() = 8; - void disableNotification() = 9; - String getFileNameToReportToUser() = 10; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IDownloadCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IDownloadCallbackClient.aidl deleted file mode 100644 index d23d3763..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IDownloadCallbackClient.aidl +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.content.Intent; -import org.chromium.weblayer_private.interfaces.IClientDownload; -import org.chromium.weblayer_private.interfaces.IDownload; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -/** - * Used to forward download requests to the client. - */ -interface IDownloadCallbackClient { - boolean interceptDownload(in String uriString, in String userAgent, in String contentDisposition, in String mimetype, long contentLength) = 0; - void allowDownload(in String uriString, in String requestMethod, in String requestInitiatorString, in IObjectWrapper valueCallback) = 1; - IClientDownload createClientDownload(in IDownload impl) = 2; - void downloadStarted(IClientDownload download) = 3; - void downloadProgressChanged(IClientDownload download) = 4; - void downloadCompleted(IClientDownload download) = 5; - void downloadFailed(IClientDownload download) = 6; - // ID 7 was createIntent and was removed in M87. -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IErrorPageCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IErrorPageCallbackClient.aidl deleted file mode 100644 index cd84f710..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IErrorPageCallbackClient.aidl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IClientNavigation; - -/** - * Allows the client to override the default way of handling user interactions - * with error pages (such as SSL interstitials). - */ -interface IErrorPageCallbackClient { - boolean onBackToSafety() = 0; - String getErrorPageContent(IClientNavigation navigation) = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IExternalIntentInIncognitoCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IExternalIntentInIncognitoCallbackClient.aidl deleted file mode 100644 index 4fc991d..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IExternalIntentInIncognitoCallbackClient.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -interface IExternalIntentInIncognitoCallbackClient { - // onUserDecisionWrapper is a ValueCallback<Integer>. - void onExternalIntentInIncognito(in IObjectWrapper onUserDecisionWrapper) = 0; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFaviconFetcher.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFaviconFetcher.aidl deleted file mode 100644 index 44bf278..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFaviconFetcher.aidl +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -interface IFaviconFetcher { - void destroy() = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFaviconFetcherClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFaviconFetcherClient.aidl deleted file mode 100644 index 4f2d8e4..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFaviconFetcherClient.aidl +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -interface IFaviconFetcherClient { - void onDestroyed() = 1; - void onFaviconChanged(in Bitmap bitmap) = 2; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFindInPageCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFindInPageCallbackClient.aidl deleted file mode 100644 index 61e1597..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFindInPageCallbackClient.aidl +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * Used to forward find in page results to the client. - */ -interface IFindInPageCallbackClient { - void onFindResult(in int numberOfMatches, in int activeMatchOrdinal, in boolean finalUpdate) = 0; - void onFindEnded() = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFullscreenCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFullscreenCallbackClient.aidl deleted file mode 100644 index 3280337a..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IFullscreenCallbackClient.aidl +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -/** - * Used to forward FullscreenCallback calls to the client. - */ -interface IFullscreenCallbackClient { - // exitFullscreenWrapper is a ValueCallback<Void> that when run exits - // fullscreen. - void enterFullscreen(in IObjectWrapper exitFullscreenWrapper) = 0; - void exitFullscreen() = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IGoogleAccountAccessTokenFetcherClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IGoogleAccountAccessTokenFetcherClient.aidl deleted file mode 100644 index 80295c8..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IGoogleAccountAccessTokenFetcherClient.aidl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -interface IGoogleAccountAccessTokenFetcherClient { - // scopesWrapper is a Set<String>, and onTokenFetchedWrapper is a ValueCallback<String>. - void fetchAccessToken(in IObjectWrapper scopesWrapper, in IObjectWrapper onTokenFetchedWrapper) = 0; - - // scopesWrapper is a Set<String>, and tokenWrapper is a String. - // Added in 93. - void onAccessTokenIdentifiedAsInvalid(in IObjectWrapper scopesWrapper, in IObjectWrapper tokenWrapper) = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IGoogleAccountsCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IGoogleAccountsCallbackClient.aidl deleted file mode 100644 index 8452191..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IGoogleAccountsCallbackClient.aidl +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -interface IGoogleAccountsCallbackClient { - void onGoogleAccountsRequest(int serviceType, in String email, in String continueUrl, boolean isSameTab) = 0; - String getGaiaId() = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IMediaCaptureCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IMediaCaptureCallbackClient.aidl deleted file mode 100644 index a132f27..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IMediaCaptureCallbackClient.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -interface IMediaCaptureCallbackClient { - void onMediaCaptureRequested(boolean audio, boolean video, in IObjectWrapper requestResult) = 0; - void onMediaCaptureStateChanged(boolean audio, boolean video) = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IMediaRouteDialogFragment.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IMediaRouteDialogFragment.aidl deleted file mode 100644 index 96a507630..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IMediaRouteDialogFragment.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IRemoteFragment; - -interface IMediaRouteDialogFragment { - IRemoteFragment asRemoteFragment() = 0; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigateParams.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigateParams.aidl deleted file mode 100644 index af76a47..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigateParams.aidl +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -/** - * Provides parameters for NavigationController.navigate. - */ -interface INavigateParams { - void replaceCurrentEntry() = 0; - void disableIntentProcessing() = 1; - void disableNetworkErrorAutoReload() = 2; - void enableAutoPlay() = 3; - void setResponse(in IObjectWrapper response) = 4; - - // @since 89 - void allowIntentLaunchesInBackground() = 5; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl deleted file mode 100644 index ed7a99d2..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IClientPage; - -/** - * Provides information about a navigation. - */ -interface INavigation { - int getState() = 0; - - String getUri() = 1; - - List<String> getRedirectChain() = 2; - - int getHttpStatusCode() = 3; - - boolean isSameDocument() = 4; - - boolean isErrorPage() = 5; - - int getLoadError() = 6; - - void setRequestHeader(in String name, in String value) = 7; - - void setUserAgentString(in String value) = 8; - - boolean isDownload() = 9; - - boolean wasStopCalled() = 10; - - boolean isPageInitiated() = 11; - boolean isReload() = 12; - - // @since 89 - boolean wasIntentLaunched() = 13; - boolean isUserDecidingIntentLaunch() = 14; - boolean isKnownProtocol() = 15; - boolean isServedFromBackForwardCache() = 16; - boolean isFormSubmission() = 19; - String getReferrer() = 20; - - // @since 88 - void disableNetworkErrorAutoReload() = 17; - - // @since 90 - IClientPage getPage() = 18; - - // @since 91 - List<String> getResponseHeaders() = 21; - - // @since 92 - int getNavigationEntryOffset() = 22; - - // @since 97 - void disableIntentProcessing() = 23; - - // @since 102 - boolean wasFetchedFromCache() = 24; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationController.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationController.aidl deleted file mode 100644 index 8cfe54f9..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationController.aidl +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.INavigateParams; -import org.chromium.weblayer_private.interfaces.NavigateParams; - -interface INavigationController { - // Deprecated in M89. - void navigate(in String uri, in NavigateParams params) = 0; - - void goBack() = 1; - - void goForward() = 2; - - void reload() = 3; - - void stop() = 4; - - int getNavigationListSize() = 5; - - int getNavigationListCurrentIndex() = 6; - - String getNavigationEntryDisplayUri(in int index) = 7; - - boolean canGoBack() = 8; - - boolean canGoForward() = 9; - - void goToIndex(in int index) = 10; - - String getNavigationEntryTitle(in int index) = 11; - - // ID 12 was replace and was removed in M83. - - boolean isNavigationEntrySkippable(int index) = 13; - - // Deprecated in M89. - void navigate2(in String uri, - in boolean shouldReplaceEntry, - in boolean disableIntentProcessing, - in boolean disableNetworkErrorAutoReload, - in boolean enableAutoPlay) = 14; - - INavigateParams createNavigateParams() = 15; - void navigate3(in String uri, - in INavigateParams params) = 16; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl deleted file mode 100644 index e66662ed..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IClientNavigation; -import org.chromium.weblayer_private.interfaces.IClientPage; -import org.chromium.weblayer_private.interfaces.INavigation; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -/** - * Interface used by NavigationController to inform the client of changes. This largely duplicates - * the NavigationCallback interface, but is a singleton to avoid unnecessary IPC. - */ -interface INavigationControllerClient { - IClientNavigation createClientNavigation(in INavigation impl) = 0; - - void navigationStarted(IClientNavigation navigation) = 1; - - void navigationRedirected(IClientNavigation navigation) = 2; - - void readyToCommitNavigation(IClientNavigation navigation) = 3; - - void navigationCompleted(IClientNavigation navigation) = 4; - - void navigationFailed(IClientNavigation navigation) = 5; - - void loadStateChanged(boolean isLoading, boolean shouldShowLoadingUi) = 6; - - void loadProgressChanged(double progress) = 7; - - void onFirstContentfulPaint() = 8; - - void onOldPageNoLongerRendered(in String uri) = 9; - - // Added in M88. - void onFirstContentfulPaint2(long navigationStartMs, long firstContentfulPaintDurationMs) = 10; - void onLargestContentfulPaint(long navigationStartMs, long largestContentfulPaintDurationMs) = 11; - - // Added in M90. - IClientPage createClientPage() = 12; - void onPageDestroyed(IClientPage page) = 13; - - // Added in M93. - void onPageLanguageDetermined(IClientPage page, in String language) = 14; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IObjectWrapper.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IObjectWrapper.aidl deleted file mode 100644 index 7e25fa8..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IObjectWrapper.aidl +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * This interface intentionally has no methods, and instances of this should - * be created from class ObjectWrapper only. This is used as a way of passing - * objects that descend from the system classes via AIDL across classloaders - * without serializing them. - */ -interface IObjectWrapper { -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IOpenUrlCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IOpenUrlCallbackClient.aidl deleted file mode 100644 index a137e73..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IOpenUrlCallbackClient.aidl +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IBrowser; - -// Since 91. -interface IOpenUrlCallbackClient { - IBrowser getBrowserForNewTab() = 0; - void onTabAdded(in int tabId) = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IPrerenderController.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IPrerenderController.aidl deleted file mode 100644 index 4f26adff..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IPrerenderController.aidl +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -interface IPrerenderController { - void prerender(in String url) = 0; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfile.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfile.aidl deleted file mode 100644 index 2b5351b..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfile.aidl +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.ICookieManager; -import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient; -import org.chromium.weblayer_private.interfaces.IUserIdentityCallbackClient; -import org.chromium.weblayer_private.interfaces.IGoogleAccountAccessTokenFetcherClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IOpenUrlCallbackClient; -import org.chromium.weblayer_private.interfaces.IPrerenderController; -import org.chromium.weblayer_private.interfaces.IProfileClient; - -interface IProfile { - void destroy() = 0; - - void clearBrowsingData(in int[] dataTypes, long fromMillis, long toMillis, - in IObjectWrapper completionCallback) = 1; - - String getName() = 2; - - void setDownloadDirectory(String directory) = 3; - - void destroyAndDeleteDataFromDisk(in IObjectWrapper completionCallback) = 4; - - void setDownloadCallbackClient(IDownloadCallbackClient client) = 5; - - ICookieManager getCookieManager() = 6; - - void setBooleanSetting(int type, boolean value) = 7; - boolean getBooleanSetting(int type) = 8; - - void getBrowserPersistenceIds(in IObjectWrapper resultCallback) = 9; - void removeBrowserPersistenceStorage(in String[] ids, - in IObjectWrapper resultCallback) = 10; - void prepareForPossibleCrossOriginNavigation() = 11; - - void getCachedFaviconForPageUri(in String uri, - in IObjectWrapper resultCallback) = 12; - - void setUserIdentityCallbackClient(IUserIdentityCallbackClient client) = 13; - IPrerenderController getPrerenderController() = 15; - boolean isIncognito() = 16; - void setClient(in IProfileClient client) = 17; - void destroyAndDeleteDataFromDiskSoon(in IObjectWrapper completeCallback) = 18; - - // Added in 89. - void setGoogleAccountAccessTokenFetcherClient(IGoogleAccountAccessTokenFetcherClient client) = 19; - - // Added in 91. - void setTablessOpenUrlCallbackClient(IOpenUrlCallbackClient client) = 20; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl deleted file mode 100644 index e80a5438..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -// Added in Version 88. -interface IProfileClient { - void onProfileDestroyed() = 0; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IRemoteFragment.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IRemoteFragment.aidl deleted file mode 100644 index 43d3a0c..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IRemoteFragment.aidl +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IRemoteFragmentClient; - -// Next value: 16 -interface IRemoteFragment { - - void setClient(in IRemoteFragmentClient client) = 15; - - // Fragment events. - void handleOnCreate() = 0; - void handleOnAttach(in IObjectWrapper context) = 1; - void handleOnStart() = 2; - void handleOnResume() = 3; - void handleOnPause() = 4; - void handleOnStop() = 5; - void handleOnDestroyView() = 6; - void handleOnDetach() = 7; - void handleOnDestroy() = 8; - - // |data| is an Intent with the result returned from the activity. - void handleOnActivityResult(int requestCode, - int resultCode, - in IObjectWrapper data) = 9; - void handleOnRequestPermissionsResult(int requestCode, - in String[] permissions, - in int[] grantResults) = 10; - - // Out of process operations. - void handleSetSurfaceControlViewHost(in IObjectWrapper /* SurfaceControlViewHost */ host) = 12; - - // In process operations. - IObjectWrapper /* View */ handleGetContentViewRenderView() = 13; - - // Fragment operations. - void handleSetMinimumSurfaceSize(in int width, in int height) = 14; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IRemoteFragmentClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IRemoteFragmentClient.aidl deleted file mode 100644 index 30302cae..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IRemoteFragmentClient.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -// Next value: 1 -interface IRemoteFragmentClient { - boolean startActivityForResult(in IObjectWrapper intent, in int requestCode, in IObjectWrapper options) = 0; -} \ No newline at end of file
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IStringCallback.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IStringCallback.aidl deleted file mode 100644 index 8fd7041a..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IStringCallback.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -oneway interface IStringCallback { - void onResult(in String result) = 1; - - // TODO(swestphal): Replace parameters with actual Exception when supported to also propagate stacktrace. - void onException(in int type, in String msg) = 2; -} \ No newline at end of file
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl deleted file mode 100644 index aa408524..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import java.util.List; - -import org.chromium.weblayer_private.interfaces.IContextMenuParams; -import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient; -import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient; -import org.chromium.weblayer_private.interfaces.IExternalIntentInIncognitoCallbackClient; -import org.chromium.weblayer_private.interfaces.IFaviconFetcher; -import org.chromium.weblayer_private.interfaces.IFaviconFetcherClient; -import org.chromium.weblayer_private.interfaces.IFindInPageCallbackClient; -import org.chromium.weblayer_private.interfaces.IFullscreenCallbackClient; -import org.chromium.weblayer_private.interfaces.IGoogleAccountsCallbackClient; -import org.chromium.weblayer_private.interfaces.IMediaCaptureCallbackClient; -import org.chromium.weblayer_private.interfaces.INavigationController; -import org.chromium.weblayer_private.interfaces.INavigationControllerClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IStringCallback; -import org.chromium.weblayer_private.interfaces.ITabClient; - -interface ITab { - void setClient(in ITabClient client) = 0; - - INavigationController createNavigationController(in INavigationControllerClient client) = 1; - - // ID 2 was setDownloadCallbackClient and was removed in M89. - - void setErrorPageCallbackClient(IErrorPageCallbackClient client) = 3; - - void setFullscreenCallbackClient(in IFullscreenCallbackClient client) = 4; - - void executeScript(in String script, boolean useSeparateIsolate, in IStringCallback callback) = 5; - - void setNewTabsEnabled(in boolean enabled) = 6; - - // Returns a unique identifier for this Tab. The id is *not* unique across - // restores. The id is intended for the client library to avoid creating duplicate client objects - // for the same ITab. - int getId() = 7; - - boolean setFindInPageCallbackClient(IFindInPageCallbackClient client) = 8; - void findInPage(in String searchText, boolean forward) = 9; - - // And and removed in 82; superseded by dismissTransientUi(). - // void dismissTabModalOverlay() = 10; - void dispatchBeforeUnloadAndClose() = 11; - - boolean dismissTransientUi() = 12; - - String getGuid() = 13; - - void setMediaCaptureCallbackClient(in IMediaCaptureCallbackClient client) = 14; - void stopMediaCapturing() = 15; - - void captureScreenShot(in float scale, in IObjectWrapper resultCallback) = 16; - - boolean setData(in Map data) = 17; - Map getData() = 18; - - // IDs 19 and 20 were registerWebMessageCallback & unregisterWebMessageCallback. - - boolean canTranslate() = 21; - void showTranslateUi() = 22; - - void setGoogleAccountsCallbackClient(IGoogleAccountsCallbackClient client) = 23; - IFaviconFetcher createFaviconFetcher(IFaviconFetcherClient client) = 24; - void setTranslateTargetLanguage(in String targetLanguage) = 25; - - void setScrollOffsetsEnabled(in boolean enabled) = 26; - - // Added in 88 - void setFloatingActionModeOverride(in int actionModeItemTypes) = 27; - boolean willAutomaticallyReloadAfterCrash() = 28; - void setDesktopUserAgentEnabled(in boolean enable) = 29; - boolean isDesktopUserAgentEnabled() = 30; - void download(in IContextMenuParams contextMenuParams) = 31; - - // Added in 90 - void addToHomescreen() = 32; - - // Added in 93 - void setExternalIntentInIncognitoCallbackClient(IExternalIntentInIncognitoCallbackClient client) = 33; - - String getUri() = 34; - - void postMessage(in String message, in String targetOrigin) = 35; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl deleted file mode 100644 index f927769..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IContextMenuParams; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -/** - * Interface used by Tab to inform the client of changes. This largely duplicates the - * TabCallback interface, but is a singleton to avoid unnecessary IPC. - */ -interface ITabClient { - void visibleUriChanged(in String uriString) = 0; - - void onNewTab(in int tabId, in int mode) = 1; - - void onRenderProcessGone() = 2; - - // ID 3 was onCloseTab and was removed in M87. - - // Deprecated in M88. - void showContextMenu(in IObjectWrapper pageUrl, in IObjectWrapper linkUrl, - in IObjectWrapper linkText, in IObjectWrapper titleOrAltText, - in IObjectWrapper srcUrl) = 4; - - void onTabModalStateChanged(in boolean isTabModalShowing) = 5; - - void onTitleUpdated(in IObjectWrapper title) = 6; - - void bringTabToFront() = 7; - - void onTabDestroyed() = 8; - - void onBackgroundColorChanged(in int color) = 9; - - void onScrollNotification( - in int notificationType, in float currentScrollRatio) = 10; - - void onVerticalScrollOffsetChanged(in int offset) = 11; - - // Added in M88 - void onActionItemClicked( - in int actionModeItemType, in IObjectWrapper selectedString) = 12; - void showContextMenu2(in IObjectWrapper pageUrl, in IObjectWrapper linkUrl, - in IObjectWrapper linkText, in IObjectWrapper titleOrAltText, - in IObjectWrapper srcUrl, in boolean isImage, in boolean isVideo, in boolean canDownload, - in IContextMenuParams contextMenuParams) = 13; - - // Added in M101. - void onVerticalOverscroll(float accumulatedOverscrollY) = 14; - - // Added in M111. - void onPostMessage(in String message, in String origin) = 15; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IUserIdentityCallbackClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IUserIdentityCallbackClient.aidl deleted file mode 100644 index 9873f73..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IUserIdentityCallbackClient.aidl +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -interface IUserIdentityCallbackClient { - String getEmail() = 0; - String getFullName() = 1; - // avatarLoadedWrapper is a ValueCallback<Bitmap> that updates the profile icon when run. - void getAvatar(int desiredSize, in IObjectWrapper avatarLoadedWrapper) = 2; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl deleted file mode 100644 index eade180..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.content.Intent; -import android.os.Bundle; - -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.IMediaRouteDialogFragment; -import org.chromium.weblayer_private.interfaces.IWebLayerClient; - -interface IWebLayer { - // ID 1 was loadAsyncV80 and was removed in M86. - // ID 2 was loadSyncV80 and was removed in M86. - - // Create or get the profile matching profileName. - IProfile getProfile(in String profileName) = 4; - - // Enable or disable DevTools remote debugging server. - void setRemoteDebuggingEnabled(boolean enabled) = 5; - - // Returns whether or not the DevTools remote debugging server is enabled. - boolean isRemoteDebuggingEnabled() = 6; - - // ID 7 was getCrashReporterControllerV80 and was removed in M86. - - // Initializes WebLayer and starts loading. - // - // It is expected that either loadAsync or loadSync is called before anything else. - // - // @param appContext A Context that refers to the Application using WebLayer. - // @param remoteContext A Context that refers to the WebLayer provider package. - // @param loadedCallback A ValueCallback that will be called when load completes. - void loadAsync(in IObjectWrapper appContext, - in IObjectWrapper remoteContext, - in IObjectWrapper loadedCallback) = 8; - - // Initializes WebLayer, starts loading and blocks until loading has completed. - // - // It is expected that either loadAsync or loadSync is called before anything else. - // - // @param appContext A Context that refers to the Application using WebLayer. - // @param remoteContext A Context that refers to the WebLayer provider package. - void loadSync(in IObjectWrapper appContext, - in IObjectWrapper remoteContext) = 9; - - // Forwards broadcast from a notification to the implementation. - void onReceivedBroadcast(in IObjectWrapper appContext, in Intent intent) = 11; - - void enumerateAllProfileNames(in IObjectWrapper valueCallback) = 12; - - void setClient(in IWebLayerClient client) = 13; - - String getUserAgentString() = 14; - - void registerExternalExperimentIDs(in String trialName, in int[] experimentIds) = 15; - - void onMediaSessionServiceStarted(in IObjectWrapper sessionService, in Intent intent) = 17; - void onMediaSessionServiceDestroyed() = 18; - - IBinder initializeImageDecoder(in IObjectWrapper appContext, - in IObjectWrapper remoteContext) = 19; - - IObjectWrapper getApplicationContext() = 20; - IProfile getIncognitoProfile(in String profileName) = 24; - - // Added in Version 88. - void onRemoteMediaServiceStarted(in IObjectWrapper sessionService, in Intent intent) = 22; - void onRemoteMediaServiceDestroyed(int id) = 23; - - // Creates an instance of GooglePayDataCallbacksService. Added in Version 92. - IObjectWrapper createGooglePayDataCallbacksService() = 26; - - // Creates an instance of PaymentDetailsUpdateService. Added in Version 92. - IObjectWrapper createPaymentDetailsUpdateService() = 27; - - // Added in Version 101. - String getXClientDataHeader() = 28; - - IBrowser createBrowser(IObjectWrapper serviceContext, IObjectWrapper fragmentArgs) = 29; - - // WARNING: when choosing next value make sure you look back for the max, as - // merges may mean the last function does not have the max value. -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl deleted file mode 100644 index 81e4606..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.content.Intent; - -interface IWebLayerClient { - Intent createIntent() = 0; - Intent createMediaSessionServiceIntent() = 1; - int getMediaSessionNotificationId() = 2; - Intent createImageDecoderServiceIntent() = 3; - - // Since Version 88. - Intent createRemoteMediaServiceIntent() = 7; - int getPresentationApiNotificationId() = 8; - int getRemotePlaybackApiNotificationId() = 9; - - // Added in Version 98. - int getMaxNavigationsPerTabForInstanceState() = 10; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerFactory.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerFactory.aidl deleted file mode 100644 index d2535c65..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerFactory.aidl +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.os.Bundle; - -import org.chromium.weblayer_private.interfaces.IWebLayer; - -// Factory for creating IWebLayer as well as determining if a particular version -// of a client is supported. -interface IWebLayerFactory { - // Returns true if a client with the specified version is supported. - boolean isClientSupported() = 0; - - // Creates a new IWebLayer. It is expected that a client has a single - // IWebLayer. Further, at this time, only a single client is supported. - IWebLayer createWebLayer() = 1; - - // Returns the full version string of the implementation. - String getImplementationVersion() = 2; - - // Returns the major version of the implementation. - int getImplementationMajorVersion() = 3; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java deleted file mode 100644 index b53c758..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({LoadError.NO_ERROR, LoadError.HTTP_CLIENT_ERROR, LoadError.HTTP_SERVER_ERROR, - LoadError.SSL_ERROR, LoadError.CONNECTIVITY_ERROR, LoadError.OTHER_ERROR, - LoadError.SAFE_BROWSING_ERROR}) -@Retention(RetentionPolicy.SOURCE) -public @interface LoadError { - int NO_ERROR = 0; - int HTTP_CLIENT_ERROR = 1; - int HTTP_SERVER_ERROR = 2; - int SSL_ERROR = 3; - int CONNECTIVITY_ERROR = 4; - int OTHER_ERROR = 5; - // Sent since 88. - int SAFE_BROWSING_ERROR = 6; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigateParams.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigateParams.aidl deleted file mode 100644 index 78dec159..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigateParams.aidl +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -parcelable NavigateParams;
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigateParams.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigateParams.java deleted file mode 100644 index a377faa..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigateParams.java +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Extra optional parameters for {@link NavigationController#navigate}. - * - * Default values should be kept in sync with C++ NavigationController::LoadURLParams. - * - * @since 83 - */ -public class NavigateParams implements Parcelable { - public boolean mShouldReplaceCurrentEntry; - - public static final Parcelable.Creator<NavigateParams> CREATOR = - new Parcelable.Creator<NavigateParams>() { - @Override - public NavigateParams createFromParcel(Parcel in) { - return new NavigateParams(in); - } - - @Override - public NavigateParams[] newArray(int size) { - return new NavigateParams[size]; - } - }; - - public NavigateParams() {} - - private NavigateParams(Parcel in) { - readFromParcel(in); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(mShouldReplaceCurrentEntry ? 1 : 0); - } - - public void readFromParcel(Parcel in) { - mShouldReplaceCurrentEntry = in.readInt() == 1; - } - - @Override - public int describeContents() { - return 0; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigationState.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigationState.java deleted file mode 100644 index aad805bd44..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NavigationState.java +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({NavigationState.WAITING_RESPONSE, NavigationState.RECEIVING_BYTES, - NavigationState.COMPLETE, NavigationState.FAILED}) -@Retention(RetentionPolicy.SOURCE) -public @interface NavigationState { - int WAITING_RESPONSE = 0; - int RECEIVING_BYTES = 1; - int COMPLETE = 2; - int FAILED = 3; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NewTabType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NewTabType.java deleted file mode 100644 index 19e4b9c..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/NewTabType.java +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({NewTabType.FOREGROUND_TAB, NewTabType.BACKGROUND_TAB, NewTabType.NEW_POPUP, - NewTabType.NEW_WINDOW}) -@Retention(RetentionPolicy.SOURCE) -public @interface NewTabType { - int FOREGROUND_TAB = 0; - int BACKGROUND_TAB = 1; - int NEW_POPUP = 2; - int NEW_WINDOW = 3; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ObjectWrapper.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ObjectWrapper.java deleted file mode 100644 index 9bc64f6e..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ObjectWrapper.java +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.os.IBinder; - -import java.lang.reflect.Field; - -/** - * This wraps an object to be transferred across sibling classloaders in the same process via the - * IObjectWrapper AIDL interface. By using reflection to retrieve the object, no serialization needs - * to occur. - * - * @param <T> The type of the wrapped object. - */ -public final class ObjectWrapper<T> extends IObjectWrapper.Stub { - /** - * The wrapped object. You must not add another member in this class because the check for - * retrieving this member variable is that this is the ONLY member variable declared in this - * class and it is private. This is because ObjectWrapper can be obfuscated, so that this member - * variable can have an obfuscated name. - */ - private final T mWrappedObject; - - /* DO NOT ADD NEW CLASS MEMBERS (see above) */ - - /** Disable creating an object wrapper. Instead, use {@link #wrap(Object)}. */ - private ObjectWrapper(T object) { - mWrappedObject = object; - } - - /** - * Create the wrapped object. - * - * @param object The object instance to wrap. - * @return The wrapped object. - */ - public static <T> IObjectWrapper wrap(T object) { - return new ObjectWrapper<T>(object); - } - - /** - * Unwrap the object within the {@link IObjectWrapper} using reflection. - * - * @param remote The {@link IObjectWrapper} instance to unwrap. - * @param clazz The {@link Class} of the unwrapped object type. - * @return The unwrapped object. - */ - public static <T> T unwrap(IObjectWrapper remote, Class<T> clazz) { - if (remote == null) return null; - - // Handle the case when not getting an IObjectWrapper from a sibling classloader - if (remote instanceof ObjectWrapper) { - @SuppressWarnings("unchecked") - ObjectWrapper<T> typedRemote = ((ObjectWrapper<T>) remote); - return typedRemote.mWrappedObject; - } - - IBinder remoteBinder = remote.asBinder(); - - // It is possible that ObjectWrapper was obfuscated in which case wrappedObject - // would have a different name. The following checks that there is a single - // declared field that is private. - Class<?> remoteClazz = remoteBinder.getClass(); - - Field validField = null; - for (Field field : remoteClazz.getDeclaredFields()) { - if (field.isSynthetic()) continue; - - // Only one valid, non-synthetic field is allowed on the class. - if (validField != null) { - validField = null; - break; - } - validField = field; - } - - if (validField == null || validField.isAccessible()) { - throw new IllegalArgumentException("The concrete class implementing IObjectWrapper" - + " must have exactly *one* declared *private* field for the wrapped object. " - + " Preferably, this is an instance of the ObjectWrapper<T> class."); - } - - validField.setAccessible(true); - try { - Object wrappedObject = validField.get(remoteBinder); - if (wrappedObject == null) return null; - if (!clazz.isInstance(wrappedObject)) { - throw new IllegalArgumentException("remoteBinder is the wrong class."); - } - return clazz.cast(wrappedObject); - } catch (NullPointerException e) { - throw new IllegalArgumentException("Binder object is null.", e); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("remoteBinder is the wrong class.", e); - } catch (IllegalAccessException e) { - throw new IllegalArgumentException("Could not access the field in remoteBinder.", e); - } - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py deleted file mode 100644 index 9d91afdc..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py +++ /dev/null
@@ -1,176 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Presubmit tests for weblayer. - -Used to verify incompatible changes have not been done to AIDL files. -""" - -import glob -import logging -import os -import shutil -import subprocess -import sys -import tempfile - -_INCOMPATIBLE_API_ERROR_STRING = """You have made an incompatible API change. -Generally this means one of the following: - A function has been removed. - The arguments of a function has changed. -This tool also reports renames as errors, which are generally okay. -If the API you are changing was added in the current release, you can -safely ignore this warning.""" - -class AidlFile: - """Provides information about an aidl file in the repo.""" - def __init__(self, f): - # The AffectedFile. - self.affected_file = f - # Path of the aidl file in the repo, this is the full absolute path. - self.path_in_repo = f.AbsoluteLocalPath() - # Absolute path to where java files start. - self.java_root_dir = '' - # Package names of the file. - self.packages = [] - # Name part of the file, e.g. IBrowser.aidl. - self.file_name = os.path.basename(self.path_in_repo) - current_dir = self.path_in_repo - packages = [] - while current_dir != '': - dir_name, base_name = os.path.split(current_dir) - packages.append(base_name) - if base_name == 'org': - packages.reverse() - self.java_root_dir = dir_name - # Last item is the file name - packages.pop() - self.packages = packages - break - parent_dir = dir_name - if current_dir == parent_dir: - logging.warn('Unable to find file system root for %s', - self.path_in_repo) - break - current_dir = parent_dir - - def IsValid(self): - """Returns true if this is a valid aidl file.""" - return len(self.packages) > 0 - - def GetPathRelativeTo(self, other_dir): - """Returns the path of the file relative to another directory. - - The path is built using the java packages. - """ - return os.path.join(os.path.join(other_dir, *self.packages), self.file_name) - - -def _CompareApiDumpForFiles(input_api, output_api, aidl_files): - if len(aidl_files) == 0: - return [] - # These tests fail to run on Windows (devil_chromium needs some non-standard - # Windows modules) and given the Android dependencies this is reasonable. - if input_api.is_windows: - return [] - - repo_root = input_api.change.RepositoryRoot() - build_android_dir = os.path.join(repo_root, 'build', 'android') - sys.path.append(build_android_dir) - sys.path.append(os.path.join(repo_root, 'third_party', 'catapult', 'devil')) - import devil_chromium - from devil.android.sdk import build_tools - devil_chromium.Initialize() - - try: - aidl_tool_path = build_tools.GetPath('aidl') - except Exception as e: - if input_api.no_diffs: - # If we are running presubmits with --all or --files and the 'aidl' tool - # cannot be found then that probably means that target_os = 'android' is - # missing from .gclient and the failure is not interesting. - return [] - if not os.path.exists(aidl_tool_path): - return [output_api.PresubmitError( - 'Android sdk does not contain aidl command ' + aidl_tool_path)] - - framework_aidl_path = glob.glob(os.path.join( - input_api.change.RepositoryRoot(), 'third_party', 'android_sdk', - 'public', 'platforms', '*', 'framework.aidl'))[0] - logging.debug('Using framework.aidl at path %s', framework_aidl_path) - - tmp_old_contents_dir = tempfile.mkdtemp() - tmp_old_aidl_dir = tempfile.mkdtemp() - tmp_new_aidl_dir = tempfile.mkdtemp() - aidl_src_dir = aidl_files[0].java_root_dir - generate_old_api_cmd = [aidl_tool_path, '--dumpapi', '--out', - tmp_old_aidl_dir, - ('-p' + framework_aidl_path), - ('-I' + aidl_src_dir)] - generate_new_api_cmd = [aidl_tool_path, '--dumpapi', '--out', - tmp_new_aidl_dir, - ('-p' + framework_aidl_path), - ('-I' + aidl_src_dir)] - - # The following generates the aidl api dump (both original and new) for any - # changed file. The dumps are then compared using --checkapi. - try: - valid_file = False - for aidl_file in aidl_files: - old_contents = '\n'.join(aidl_file.affected_file.OldContents()) - if len(old_contents) == 0: - # When |old_contents| is empty it indicates a new file, which is - # implicitly compatible. - continue - old_contents_file_path = aidl_file.GetPathRelativeTo(tmp_old_contents_dir) - # aidl expects the directory to match the java package names. - if not os.path.isdir(os.path.dirname(old_contents_file_path)): - os.makedirs(os.path.dirname(old_contents_file_path)) - with open(old_contents_file_path, 'w') as old_contents_file: - old_contents_file.write(old_contents) - generate_old_api_cmd += [old_contents_file_path] - generate_new_api_cmd += [aidl_file.path_in_repo] - valid_file = True - - if not valid_file: - return [] - - logging.debug('Generating old api %s', generate_old_api_cmd) - result = subprocess.call(generate_old_api_cmd) - if result != 0: - return [output_api.PresubmitError('Error generating old aidl api dump')] - - logging.debug('Generating new api %s', generate_new_api_cmd) - result = subprocess.call(generate_new_api_cmd) - if result != 0: - return [output_api.PresubmitError('Error generating new aidl api')] - - logging.debug('Diffing api') - result = subprocess.call([aidl_tool_path, '--checkapi', - tmp_old_aidl_dir, tmp_new_aidl_dir]) - if result != 0: - return [output_api.PresubmitPromptWarning(_INCOMPATIBLE_API_ERROR_STRING)] - finally: - shutil.rmtree(tmp_old_contents_dir) - shutil.rmtree(tmp_old_aidl_dir) - shutil.rmtree(tmp_new_aidl_dir) - return [] - - -def CheckChangeOnUpload(input_api, output_api): - filter_lambda = lambda x: input_api.FilterSourceFile( - x, files_to_check=[r'.*\.aidl$' ]) - aidl_files = [] - for f in input_api.AffectedFiles(include_deletes=False, - file_filter=filter_lambda): - aidl_file = AidlFile(f) - logging.debug('Possible aidl file %s', f.AbsoluteLocalPath()) - if aidl_file.IsValid(): - aidl_files.append(aidl_file) - else: - logging.warn('File matched aidl extension, but not valid ' + - f.AbsoluteLocalPath()) - if len(aidl_files) == 0: - return [] - return _CompareApiDumpForFiles(input_api, output_api, aidl_files)
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java deleted file mode 100644 index e3f9757..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** Keys for remote media service intent extras. */ -public interface RemoteMediaServiceConstants { - // Used as a key in the client's AndroidManifest.xml to enable remote media playback, i.e. - // Presentation API, Remote Playback API, and Media Fling (automatic casting of html5 videos). - // This exists because clients that already integrate with GMSCore cast framework may find WL's - // integration problematic and need to turn it off. To use this, the application's - // AndroidManifest.xml should have a meta-data tag with this name and value of false. The - // default is true, i.e. enabled. - // TODO(crbug.com/1148410): remove this. - String FEATURE_ENABLED_KEY = "org.chromium.weblayer.ENABLE_REMOTE_MEDIA"; - - // Used internally by WebLayer as a key to the various values of remote media service - // notification IDs. - String NOTIFICATION_ID_KEY = "REMOTE_MEDIA_SERVICE_NOTIFICATION_ID_KEY"; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ScrollNotificationType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ScrollNotificationType.java deleted file mode 100644 index 0f713f3..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ScrollNotificationType.java +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ScrollNotificationType.DIRECTION_CHANGED_UP, - ScrollNotificationType.DIRECTION_CHANGED_DOWN}) -@Retention(RetentionPolicy.SOURCE) -public @interface ScrollNotificationType { - int DIRECTION_CHANGED_UP = 0; - int DIRECTION_CHANGED_DOWN = 1; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/SettingType.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/SettingType.java deleted file mode 100644 index a54f0dd..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/SettingType.java +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({SettingType.BASIC_SAFE_BROWSING_ENABLED, SettingType.UKM_ENABLED, - SettingType.EXTENDED_REPORTING_SAFE_BROWSING_ENABLED, - SettingType.REAL_TIME_SAFE_BROWSING_ENABLED, SettingType.NETWORK_PREDICTION_ENABLED}) -@Retention(RetentionPolicy.SOURCE) -public @interface SettingType { - int BASIC_SAFE_BROWSING_ENABLED = 0; - int UKM_ENABLED = 1; - int EXTENDED_REPORTING_SAFE_BROWSING_ENABLED = 2; - int REAL_TIME_SAFE_BROWSING_ENABLED = 3; - int NETWORK_PREDICTION_ENABLED = 4; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java deleted file mode 100644 index 11535cc..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -import android.os.Parcel; -import android.os.StrictMode; -import android.util.Log; - -import java.lang.reflect.Field; - -/** - * Workaround to unset PENALTY_GATHER in StrictMode. - * Normally the serialization code to set the PENALTY_GATHER bit in each AIDL - * call and the IPC code unsets the bit. WebLayer only uses AIDL for - * serialization, but not IPC; this leaves the PENALTY_GATHER bit always set, - * causing any StrictMode violations to be gathered and serialized in ever AIDL - * call but never reported. - * StrictModeWorkaround.apply will unset the PENALTY_GATHER bit and should be - * called at the beginning of the implementation of an AIDL call. - */ -public final class StrictModeWorkaround { - private static final String TAG = "StrictModeWorkaround"; - - private static final int PENALTY_GATHER; - private static final Field sThreadPolicyMaskField; - static { - Field field; - int mask; - try { - field = StrictMode.ThreadPolicy.class.getDeclaredField("mask"); - field.setAccessible(true); - - int currentMask = getCurrentPolicyMask(field); - try { - setCurrentPolicyMask(field, 0); - - // The value of PENALTY_GATHER has changed between Android - // versions. Instead of hard coding them, try to get the value - // from Parcel directly. - Parcel parcel = Parcel.obtain(); - // The value of the token does not matter. - parcel.writeInterfaceToken(TAG); - parcel.setDataPosition(0); - mask = parcel.readInt(); - parcel.recycle(); - } finally { - setCurrentPolicyMask(field, currentMask); - } - } catch (NoSuchFieldException | SecurityException e) { - Log.w(TAG, "StrictMode reflection exception", e); - field = null; - mask = 0; - } catch (RuntimeException e) { - Log.w(TAG, "StrictMode run time exception", e); - field = null; - mask = 0; - } - sThreadPolicyMaskField = field; - PENALTY_GATHER = mask; - } - - private static int getCurrentPolicyMask(Field field) { - StrictMode.ThreadPolicy policy = StrictMode.getThreadPolicy(); - try { - return field.getInt(policy); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - private static void setCurrentPolicyMask(Field field, int newPolicyMask) { - StrictMode.ThreadPolicy policy = StrictMode.getThreadPolicy(); - try { - field.setInt(policy, newPolicyMask); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - StrictMode.setThreadPolicy(policy); - } - - public static void apply() { - if (sThreadPolicyMaskField == null) return; - try { - int currentPolicyMask = getCurrentPolicyMask(sThreadPolicyMaskField); - if ((currentPolicyMask & PENALTY_GATHER) == 0) { - return; - } - setCurrentPolicyMask(sThreadPolicyMaskField, currentPolicyMask & ~PENALTY_GATHER); - } catch (RuntimeException e) { - // Ignore exceptions. - } - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java deleted file mode 100644 index 491515c6..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.interfaces; - -/** - * Versioning related constants. - */ -public interface WebLayerVersionConstants { - /** - * Maximum allowed version skew. If the skew is greater than this, the implementation and client - * are not considered compatible, and WebLayer is unusable. The skew is the absolute value of - * the difference between the client major version and the implementation major version. - * - * @see WebLayer#isAvailable() - */ - int MAX_SKEW = 9; - - /** - * Minimum version of client and implementation. - */ - int MIN_VERSION = 87; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java deleted file mode 100644 index 76586a4..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.media; - -import android.content.Context; - -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory; -import org.chromium.weblayer_private.FragmentHostingRemoteFragmentImpl; -import org.chromium.weblayer_private.R; -import org.chromium.weblayer_private.interfaces.IMediaRouteDialogFragment; -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.lang.ref.WeakReference; - -/** - * WebLayer's implementation of the client library's MediaRouteDialogFragment. - * - * This class is the impl-side representation of a client fragment which is added to the browser - * fragment, and is parent to MediaRouter-related {@link DialogFragment} instances. This class will - * automatically clean up the client-side fragment when the child fragment is detached. - */ -public class MediaRouteDialogFragmentImpl extends FragmentHostingRemoteFragmentImpl { - // The instance for the currently active dialog, if any. This is a WeakReference to get around - // StaticFieldLeak warnings. - private static WeakReference<MediaRouteDialogFragmentImpl> sInstanceForTest; - - private static class MediaRouteDialogContext - extends FragmentHostingRemoteFragmentImpl.RemoteFragmentContext { - public MediaRouteDialogContext(Context embedderContext) { - super(ClassLoaderContextWrapperFactory.get(embedderContext)); - // TODO(estade): this is necessary because MediaRouter dialogs crash if the theme has an - // action bar. It's unclear why this is necessary when it's not in Chrome, and why - // ContextThemeWrapper doesn't work. - getTheme().applyStyle(R.style.Theme_BrowserUI_DayNight, /*force=*/true); - } - } - - public MediaRouteDialogFragmentImpl(Context context) { - super(context); - sInstanceForTest = new WeakReference<MediaRouteDialogFragmentImpl>(this); - } - - @Override - public void onAttach(Context context) { - StrictModeWorkaround.apply(); - super.onAttach(context); - - // Remove the host fragment as soon as the media router dialog fragment is detached. - getSupportFragmentManager().registerFragmentLifecycleCallbacks( - new FragmentManager.FragmentLifecycleCallbacks() { - @Override - public void onFragmentDetached(FragmentManager fm, Fragment f) { - MediaRouteDialogFragmentImpl.this.removeFragmentFromFragmentManager(); - } - }, - false); - } - - @Override - protected FragmentHostingRemoteFragmentImpl.RemoteFragmentContext createRemoteFragmentContext( - Context embedderContext) { - return new MediaRouteDialogContext(embedderContext); - } - - public IMediaRouteDialogFragment asIMediaRouteDialogFragment() { - return new IMediaRouteDialogFragment.Stub() { - @Override - public IRemoteFragment asRemoteFragment() { - StrictModeWorkaround.apply(); - return MediaRouteDialogFragmentImpl.this; - } - }; - } - - public static MediaRouteDialogFragmentImpl fromRemoteFragment(IRemoteFragment remoteFragment) { - return (MediaRouteDialogFragmentImpl) remoteFragment; - } - - public static MediaRouteDialogFragmentImpl getInstanceForTest() { - return sInstanceForTest.get(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java deleted file mode 100644 index 027ed85..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java +++ /dev/null
@@ -1,198 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.media; - -import android.app.Application; -import android.app.Service; -import android.content.Context; -import android.content.ContextWrapper; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.support.v4.media.session.MediaSessionCompat; - -import androidx.fragment.app.FragmentManager; -import androidx.mediarouter.media.MediaRouter; - -import org.chromium.base.ContextUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.components.browser_ui.media.MediaNotificationController; -import org.chromium.components.browser_ui.media.MediaNotificationInfo; -import org.chromium.components.browser_ui.media.MediaNotificationManager; -import org.chromium.components.browser_ui.notifications.NotificationWrapper; -import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder; -import org.chromium.components.media_router.MediaRouterClient; -import org.chromium.content_public.browser.WebContents; -import org.chromium.weblayer_private.IntentUtils; -import org.chromium.weblayer_private.TabImpl; -import org.chromium.weblayer_private.WebLayerFactoryImpl; -import org.chromium.weblayer_private.WebLayerImpl; -import org.chromium.weblayer_private.interfaces.RemoteMediaServiceConstants; - -/** Provides WebLayer-specific behavior for Media Router. */ -@JNINamespace("weblayer") -public class MediaRouterClientImpl extends MediaRouterClient { - static int sPresentationNotificationId; - static int sRemotingNotificationId; - - private MediaRouterClientImpl() {} - - public static void serviceStarted(Service service, Intent intent) { - int notificationId = intent.getIntExtra(RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, 0); - if (notificationId == 0) { - throw new RuntimeException("Invalid RemoteMediaService notification id"); - } - MediaSessionNotificationHelper.serviceStarted(service, intent, notificationId); - } - - public static void serviceDestroyed(int notificationId) { - MediaSessionNotificationHelper.serviceDestroyed(notificationId); - } - - @Override - public Context getContextForRemoting() { - return getContextForRemotingImpl(); - } - - @Override - public int getTabId(WebContents webContents) { - TabImpl tab = TabImpl.fromWebContents(webContents); - return tab == null ? -1 : tab.getId(); - } - - @Override - public Intent createBringTabToFrontIntent(int tabId) { - return IntentUtils.createBringTabToFrontIntent(tabId); - } - - @Override - public void showNotification(MediaNotificationInfo notificationInfo) { - MediaNotificationManager.show(notificationInfo, () -> { - return new MediaRouterNotificationControllerDelegate(notificationInfo.id); - }); - } - - @Override - public int getPresentationNotificationId() { - return getPresentationNotificationIdFromClient(); - } - - @Override - public int getRemotingNotificationId() { - return getRemotingNotificationIdFromClient(); - } - - @Override - public FragmentManager getSupportFragmentManager(WebContents initiator) { - return null; - } - - @Override - // TODO(crbug.com/1377518): Implement addDeferredTask(). - public void addDeferredTask(Runnable deferredTask) { - deferredTask.run(); - } - - @Override - public boolean isCastAnotherContentWhileCastingEnabled() { - return true; - } - - @CalledByNative - public static void initialize() { - if (MediaRouterClient.getInstance() != null) return; - - MediaRouterClient.setInstance(new MediaRouterClientImpl()); - } - - @CalledByNative - public static boolean isMediaRouterEnabled() { - if (WebLayerFactoryImpl.getClientMajorVersion() < 88) return false; - - Context context = ContextUtils.getApplicationContext(); - try { - ApplicationInfo ai = context.getPackageManager().getApplicationInfo( - context.getPackageName(), PackageManager.GET_META_DATA); - return ai.metaData.getBoolean(RemoteMediaServiceConstants.FEATURE_ENABLED_KEY, true); - } catch (NameNotFoundException e) { - return true; - } - } - - private static class MediaRouterNotificationControllerDelegate - implements MediaNotificationController.Delegate { - // The ID distinguishes between Presentation and Remoting services/notifications. - private final int mNotificationId; - - MediaRouterNotificationControllerDelegate(int notificationId) { - mNotificationId = notificationId; - } - - @Override - public Intent createServiceIntent() { - return WebLayerImpl.createRemoteMediaServiceIntent().putExtra( - RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, mNotificationId); - } - - @Override - public String getAppName() { - return WebLayerImpl.getClientApplicationName(); - } - - @Override - public String getNotificationGroupName() { - if (mNotificationId == getPresentationNotificationIdFromClient()) { - return "org.chromium.weblayer.PresentationApi"; - } - - assert mNotificationId == getRemotingNotificationIdFromClient(); - return "org.chromium.weblayer.RemotePlaybackApi"; - } - - @Override - public NotificationWrapperBuilder createNotificationWrapperBuilder() { - return MediaSessionNotificationHelper.createNotificationWrapperBuilder(mNotificationId); - } - - @Override - public void onMediaSessionUpdated(MediaSessionCompat session) { - MediaRouter.getInstance(getContextForRemotingImpl()).setMediaSessionCompat(session); - } - - @Override - public void logNotificationShown(NotificationWrapper notification) {} - } - - private static int getPresentationNotificationIdFromClient() { - if (sPresentationNotificationId == 0) { - sPresentationNotificationId = WebLayerImpl.getPresentationApiNotificationId(); - } - return sPresentationNotificationId; - } - - private static int getRemotingNotificationIdFromClient() { - if (sRemotingNotificationId == 0) { - sRemotingNotificationId = WebLayerImpl.getRemotePlaybackApiNotificationId(); - } - return sRemotingNotificationId; - } - - private static Context getContextForRemotingImpl() { - Context context = ContextUtils.getApplicationContext(); - // The GMS Cast framework assumes the passed {@link Context} returns an instance of {@link - // Application} from {@link getApplicationContext()}, so we make sure to remove any - // wrappers. - while (!(context.getApplicationContext() instanceof Application)) { - if (context instanceof ContextWrapper) { - context = ((ContextWrapper) context).getBaseContext(); - } else { - return null; - } - } - return context; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java deleted file mode 100644 index ef1ca217..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java +++ /dev/null
@@ -1,114 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.media; - -import android.app.Service; -import android.content.Intent; -import android.support.v4.media.session.MediaSessionCompat; - -import org.chromium.components.browser_ui.media.MediaNotificationController; -import org.chromium.components.browser_ui.media.MediaNotificationInfo; -import org.chromium.components.browser_ui.media.MediaNotificationManager; -import org.chromium.components.browser_ui.media.MediaSessionHelper; -import org.chromium.components.browser_ui.notifications.NotificationWrapper; -import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder; -import org.chromium.content_public.browser.BrowserContextHandle; -import org.chromium.weblayer_private.IntentUtils; -import org.chromium.weblayer_private.TabImpl; -import org.chromium.weblayer_private.WebLayerImpl; - -/** - * A glue class for MediaSession. - * This class defines delegates that provide WebLayer-specific behavior to shared MediaSession code. - * It also manages the lifetime of {@link MediaNotificationController} and the {@link Service} - * associated with the notification. - */ -public class MediaSessionManager { - private static int sNotificationId; - - public static void serviceStarted(Service service, Intent intent) { - MediaSessionNotificationHelper.serviceStarted(service, intent, getNotificationId()); - } - - public static void serviceDestroyed() { - MediaSessionNotificationHelper.serviceDestroyed(getNotificationId()); - } - - public static MediaSessionHelper.Delegate createMediaSessionHelperDelegate(TabImpl tab) { - return new MediaSessionHelper.Delegate() { - @Override - public Intent createBringTabToFrontIntent() { - return IntentUtils.createBringTabToFrontIntent(tab.getId()); - } - - @Override - public BrowserContextHandle getBrowserContextHandle() { - return tab.getProfile(); - } - - @Override - public MediaNotificationInfo.Builder createMediaNotificationInfoBuilder() { - return new MediaNotificationInfo.Builder() - .setInstanceId(tab.getId()) - .setId(getNotificationId()); - } - - @Override - public void showMediaNotification(MediaNotificationInfo notificationInfo) { - assert notificationInfo.id == getNotificationId(); - MediaNotificationManager.show(notificationInfo, - () -> { return new WebLayerMediaNotificationControllerDelegate(); }); - } - - @Override - public void hideMediaNotification() { - MediaNotificationManager.hide(tab.getId(), getNotificationId()); - } - - @Override - public void activateAndroidMediaSession() { - MediaNotificationManager.activateAndroidMediaSession( - tab.getId(), getNotificationId()); - } - }; - } - - private static class WebLayerMediaNotificationControllerDelegate - implements MediaNotificationController.Delegate { - @Override - public Intent createServiceIntent() { - return WebLayerImpl.createMediaSessionServiceIntent(); - } - - @Override - public String getAppName() { - return WebLayerImpl.getClientApplicationName(); - } - - @Override - public String getNotificationGroupName() { - return "org.chromium.weblayer.MediaSession"; - } - - @Override - public NotificationWrapperBuilder createNotificationWrapperBuilder() { - return MediaSessionNotificationHelper.createNotificationWrapperBuilder( - getNotificationId()); - } - - @Override - public void onMediaSessionUpdated(MediaSessionCompat session) { - // This is only relevant when casting. - } - - @Override - public void logNotificationShown(NotificationWrapper notification) {} - } - - private static int getNotificationId() { - if (sNotificationId == 0) sNotificationId = WebLayerImpl.getMediaSessionNotificationId(); - return sNotificationId; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java deleted file mode 100644 index 58aab7f1..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.media; - -import android.app.Service; -import android.content.Intent; - -import org.chromium.components.browser_ui.media.MediaNotificationController; -import org.chromium.components.browser_ui.media.MediaNotificationManager; -import org.chromium.components.browser_ui.notifications.ForegroundServiceUtils; -import org.chromium.components.browser_ui.notifications.NotificationMetadata; -import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder; -import org.chromium.weblayer_private.WebLayerNotificationChannels; -import org.chromium.weblayer_private.WebLayerNotificationWrapperBuilder; - -/** - * A helper class for management of MediaSession (local device), Presentation API and Remote - * Playback API (casting) notifications and foreground services. - */ -class MediaSessionNotificationHelper { - static void serviceStarted(Service service, Intent intent, int notificationId) { - MediaNotificationController controller = - MediaNotificationManager.getController(notificationId); - if (controller != null && controller.processIntent(service, intent)) return; - - // The service has been started with startForegroundService() but the - // notification hasn't been shown. See similar logic in {@link - // ChromeMediaNotificationControllerDelegate}. - MediaNotificationController.finishStartingForegroundServiceOnO(service, - createNotificationWrapperBuilder(notificationId).buildNotificationWrapper()); - // Call stopForeground to guarantee Android unset the foreground bit. - ForegroundServiceUtils.getInstance().stopForeground( - service, Service.STOP_FOREGROUND_REMOVE); - service.stopSelf(); - } - - static void serviceDestroyed(int notificationId) { - MediaNotificationController controller = - MediaNotificationManager.getController(notificationId); - if (controller != null) controller.onServiceDestroyed(); - MediaNotificationManager.clear(notificationId); - } - - static NotificationWrapperBuilder createNotificationWrapperBuilder(int notificationId) { - // Only the null tag will work as expected, because {@link Service#startForeground()} only - // takes an ID and no tag. If we pass a tag here, then the notification that's used to - // display a paused state (no foreground service) will not be identified as the same one - // that's used with the foreground service. - return WebLayerNotificationWrapperBuilder.create( - WebLayerNotificationChannels.ChannelId.MEDIA_PLAYBACK, - new NotificationMetadata(0, null /*notificationTag*/, notificationId)); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaStreamManager.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaStreamManager.java deleted file mode 100644 index d74fd785..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaStreamManager.java +++ /dev/null
@@ -1,220 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.media; - -import android.app.NotificationManager; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.RemoteException; -import android.util.AndroidRuntimeException; -import android.webkit.ValueCallback; - -import org.chromium.base.ContextUtils; -import org.chromium.base.ThreadUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxy; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; -import org.chromium.components.browser_ui.notifications.NotificationMetadata; -import org.chromium.components.browser_ui.notifications.NotificationWrapper; -import org.chromium.components.browser_ui.notifications.PendingIntentProvider; -import org.chromium.components.webrtc.MediaCaptureNotificationUtil; -import org.chromium.components.webrtc.MediaCaptureNotificationUtil.MediaType; -import org.chromium.content_public.browser.WebContents; -import org.chromium.weblayer_private.IntentUtils; -import org.chromium.weblayer_private.TabImpl; -import org.chromium.weblayer_private.WebLayerImpl; -import org.chromium.weblayer_private.WebLayerNotificationChannels; -import org.chromium.weblayer_private.WebLayerNotificationWrapperBuilder; -import org.chromium.weblayer_private.interfaces.IMediaCaptureCallbackClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -import java.util.HashSet; -import java.util.Set; - -/** - * A per-tab object that manages notifications for ongoing media capture streams - * (microphone/camera). This object is created by {@link TabImpl} and creates and destroys its - * native equivalent. - */ -@JNINamespace("weblayer") -public class MediaStreamManager { - private static final String WEBRTC_PREFIX = "org.chromium.weblayer.webrtc"; - private static final String AV_STREAM_TAG = WEBRTC_PREFIX + ".avstream"; - - /** - * A key used in the app's shared preferences to track a set of active streaming notifications. - * This is used to clear notifications that may have persisted across restarts due to a crash. - * TODO(estade): remove this approach and simply iterate across all notifications via - * {@link NotificationManager#getActiveNotifications} once the minimum API level is 23. - */ - private static final String PREF_ACTIVE_AV_STREAM_NOTIFICATION_IDS = - WEBRTC_PREFIX + ".avstream_notifications"; - - private IMediaCaptureCallbackClient mClient; - - private TabImpl mTab; - - // The notification ID matches the tab ID, which uniquely identifies the notification when - // paired with the tag. - private int mNotificationId; - - // Pointer to the native MediaStreamManager. - private long mNative; - - /** - * To be called when WebLayer is started. Clears notifications that may have persisted from - * before a crash. - */ - public static void onWebLayerInit() { - SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); - Set<String> staleNotificationIds = - prefs.getStringSet(PREF_ACTIVE_AV_STREAM_NOTIFICATION_IDS, null); - if (staleNotificationIds == null) return; - - NotificationManagerProxy manager = getNotificationManager(); - if (manager == null) return; - - for (String id : staleNotificationIds) { - manager.cancel(AV_STREAM_TAG, Integer.parseInt(id)); - } - prefs.edit().remove(PREF_ACTIVE_AV_STREAM_NOTIFICATION_IDS).apply(); - } - - public MediaStreamManager(TabImpl tab) { - mTab = tab; - mNotificationId = tab.getId(); - mNative = MediaStreamManagerJni.get().create(this, tab.getWebContents()); - } - - public void destroy() { - cancelNotification(); - MediaStreamManagerJni.get().destroy(mNative); - mNative = 0; - mClient = null; - } - - public void setClient(IMediaCaptureCallbackClient client) { - mClient = client; - } - - public void stopStreaming() { - MediaStreamManagerJni.get().stopStreaming(mNative); - } - - private void cancelNotification() { - NotificationManagerProxy notificationManager = getNotificationManager(); - if (notificationManager != null) { - notificationManager.cancel(AV_STREAM_TAG, mNotificationId); - } - notifyClient(false, false); - updateActiveNotifications(false); - } - - private void notifyClient(boolean audio, boolean video) { - if (mClient != null) { - try { - mClient.onMediaCaptureStateChanged(audio, video); - } catch (RemoteException e) { - throw new AndroidRuntimeException(e); - } - } - } - - /** - * Updates the list of active notifications stored in the SharedPrefences. - * - * @param active if true, then {@link mNotificationId} will be added to the list of active - * notifications, otherwise it will be removed. - */ - private void updateActiveNotifications(boolean active) { - SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); - Set<String> activeIds = new HashSet<String>( - prefs.getStringSet(PREF_ACTIVE_AV_STREAM_NOTIFICATION_IDS, new HashSet<String>())); - if (active) { - activeIds.add(Integer.toString(mNotificationId)); - } else { - activeIds.remove(Integer.toString(mNotificationId)); - } - prefs.edit() - .putStringSet(PREF_ACTIVE_AV_STREAM_NOTIFICATION_IDS, - activeIds.isEmpty() ? null : activeIds) - .apply(); - } - - @CalledByNative - private void prepareToStream(boolean audio, boolean video, int requestId) - throws RemoteException { - if (mClient == null) { - respondToStreamRequest(requestId, true); - } else { - mClient.onMediaCaptureRequested( - audio, video, ObjectWrapper.wrap(new ValueCallback<Boolean>() { - @Override - public void onReceiveValue(Boolean allowed) { - ThreadUtils.assertOnUiThread(); - respondToStreamRequest(requestId, allowed.booleanValue()); - } - })); - } - } - - private void respondToStreamRequest(int requestId, boolean allow) { - if (mNative == 0) return; - MediaStreamManagerJni.get().onClientReadyToStream(mNative, requestId, allow); - } - - /** - * Called after the tab's media streaming state has changed. - * - * A notification should be shown (or updated) iff one of the parameters is true, otherwise - * any existing notification will be removed. - * - * @param audio true if the tab is streaming audio. - * @param video true if the tab is streaming video. - */ - @CalledByNative - private void update(boolean audio, boolean video) { - if (!audio && !video) { - cancelNotification(); - return; - } - - Context appContext = ContextUtils.getApplicationContext(); - Intent intent = IntentUtils.createBringTabToFrontIntent(mNotificationId); - PendingIntentProvider contentIntent = - PendingIntentProvider.getBroadcast(appContext, mNotificationId, intent, 0); - - int mediaType = audio && video ? MediaType.AUDIO_AND_VIDEO - : audio ? MediaType.AUDIO_ONLY : MediaType.VIDEO_ONLY; - - NotificationWrapper notification = MediaCaptureNotificationUtil.createNotification( - WebLayerNotificationWrapperBuilder.create( - WebLayerNotificationChannels.ChannelId.WEBRTC_CAM_AND_MIC, - new NotificationMetadata(0, AV_STREAM_TAG, mNotificationId)), - mediaType, - mTab.getProfile().isIncognito() ? null - : mTab.getWebContents().getVisibleUrl().getSpec(), - WebLayerImpl.getClientApplicationName(), contentIntent, null /*stopIntent*/); - getNotificationManager().notify(notification); - - updateActiveNotifications(true); - notifyClient(audio, video); - } - - private static NotificationManagerProxy getNotificationManager() { - return new NotificationManagerProxyImpl(ContextUtils.getApplicationContext()); - } - - @NativeMethods - interface Natives { - long create(MediaStreamManager caller, WebContents webContents); - void destroy(long manager); - void onClientReadyToStream(long nativeMediaStreamManager, int requestId, boolean allow); - void stopStreaming(long nativeMediaStreamManager); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/metrics/MetricsServiceClient.java b/weblayer/browser/java/org/chromium/weblayer_private/metrics/MetricsServiceClient.java deleted file mode 100644 index 7d01a3a2..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/metrics/MetricsServiceClient.java +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.metrics; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; - -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer_private.GmsBridge; - -/** - * Determines user consent and app opt-out for metrics. See metrics_service_client.h for more - * explanation. - * - * TODO(weblayer-team): Consider compoentizing once requirements are nailed down. - */ -@JNINamespace("weblayer") -public class MetricsServiceClient { - private static final String TAG = "MetricsServiceClie-"; - - // Individual apps can use this meta-data tag in their manifest to opt out of metrics. - private static final String AUTO_UPLOAD_METADATA_STR = "android.WebLayer.MetricsAutoUpload"; - - private static boolean isAppOptedOut(Context ctx) { - try { - ApplicationInfo info = ctx.getPackageManager().getApplicationInfo( - ctx.getPackageName(), PackageManager.GET_META_DATA); - if (info.metaData == null) { - // null means no such tag was found which we interpret as not opting out. - return false; - } - // getBoolean returns false if the key is not found, which is what we want. - return info.metaData.getBoolean(AUTO_UPLOAD_METADATA_STR); - } catch (PackageManager.NameNotFoundException e) { - // This should never happen. - Log.e(TAG, "App could not find itself by package name!"); - // The conservative thing is to assume the app HAS opted out. - return true; - } - } - - public static void init() { - GmsBridge.getInstance().queryMetricsSetting(userConsent -> { - MetricsServiceClientJni.get().setHaveMetricsConsent( - userConsent, !isAppOptedOut(ContextUtils.getApplicationContext())); - }); - } - - @NativeMethods - interface Natives { - void setHaveMetricsConsent(boolean userConsent, boolean appConsent); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java b/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java deleted file mode 100644 index a7f2a3d..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.metrics; - -import android.os.SystemClock; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; - -/** - * Utilities to support startup metrics - */ -@JNINamespace("weblayer") -public class UmaUtils { - private static long sApplicationStartTimeMs; - - /** - * Record the time in the application lifecycle at which WebLayer code first runs. - */ - public static void recordMainEntryPointTime() { - // We can't simply pass this down through a JNI call, since the JNI for weblayer - // isn't initialized until we start the native content browser component, and we - // then need the start time in the C++ side before we return to Java. As such we - // save it in a static that the C++ can fetch once it has initialized the JNI. - sApplicationStartTimeMs = SystemClock.uptimeMillis(); - } - - @CalledByNative - public static long getApplicationStartTime() { - return sApplicationStartTimeMs; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/DIR_METADATA b/weblayer/browser/java/org/chromium/weblayer_private/payments/DIR_METADATA deleted file mode 100644 index c933c59..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/DIR_METADATA +++ /dev/null
@@ -1,2 +0,0 @@ -mixins: "//components/payments/COMMON_METADATA" -os: ANDROID
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/OWNERS b/weblayer/browser/java/org/chromium/weblayer_private/payments/OWNERS deleted file mode 100644 index 616d5533..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -file://components/payments/OWNERS
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java b/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java deleted file mode 100644 index 75adb3c..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.payments; - -import androidx.annotation.Nullable; - -import org.chromium.components.payments.BrowserPaymentRequest; -import org.chromium.components.payments.InvalidPaymentRequest; -import org.chromium.components.payments.MojoPaymentRequestGateKeeper; -import org.chromium.components.payments.OriginSecurityChecker; -import org.chromium.components.payments.PaymentAppServiceBridge; -import org.chromium.components.payments.PaymentFeatureList; -import org.chromium.components.payments.PaymentRequestService; -import org.chromium.components.payments.PaymentRequestServiceUtil; -import org.chromium.components.payments.PrefsStrings; -import org.chromium.components.payments.SslValidityChecker; -import org.chromium.components.user_prefs.UserPrefs; -import org.chromium.content_public.browser.BrowserContextHandle; -import org.chromium.content_public.browser.PermissionsPolicyFeature; -import org.chromium.content_public.browser.RenderFrameHost; -import org.chromium.content_public.browser.WebContents; -import org.chromium.content_public.browser.WebContentsStatics; -import org.chromium.payments.mojom.PaymentRequest; -import org.chromium.services.service_manager.InterfaceFactory; -import org.chromium.url.GURL; -import org.chromium.weblayer_private.ProfileImpl; -import org.chromium.weblayer_private.TabImpl; - -/** Creates an instance of PaymentRequest for use in WebLayer. */ -public class WebLayerPaymentRequestFactory implements InterfaceFactory<PaymentRequest> { - private final RenderFrameHost mRenderFrameHost; - - /** - * Production implementation of the WebLayerPaymentRequestService's Delegate. Gives true answers - * about the system. - */ - private static class WebLayerPaymentRequestDelegateImpl - implements PaymentRequestService.Delegate { - private final RenderFrameHost mRenderFrameHost; - - /* package */ WebLayerPaymentRequestDelegateImpl(RenderFrameHost renderFrameHost) { - mRenderFrameHost = renderFrameHost; - } - - @Override - public BrowserPaymentRequest createBrowserPaymentRequest( - PaymentRequestService paymentRequestService) { - return new WebLayerPaymentRequestService(paymentRequestService, this); - } - - @Override - public boolean isOffTheRecord() { - ProfileImpl profile = getProfile(); - if (profile == null) return true; - return profile.isIncognito(); - } - - @Override - public String getInvalidSslCertificateErrorMessage() { - WebContents webContents = - PaymentRequestServiceUtil.getLiveWebContents(mRenderFrameHost); - if (webContents == null || webContents.isDestroyed()) return null; - - GURL url = webContents.getLastCommittedUrl(); - if (url == null || !OriginSecurityChecker.isSchemeCryptographic(url)) { - return null; - } - return SslValidityChecker.getInvalidSslCertificateErrorMessage(webContents); - } - - @Override - public boolean prefsCanMakePayment() { - BrowserContextHandle profile = getProfile(); - return profile != null - && UserPrefs.get(profile).getBoolean(PrefsStrings.CAN_MAKE_PAYMENT_ENABLED); - } - - @Nullable - @Override - public String getTwaPackageName() { - return null; - } - - @Nullable - private ProfileImpl getProfile() { - WebContents webContents = - PaymentRequestServiceUtil.getLiveWebContents(mRenderFrameHost); - if (webContents == null) return null; - TabImpl tab = TabImpl.fromWebContents(webContents); - if (tab == null) return null; - return tab.getProfile(); - } - } - - /** - * Creates an instance of WebLayerPaymentRequestFactory. - * @param renderFrameHost The frame that issues the payment request on the merchant page. - */ - public WebLayerPaymentRequestFactory(RenderFrameHost renderFrameHost) { - mRenderFrameHost = renderFrameHost; - } - - @Override - public PaymentRequest createImpl() { - if (mRenderFrameHost == null) return new InvalidPaymentRequest(); - if (!mRenderFrameHost.isFeatureEnabled(PermissionsPolicyFeature.PAYMENT)) { - mRenderFrameHost.terminateRendererDueToBadMessage(241 /*PAYMENTS_WITHOUT_PERMISSION*/); - return null; - } - - if (!PaymentFeatureList.isEnabled(PaymentFeatureList.WEB_PAYMENTS)) { - return new InvalidPaymentRequest(); - } - - PaymentRequestService.Delegate delegate = - new WebLayerPaymentRequestDelegateImpl(mRenderFrameHost); - - WebContents webContents = WebContentsStatics.fromRenderFrameHost(mRenderFrameHost); - if (webContents == null || webContents.isDestroyed()) return new InvalidPaymentRequest(); - return new MojoPaymentRequestGateKeeper( - (client, onClosed) - -> new PaymentRequestService(mRenderFrameHost, client, onClosed, delegate, - PaymentAppServiceBridge::new)); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java b/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java deleted file mode 100644 index 0164e1f..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.payments; - -import androidx.annotation.Nullable; - -import org.chromium.components.payments.BrowserPaymentRequest; -import org.chromium.components.payments.JourneyLogger; -import org.chromium.components.payments.PaymentApp; -import org.chromium.components.payments.PaymentAppType; -import org.chromium.components.payments.PaymentRequestService; -import org.chromium.components.payments.PaymentRequestService.Delegate; -import org.chromium.components.payments.PaymentRequestSpec; -import org.chromium.components.payments.PaymentResponseHelper; -import org.chromium.components.payments.PaymentResponseHelperInterface; -import org.chromium.payments.mojom.PaymentDetails; -import org.chromium.payments.mojom.PaymentErrorReason; -import org.chromium.payments.mojom.PaymentItem; -import org.chromium.payments.mojom.PaymentValidationErrors; - -import java.util.ArrayList; -import java.util.List; - -/** The WebLayer-specific part of the payment request service. */ -public class WebLayerPaymentRequestService implements BrowserPaymentRequest { - private final List<PaymentApp> mAvailableApps = new ArrayList<>(); - private final JourneyLogger mJourneyLogger; - private PaymentRequestService mPaymentRequestService; - private PaymentRequestSpec mSpec; - private boolean mHasClosed; - private boolean mShouldSkipAppSelector; - private PaymentApp mSelectedApp; - - /** - * Create an instance of {@link WebLayerPaymentRequestService}. - * @param paymentRequestService The payment request service. - * @param delegate The delegate of the payment request service. - */ - public WebLayerPaymentRequestService( - PaymentRequestService paymentRequestService, Delegate delegate) { - mPaymentRequestService = paymentRequestService; - mJourneyLogger = mPaymentRequestService.getJourneyLogger(); - } - - // Implements BrowserPaymentRequest: - @Override - public void onPaymentDetailsUpdated( - PaymentDetails details, boolean hasNotifiedInvokedPaymentApp) {} - - // Implements BrowserPaymentRequest: - @Override - public void onPaymentDetailsNotUpdated(String selectedShippingOptionError) {} - - @Override - public boolean onPaymentAppCreated(PaymentApp paymentApp) { - // Ignores the service worker payment apps in WebLayer until - - // TODO(crbug.com/1224420): WebLayer supports Service worker payment apps. - return paymentApp.getPaymentAppType() != PaymentAppType.SERVICE_WORKER_APP; - } - - // Implements BrowserPaymentRequest: - @Override - public void complete(int result, Runnable onCompleteHandled) { - onCompleteHandled.run(); - } - - // Implements BrowserPaymentRequest: - @Override - public void onRetry(PaymentValidationErrors errors) {} - - // Implements BrowserPaymentRequest: - @Override - public void close() { - if (mHasClosed) return; - mHasClosed = true; - - if (mPaymentRequestService != null) { - mPaymentRequestService.close(); - mPaymentRequestService = null; - } - } - - // Implements BrowserPaymentRequest: - @Override - public boolean hasAvailableApps() { - return !mAvailableApps.isEmpty(); - } - - // Implements BrowserPaymentRequest: - @Override - public void notifyPaymentUiOfPendingApps(List<PaymentApp> pendingApps) { - assert mAvailableApps.isEmpty() - : "notifyPaymentUiOfPendingApps() should be called at most once."; - mAvailableApps.addAll(pendingApps); - mSelectedApp = mAvailableApps.size() == 0 ? null : mAvailableApps.get(0); - } - - // Implements BrowserPaymentRequest: - @Override - public void onSpecValidated(PaymentRequestSpec spec) { - mSpec = spec; - } - - // Implements BrowserPaymentRequest: - @Override - @Nullable - public String showOrSkipAppSelector(boolean isShowWaitingForUpdatedDetails, PaymentItem total, - boolean shouldSkipAppSelector) { - mShouldSkipAppSelector = shouldSkipAppSelector; - if (!mShouldSkipAppSelector) { - return "This request is not supported in Web Layer. Please try in Chrome, or make sure " - + "that: (1) show() is triggered by user gesture, or" - + "(2) do not request any contact information."; - } - return null; - } - - // Implements BrowserPaymentRequest: - @Override - @Nullable - public String onShowCalledAndAppsQueriedAndDetailsFinalized() { - assert !mAvailableApps.isEmpty() - : "triggerPaymentAppUiSkipIfApplicable() should be called only when there is any " - + "available app."; - PaymentApp selectedPaymentApp = mAvailableApps.get(0); - if (mShouldSkipAppSelector) { - mJourneyLogger.setSkippedShow(); - PaymentResponseHelperInterface paymentResponseHelper = - new PaymentResponseHelper(selectedPaymentApp, mSpec.getPaymentOptions()); - mPaymentRequestService.invokePaymentApp(selectedPaymentApp, paymentResponseHelper); - } - return null; - } - - // Implements BrowserPaymentRequest: - @Override - public PaymentApp getSelectedPaymentApp() { - return mAvailableApps.get(0); - } - - // Implements BrowserPaymentRequest: - @Override - public List<PaymentApp> getPaymentApps() { - return mAvailableApps; - } - - // Implements BrowserPaymentRequest: - @Override - public boolean hasAnyCompleteApp() { - return !mAvailableApps.isEmpty() && mAvailableApps.get(0).isComplete(); - } - - private void disconnectFromClientWithDebugMessage(String debugMessage) { - if (mPaymentRequestService != null) { - mPaymentRequestService.disconnectFromClientWithDebugMessage( - debugMessage, PaymentErrorReason.USER_CANCEL); - } - close(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java b/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java deleted file mode 100644 index fd09320..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java +++ /dev/null
@@ -1,166 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.payments; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.mockito.quality.Strictness; -import org.robolectric.annotation.Config; - -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.JniMocker; -import org.chromium.components.payments.ErrorMessageUtil; -import org.chromium.components.payments.ErrorMessageUtilJni; -import org.chromium.components.payments.PayerData; -import org.chromium.components.payments.PaymentApp; -import org.chromium.components.payments.PaymentApp.InstrumentDetailsCallback; -import org.chromium.components.payments.PaymentAppFactoryDelegate; -import org.chromium.components.payments.PaymentAppFactoryInterface; -import org.chromium.components.payments.PaymentAppService; -import org.chromium.components.payments.PaymentRequestService; -import org.chromium.components.payments.test_support.DefaultPaymentFeatureConfig; -import org.chromium.payments.mojom.PaymentRequest; -import org.chromium.payments.mojom.PaymentRequestClient; -import org.chromium.payments.mojom.PaymentResponse; -import org.chromium.weblayer_private.payments.test_support.WebLayerPaymentRequestBuilder; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * A test for the integration of PaymentRequestService, MojoPaymentRequestGateKeeper, - * WebLayerPaymentRequestService and PaymentAppService. - */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class WebLayerPaymentRequestServiceTest { - private static final String METHOD_NAME = "https://www.chromium.org"; - private static final String STRINGIFIED_DETAILS = "test stringifiedDetails"; - private final ArgumentCaptor<InstrumentDetailsCallback> mPaymentAppCallbackCaptor = - ArgumentCaptor.forClass(InstrumentDetailsCallback.class); - - @Rule - public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.WARN); - - @Rule - public JniMocker mJniMocker = new JniMocker(); - - @Mock - private ErrorMessageUtil.Natives mErrorMessageUtilMock; - - private PaymentRequestClient mClient; - private PaymentAppFactoryInterface mFactory; - private PaymentApp mPaymentApp; - private boolean mWaitForUpdatedDetails; - private boolean mIsUserGestureShow; - - @Before - public void setUp() { - mJniMocker.mock(ErrorMessageUtilJni.TEST_HOOKS, mErrorMessageUtilMock); - Mockito.doAnswer(args -> { - String[] methods = args.getArgument(0); - return "(Mock) Not supported error: " + Arrays.toString(methods); - }) - .when(mErrorMessageUtilMock) - .getNotSupportedErrorMessage(Mockito.any()); - - DefaultPaymentFeatureConfig.setDefaultFlagConfigurationForTesting(); - PaymentRequestService.resetShowingPaymentRequestForTest(); - PaymentAppService.getInstance().resetForTest(); - - mClient = Mockito.mock(PaymentRequestClient.class); - mPaymentApp = mockPaymentApp(); - mFactory = Mockito.mock(PaymentAppFactoryInterface.class); - Mockito.doAnswer((args) -> { - PaymentAppFactoryDelegate delegate = args.getArgument(0); - delegate.onCanMakePaymentCalculated(true); - delegate.onPaymentAppCreated(mPaymentApp); - delegate.onDoneCreatingPaymentApps(mFactory); - return null; - }) - .when(mFactory) - .create(Mockito.any()); - } - - @After - public void tearDown() { - PaymentRequestService.resetShowingPaymentRequestForTest(); - PaymentAppService.getInstance().resetForTest(); - } - - private PaymentApp mockPaymentApp() { - PaymentApp app = Mockito.mock(PaymentApp.class); - Set<String> methodNames = new HashSet<>(); - methodNames.add(METHOD_NAME); - Mockito.doReturn(methodNames).when(app).getInstrumentMethodNames(); - Mockito.doReturn("testPaymentApp").when(app).getIdentifier(); - Mockito.doReturn(true).when(app).handlesShippingAddress(); - return app; - } - - private WebLayerPaymentRequestBuilder defaultBuilder() { - WebLayerPaymentRequestBuilder builder = - WebLayerPaymentRequestBuilder.defaultBuilder(mClient); - PaymentAppService.getInstance().addUniqueFactory(mFactory, "testFactoryId"); - return builder; - } - - private void show(PaymentRequest request) { - request.show(mWaitForUpdatedDetails, mIsUserGestureShow); - } - - private void assertNoError() { - Mockito.verify(mClient, Mockito.never()).onError(Mockito.anyInt(), Mockito.anyString()); - } - - private void assertResponse() { - ArgumentCaptor<PaymentResponse> responseCaptor = - ArgumentCaptor.forClass(PaymentResponse.class); - Mockito.verify(mClient, Mockito.times(1)).onPaymentResponse(responseCaptor.capture()); - PaymentResponse response = responseCaptor.getValue(); - Assert.assertNotNull(response); - Assert.assertEquals(METHOD_NAME, response.methodName); - Assert.assertEquals(STRINGIFIED_DETAILS, response.stringifiedDetails); - } - - private void assertInvokePaymentAppCalled() { - Mockito.verify(mPaymentApp, Mockito.times(1)) - .invokePaymentApp(Mockito.any(), Mockito.any(), Mockito.anyString(), - Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), - Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), - mPaymentAppCallbackCaptor.capture()); - } - - private void simulatePaymentAppRespond() { - mPaymentAppCallbackCaptor.getValue().onInstrumentDetailsReady( - METHOD_NAME, STRINGIFIED_DETAILS, new PayerData()); - } - - @Test - @Feature({"Payments"}) - public void testPaymentIsSuccessful() { - PaymentRequest request = defaultBuilder().buildAndInit(); - Assert.assertNotNull(request); - assertNoError(); - - show(request); - assertNoError(); - assertInvokePaymentAppCalled(); - - simulatePaymentAppRespond(); - assertResponse(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/payments/test_support/WebLayerPaymentRequestBuilder.java b/weblayer/browser/java/org/chromium/weblayer_private/payments/test_support/WebLayerPaymentRequestBuilder.java deleted file mode 100644 index d4b39f3..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/payments/test_support/WebLayerPaymentRequestBuilder.java +++ /dev/null
@@ -1,199 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.payments.test_support; - -import android.content.Context; - -import androidx.annotation.Nullable; - -import org.mockito.Mockito; - -import org.chromium.components.payments.BrowserPaymentRequest; -import org.chromium.components.payments.JourneyLogger; -import org.chromium.components.payments.MojoPaymentRequestGateKeeper; -import org.chromium.components.payments.PaymentAppFactoryInterface; -import org.chromium.components.payments.PaymentRequestService; -import org.chromium.components.payments.PaymentRequestSpec; -import org.chromium.content_public.browser.RenderFrameHost; -import org.chromium.content_public.browser.WebContents; -import org.chromium.payments.mojom.PaymentCurrencyAmount; -import org.chromium.payments.mojom.PaymentDetails; -import org.chromium.payments.mojom.PaymentItem; -import org.chromium.payments.mojom.PaymentMethodData; -import org.chromium.payments.mojom.PaymentOptions; -import org.chromium.payments.mojom.PaymentRequest; -import org.chromium.payments.mojom.PaymentRequestClient; -import org.chromium.ui.base.WindowAndroid; -import org.chromium.url.GURL; -import org.chromium.url.JUnitTestGURLs; -import org.chromium.url.Origin; -import org.chromium.weblayer_private.payments.WebLayerPaymentRequestService; - -import java.lang.ref.WeakReference; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** The builder of PaymentRequest used in WebLayer, for testing purpose only. */ -public class WebLayerPaymentRequestBuilder implements PaymentRequestService.Delegate { - private final PaymentRequestClient mClient; - private final PaymentRequestService.Delegate mDelegate; - private final RenderFrameHost mRenderFrameHost; - private final PaymentMethodData[] mMethodData; - private final PaymentDetails mDetails; - private final WebContents mWebContents; - private final JourneyLogger mJourneyLogger; - private final PaymentRequestSpec mSpec; - private final PaymentOptions mOptions; - private String mSupportedMethod = "https://www.chromium.org"; - - /** - * Create a default builder. - * @param client The PaymentRequestClient used for this PaymentRequest. - * @return The created builder. - */ - public static WebLayerPaymentRequestBuilder defaultBuilder(PaymentRequestClient client) { - return new WebLayerPaymentRequestBuilder(client); - } - - private WebLayerPaymentRequestBuilder(PaymentRequestClient client) { - mClient = client; - mDelegate = this; - mJourneyLogger = Mockito.mock(JourneyLogger.class); - mWebContents = Mockito.mock(WebContents.class); - Mockito.doReturn(JUnitTestGURLs.URL_1).when(mWebContents).getLastCommittedUrl(); - mRenderFrameHost = Mockito.mock(RenderFrameHost.class); - Mockito.doReturn(JUnitTestGURLs.URL_2).when(mRenderFrameHost).getLastCommittedURL(); - Origin origin = Mockito.mock(Origin.class); - Mockito.doReturn(origin).when(mRenderFrameHost).getLastCommittedOrigin(); - mMethodData = new PaymentMethodData[1]; - mDetails = new PaymentDetails(); - mDetails.id = "testId"; - mDetails.total = new PaymentItem(); - mOptions = new PaymentOptions(); - mSpec = Mockito.mock(PaymentRequestSpec.class); - } - - /** - * Build PaymentRequest and calls its init(). - * @return The built and initialized PaymentRequest. - */ - public PaymentRequest buildAndInit() { - mMethodData[0] = new PaymentMethodData(); - mMethodData[0].supportedMethod = mSupportedMethod; - - PaymentCurrencyAmount amount = new PaymentCurrencyAmount(); - amount.currency = "CNY"; - amount.value = "123"; - PaymentItem total = new PaymentItem(); - total.amount = amount; - Mockito.doReturn(total).when(mSpec).getRawTotal(); - Map<String, PaymentMethodData> methodDataMap = new HashMap<>(); - methodDataMap.put(mMethodData[0].supportedMethod, mMethodData[0]); - Mockito.doReturn(methodDataMap).when(mSpec).getMethodData(); - Mockito.doReturn(mOptions).when(mSpec).getPaymentOptions(); - - PaymentRequest request = new MojoPaymentRequestGateKeeper( - (client, onClosed) - -> new PaymentRequestService( - mRenderFrameHost, client, onClosed, /*delegate=*/this, () -> null)); - request.init(mClient, mMethodData, mDetails, mOptions); - return request; - } - - /** - * Sets the method supported by this payment request (currently, only one method is supported). - * @param supportedMethod The supported method. - * @return The builder after the setting. - */ - public WebLayerPaymentRequestBuilder setSupportedMethod(String supportedMethod) { - mSupportedMethod = supportedMethod; - return this; - } - - @Override - public BrowserPaymentRequest createBrowserPaymentRequest( - PaymentRequestService paymentRequestService) { - return new WebLayerPaymentRequestService(paymentRequestService, mDelegate); - } - - @Override - public boolean isOffTheRecord() { - return false; - } - - @Override - public String getInvalidSslCertificateErrorMessage() { - return null; - } - - @Override - public boolean prefsCanMakePayment() { - return false; - } - - @Nullable - @Override - public String getTwaPackageName() { - return null; - } - - @Nullable - @Override - public WebContents getLiveWebContents(RenderFrameHost renderFrameHost) { - return mWebContents; - } - - @Override - public boolean isOriginSecure(GURL url) { - return true; - } - - @Override - public JourneyLogger createJourneyLogger(boolean isIncognito, WebContents webContents) { - return mJourneyLogger; - } - - @Override - public String formatUrlForSecurityDisplay(GURL uri) { - return uri.getSpec(); - } - - @Override - public byte[][] getCertificateChain(WebContents webContents) { - return new byte[0][]; - } - - @Override - public boolean isOriginAllowedToUseWebPaymentApis(GURL url) { - return true; - } - - @Override - public boolean validatePaymentDetails(PaymentDetails details) { - return true; - } - - @Override - public PaymentRequestSpec createPaymentRequestSpec(PaymentOptions options, - PaymentDetails details, Collection<PaymentMethodData> methodData, String appLocale) { - return mSpec; - } - - @Override - public WindowAndroid getWindowAndroid(RenderFrameHost renderFrameHost) { - WindowAndroid window = Mockito.mock(WindowAndroid.class); - Context context = Mockito.mock(Context.class); - WeakReference<Context> weakContext = Mockito.mock(WeakReference.class); - Mockito.doReturn(context).when(weakContext).get(); - Mockito.doReturn(weakContext).when(window).getContext(); - return window; - } - - @Override - public PaymentAppFactoryInterface createAndroidPaymentAppFactory() { - return null; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/permissions/PermissionRequestUtils.java b/weblayer/browser/java/org/chromium/weblayer_private/permissions/PermissionRequestUtils.java deleted file mode 100644 index 52d7abf..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/permissions/PermissionRequestUtils.java +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.permissions; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.permissions.AndroidPermissionRequester; -import org.chromium.ui.base.WindowAndroid; - -/** Util functions to request Android permissions for a content setting. */ -@JNINamespace("weblayer") -public final class PermissionRequestUtils { - @CalledByNative - private static void requestPermission( - WindowAndroid windowAndroid, long nativeCallback, int[] contentSettingsTypes) { - if (!AndroidPermissionRequester.requestAndroidPermissions(windowAndroid, - contentSettingsTypes, new AndroidPermissionRequester.RequestDelegate() { - @Override - public void onAndroidPermissionAccepted() { - PermissionRequestUtilsJni.get().onResult(nativeCallback, true); - } - - @Override - public void onAndroidPermissionCanceled() { - PermissionRequestUtilsJni.get().onResult(nativeCallback, false); - } - })) { - PermissionRequestUtilsJni.get().onResult(nativeCallback, false); - } - } - - @NativeMethods - interface Natives { - void onResult(long callback, boolean result); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/resources/ResourceMapper.java b/weblayer/browser/java/org/chromium/weblayer_private/resources/ResourceMapper.java deleted file mode 100644 index 79e39af..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/resources/ResourceMapper.java +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.resources; - -import org.chromium.base.annotations.CalledByNative; - -/** - * Wrapper class for ResourceId so it can be called over JNI. Since ResourceId is a generated class - * `@CalledByNative` does not work on it directly. - */ -class ResourceMapper { - @CalledByNative - private static int[] getResourceIdList() { - return ResourceId.getResourceIdList(); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java b/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java deleted file mode 100644 index 9000d198..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.settings; - -import androidx.preference.PreferenceFragmentCompat; - -import org.chromium.components.browser_ui.accessibility.AccessibilitySettingsDelegate; -import org.chromium.content_public.browser.BrowserContextHandle; -import org.chromium.weblayer_private.ProfileImpl; - -/** The WebLayer implementation of AccessibilitySettingsDelegate. */ -public class WebLayerAccessibilitySettingsDelegate implements AccessibilitySettingsDelegate { - private ProfileImpl mProfile; - - public WebLayerAccessibilitySettingsDelegate(ProfileImpl profile) { - mProfile = profile; - } - - @Override - public BrowserContextHandle getBrowserContextHandle() { - return mProfile; - } - - @Override - public BooleanPreferenceDelegate getAccessibilityTabSwitcherDelegate() { - return null; - } - - @Override - public BooleanPreferenceDelegate getReaderForAccessibilityDelegate() { - return null; - } - - @Override - public void addExtraPreferences(PreferenceFragmentCompat fragment) {} - - @Override - public boolean showPageZoomSettingsUI() { - return false; - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java b/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java deleted file mode 100644 index 06ab5a9..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java +++ /dev/null
@@ -1,199 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.settings; - -import android.app.Activity; -import android.graphics.drawable.Drawable; - -import androidx.annotation.LayoutRes; -import androidx.annotation.Nullable; -import androidx.preference.Preference; - -import org.chromium.base.Callback; -import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate; -import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory.Type; -import org.chromium.components.browser_ui.site_settings.SiteSettingsDelegate; -import org.chromium.components.content_settings.ContentSettingsType; -import org.chromium.components.embedder_support.util.Origin; -import org.chromium.content_public.browser.BrowserContextHandle; -import org.chromium.url.GURL; -import org.chromium.weblayer_private.WebLayerImpl; - -import java.util.Collections; -import java.util.Set; - -/** - * A SiteSettingsDelegate instance that contains WebLayer-specific Site Settings logic. - */ -public class WebLayerSiteSettingsDelegate - implements SiteSettingsDelegate, ManagedPreferenceDelegate { - private final BrowserContextHandle mBrowserContextHandle; - - public WebLayerSiteSettingsDelegate(BrowserContextHandle browserContextHandle) { - mBrowserContextHandle = browserContextHandle; - } - - // SiteSettingsDelegate implementation: - - @Override - public BrowserContextHandle getBrowserContextHandle() { - return mBrowserContextHandle; - } - - @Override - public ManagedPreferenceDelegate getManagedPreferenceDelegate() { - return this; - } - - @Override - public void getFaviconImageForURL(GURL faviconUrl, Callback<Drawable> callback) { - // We don't currently support favicons on WebLayer. - callback.onResult(null); - } - - @Override - public boolean isCategoryVisible(@Type int type) { - return type == Type.ADS || type == Type.ALL_SITES || type == Type.AUTOMATIC_DOWNLOADS - || type == Type.BACKGROUND_SYNC || type == Type.CAMERA || type == Type.COOKIES - || type == Type.DEVICE_LOCATION || type == Type.JAVASCRIPT - || type == Type.MICROPHONE || type == Type.POPUPS || type == Type.PROTECTED_MEDIA - || type == Type.SOUND || type == Type.USE_STORAGE || type == Type.ZOOM; - } - - @Override - public boolean isIncognitoModeEnabled() { - return true; - } - - @Override - public boolean isQuietNotificationPromptsFeatureEnabled() { - return false; - } - - @Override - public boolean isPrivacySandboxFirstPartySetsUIFeatureEnabled() { - return false; - } - - @Override - public boolean isPrivacySandboxSettings4Enabled() { - return false; - } - - @Override - public boolean isUserBypassUIEnabled() { - return false; - } - - @Override - public String getChannelIdForOrigin(String origin) { - return null; - } - - @Override - public String getAppName() { - return WebLayerImpl.getClientApplicationName(); - } - - @Override - @Nullable - public String getDelegateAppNameForOrigin(Origin origin, @ContentSettingsType int type) { - return null; - } - - @Override - @Nullable - public String getDelegatePackageNameForOrigin(Origin origin, @ContentSettingsType int type) { - return null; - } - - // ManagedPrefrenceDelegate implementation: - // A no-op because WebLayer doesn't support managed preferences. - - @Override - public boolean isPreferenceControlledByPolicy(Preference preference) { - return false; - } - - @Override - public boolean isPreferenceControlledByCustodian(Preference preference) { - return false; - } - - @Override - public boolean doesProfileHaveMultipleCustodians() { - return false; - } - - @Override - public @LayoutRes int defaultPreferenceLayoutResource() { - // WebLayer uses Android's default Preference layout. - return 0; - } - - @Override - public boolean isHelpAndFeedbackEnabled() { - return false; - } - - @Override - public void launchSettingsHelpAndFeedbackActivity(Activity currentActivity) {} - - @Override - public void launchProtectedContentHelpAndFeedbackActivity(Activity currentActivity) {} - - @Override - public Set<String> getOriginsWithInstalledApp() { - return Collections.EMPTY_SET; - } - - @Override - public Set<String> getAllDelegatedNotificationOrigins() { - return Collections.EMPTY_SET; - } - - @Override - public void maybeDisplayPrivacySandboxSnackbar() {} - - @Override - public void dismissPrivacySandboxSnackbar() {} - - @Override - public boolean isFirstPartySetsDataAccessEnabled() { - return false; - } - - @Override - public boolean isFirstPartySetsDataAccessManaged() { - return false; - } - - @Override - public boolean isPartOfManagedFirstPartySet(String origin) { - return false; - } - - @Override - public void setFirstPartySetsDataAccessEnabled(boolean enabled) {} - - @Override - public String getFirstPartySetOwner(String memberOrigin) { - return null; - } - - @Override - public boolean canLaunchClearBrowsingDataDialog() { - return false; - } - - @Override - public void launchClearBrowsingDataDialog(Activity currentActivity) {} - - @Override - public void notifyRequestDesktopSiteSettingsPageOpened() {} - - @Override - public void onDestroyView() {} -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/test/TestAutofillManagerWrapper.java b/weblayer/browser/java/org/chromium/weblayer_private/test/TestAutofillManagerWrapper.java deleted file mode 100644 index 3d6cb9d..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/test/TestAutofillManagerWrapper.java +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.test; - -import android.content.Context; -import android.graphics.Rect; -import android.view.View; -import android.view.autofill.AutofillValue; - -import org.chromium.base.Log; -import org.chromium.components.autofill.AutofillManagerWrapper; -import org.chromium.weblayer_private.test_interfaces.AutofillEventType; - -import java.util.ArrayList; - -/** - * A test AutofillManagerWrapper for AutofillTest - */ -public class TestAutofillManagerWrapper extends AutofillManagerWrapper { - public static final boolean DEBUG = false; - public static final String TAG = "AutofillTest"; - - public TestAutofillManagerWrapper( - Context context, Runnable onNewEvents, ArrayList<Integer> eventsObserved) { - super(context); - if (DEBUG) Log.i(TAG, "TestAutofillManagerWrapper"); - mOnNewEvents = onNewEvents; - mEventsObserved = eventsObserved; - } - - @Override - public boolean isDisabled() { - return false; - } - - @Override - public boolean isAwGCurrentAutofillService() { - return true; - } - - @Override - public void notifyVirtualViewEntered(View parent, int childId, Rect absBounds) { - if (DEBUG) Log.i(TAG, "notifyVirtualViewEntered"); - mEventsObserved.add(AutofillEventType.VIEW_ENTERED); - mOnNewEvents.run(); - } - - @Override - public void notifyVirtualViewExited(View parent, int childId) { - if (DEBUG) Log.i(TAG, "notifyVirtualViewExited"); - mEventsObserved.add(AutofillEventType.VIEW_EXITED); - mOnNewEvents.run(); - } - - @Override - public void notifyVirtualValueChanged(View parent, int childId, AutofillValue value) { - if (DEBUG) Log.i(TAG, "notifyVirtualValueChanged"); - mEventsObserved.add(AutofillEventType.VALUE_CHANGED); - mOnNewEvents.run(); - } - - @Override - public void commit(int submissionSource) { - if (DEBUG) Log.i(TAG, "commit"); - mEventsObserved.add(AutofillEventType.COMMIT); - mOnNewEvents.run(); - } - - @Override - public void cancel() { - if (DEBUG) Log.i(TAG, "cancel"); - mEventsObserved.add(AutofillEventType.CANCEL); - mOnNewEvents.run(); - } - - @Override - public void notifyNewSessionStarted(boolean hasServerPrediction) { - if (DEBUG) Log.i(TAG, "notifyNewSessionStarted"); - mEventsObserved.add(AutofillEventType.SESSION_STARTED); - mOnNewEvents.run(); - } - - @Override - public void onQueryDone(boolean success) { - if (DEBUG) Log.i(TAG, "onQueryDone " + success); - mEventsObserved.add(AutofillEventType.QUERY_DONE); - mOnNewEvents.run(); - } - - private ArrayList<Integer> mEventsObserved; - private Runnable mOnNewEvents; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/test/TestContentCaptureConsumer.java b/weblayer/browser/java/org/chromium/weblayer_private/test/TestContentCaptureConsumer.java deleted file mode 100644 index 9287d4c..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/test/TestContentCaptureConsumer.java +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.test; - -import org.chromium.components.content_capture.ContentCaptureConsumer; -import org.chromium.components.content_capture.ContentCaptureFrame; -import org.chromium.components.content_capture.FrameSession; - -import java.util.ArrayList; - -/** - * A test ContentCaptureConsumer for ContentCaptureTest. - */ -public class TestContentCaptureConsumer implements ContentCaptureConsumer { - public static final int CONTENT_CAPTURED = 1; - public static final int CONTENT_UPDATED = 2; - public static final int CONTENT_REMOVED = 3; - public static final int SESSION_REMOVED = 4; - public static final int TITLE_UPDATED = 5; - public static final int FAVICON_UPDATED = 6; - - public TestContentCaptureConsumer(Runnable onNewEvents, ArrayList<Integer> eventsObserved) { - mOnNewEvents = onNewEvents; - mEventsObserved = eventsObserved; - } - - @Override - public void onContentCaptured( - FrameSession parentFrame, ContentCaptureFrame contentCaptureData) { - mEventsObserved.add(CONTENT_CAPTURED); - mOnNewEvents.run(); - } - - @Override - public void onContentUpdated(FrameSession parentFrame, ContentCaptureFrame contentCaptureData) { - mEventsObserved.add(CONTENT_UPDATED); - mOnNewEvents.run(); - } - - @Override - public void onSessionRemoved(FrameSession session) { - mEventsObserved.add(SESSION_REMOVED); - mOnNewEvents.run(); - } - - @Override - public void onContentRemoved(FrameSession session, long[] removedIds) { - mEventsObserved.add(CONTENT_REMOVED); - mOnNewEvents.run(); - } - - @Override - public void onTitleUpdated(ContentCaptureFrame mainFrame) { - mEventsObserved.add(TITLE_UPDATED); - mOnNewEvents.run(); - } - - @Override - public void onFaviconUpdated(ContentCaptureFrame mainFrame) { - mEventsObserved.add(FAVICON_UPDATED); - mOnNewEvents.run(); - } - - @Override - public boolean shouldCapture(String[] urls) { - return true; - } - - private ArrayList<Integer> mEventsObserved; - private Runnable mOnNewEvents; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/test/TestInfoBar.java b/weblayer/browser/java/org/chromium/weblayer_private/test/TestInfoBar.java deleted file mode 100644 index d12bf375..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/test/TestInfoBar.java +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.test; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.components.infobars.InfoBar; -import org.chromium.components.infobars.InfoBarCompactLayout; -import org.chromium.content_public.browser.WebContents; -import org.chromium.weblayer_private.TabImpl; - -/** - * A test infobar. - */ -@JNINamespace("weblayer") -public class TestInfoBar extends InfoBar { - @VisibleForTesting - public TestInfoBar() { - super(0, 0, null, null); - } - - @Override - protected boolean usesCompactLayout() { - return true; - } - - @Override - protected void createCompactLayoutContent(InfoBarCompactLayout layout) { - new InfoBarCompactLayout.MessageBuilder(layout) - .withText("I am a compact infobar") - .buildAndInsert(); - } - - @CalledByNative - private static TestInfoBar create() { - return new TestInfoBar(); - } - - public static void show(TabImpl tab) { - TestInfoBarJni.get().show(tab.getWebContents()); - } - - @NativeMethods - interface Natives { - void show(WebContents webContents); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/test/TestWebLayerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/test/TestWebLayerImpl.java deleted file mode 100644 index 6b369b6..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/test/TestWebLayerImpl.java +++ /dev/null
@@ -1,324 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.test; - -import android.os.IBinder; -import android.os.RemoteException; - -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.build.annotations.UsedByReflection; -import org.chromium.components.autofill.AutofillProviderTestHelper; -import org.chromium.components.browser_ui.accessibility.FontSizePrefs; -import org.chromium.components.infobars.InfoBarAnimationListener; -import org.chromium.components.infobars.InfoBarUiItem; -import org.chromium.components.location.LocationUtils; -import org.chromium.components.media_router.BrowserMediaRouter; -import org.chromium.components.media_router.MockMediaRouteProvider; -import org.chromium.components.permissions.PermissionDialogController; -import org.chromium.components.webauthn.AuthenticatorImpl; -import org.chromium.components.webauthn.MockFido2CredentialRequest; -import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.content_public.browser.test.util.WebContentsUtils; -import org.chromium.device.geolocation.LocationProviderOverrider; -import org.chromium.device.geolocation.MockLocationProvider; -import org.chromium.net.NetworkChangeNotifier; -import org.chromium.ui.modaldialog.ModalDialogProperties; -import org.chromium.weblayer_private.BrowserImpl; -import org.chromium.weblayer_private.DownloadImpl; -import org.chromium.weblayer_private.InfoBarContainer; -import org.chromium.weblayer_private.ProfileImpl; -import org.chromium.weblayer_private.TabImpl; -import org.chromium.weblayer_private.WebLayerAccessibilityUtil; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.test_interfaces.ITestWebLayer; - -import java.util.ArrayList; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -/** - * Root implementation class for TestWebLayer. - */ -@JNINamespace("weblayer") -@UsedByReflection("WebLayer") -public final class TestWebLayerImpl extends ITestWebLayer.Stub { - private MockLocationProvider mMockLocationProvider; - - @UsedByReflection("WebLayer") - public static IBinder create() { - return new TestWebLayerImpl(); - } - - private TestWebLayerImpl() {} - - @Override - public boolean isNetworkChangeAutoDetectOn() { - return NetworkChangeNotifier.getAutoDetectorForTest() != null; - } - - @Override - public void setMockLocationProvider(boolean enable) { - if (enable) { - mMockLocationProvider = new MockLocationProvider(); - LocationProviderOverrider.setLocationProviderImpl(mMockLocationProvider); - } else if (mMockLocationProvider != null) { - mMockLocationProvider.stop(); - mMockLocationProvider.stopUpdates(); - } - } - - @Override - public boolean isMockLocationProviderRunning() { - return mMockLocationProvider.isRunning(); - } - - @Override - public boolean isPermissionDialogShown() { - try { - return TestThreadUtils.runOnUiThreadBlocking(() -> { - return PermissionDialogController.getInstance().isDialogShownForTest(); - }); - } catch (ExecutionException e) { - return false; - } - } - - @Override - public void clickPermissionDialogButton(boolean allow) { - TestThreadUtils.runOnUiThreadBlocking(() -> { - PermissionDialogController.getInstance().clickButtonForTest(allow - ? ModalDialogProperties.ButtonType.POSITIVE - : ModalDialogProperties.ButtonType.NEGATIVE); - }); - } - - @Override - public void setSystemLocationSettingEnabled(boolean enabled) { - TestThreadUtils.runOnUiThreadBlocking(() -> { - LocationUtils.setFactory(() -> { - return new LocationUtils() { - @Override - public boolean isSystemLocationSettingEnabled() { - return enabled; - } - }; - }); - }); - } - - @Override - public void waitForBrowserControlsMetadataState( - ITab tab, int topHeight, int bottomHeight, IObjectWrapper runnable) { - TestWebLayerImplJni.get().waitForBrowserControlsMetadataState( - ((TabImpl) tab).getNativeTab(), topHeight, bottomHeight, - ObjectWrapper.unwrap(runnable, Runnable.class)); - } - - @Override - public void setAccessibilityEnabled(boolean value) { - WebLayerAccessibilityUtil.get().setAccessibilityEnabledForTesting(value); - } - - @Override - public void addInfoBar(ITab tab, IObjectWrapper runnable) { - Runnable unwrappedRunnable = ObjectWrapper.unwrap(runnable, Runnable.class); - TabImpl tabImpl = (TabImpl) tab; - - InfoBarContainer infoBarContainer = tabImpl.getInfoBarContainerForTesting(); - infoBarContainer.addAnimationListener(new InfoBarAnimationListener() { - @Override - public void notifyAnimationFinished(int animationType) {} - @Override - public void notifyAllAnimationsFinished(InfoBarUiItem frontInfoBar) { - unwrappedRunnable.run(); - infoBarContainer.removeAnimationListener(this); - } - }); - - TestInfoBar.show((TabImpl) tab); - } - - @Override - public IObjectWrapper getInfoBarContainerView(ITab tab) { - return ObjectWrapper.wrap( - ((TabImpl) tab).getInfoBarContainerForTesting().getViewForTesting()); - } - - @Override - public void setIgnoreMissingKeyForTranslateManager(boolean ignore) { - TestWebLayerImplJni.get().setIgnoreMissingKeyForTranslateManager(ignore); - } - - @Override - public void forceNetworkConnectivityState(boolean networkAvailable) { - TestThreadUtils.runOnUiThreadBlocking( - () -> { NetworkChangeNotifier.forceConnectivityState(true); }); - } - - @Override - public boolean canInfoBarContainerScroll(ITab tab) { - return ((TabImpl) tab).canInfoBarContainerScrollForTesting(); - } - - @Override - public String getTranslateInfoBarTargetLanguage(ITab tab) { - TabImpl tabImpl = (TabImpl) tab; - return tabImpl.getTranslateInfoBarTargetLanguageForTesting(); - } - - @Override - public boolean didShowFullscreenToast(ITab tab) { - TabImpl tabImpl = (TabImpl) tab; - return tabImpl.didShowFullscreenToast(); - } - - @Override - public void initializeMockMediaRouteProvider(boolean closeRouteWithErrorOnSend, - boolean disableIsSupportsSource, String createRouteErrorMessage, - String joinRouteErrorMessage) { - BrowserMediaRouter.setRouteProviderFactoryForTest(new MockMediaRouteProvider.Factory()); - - if (closeRouteWithErrorOnSend) { - MockMediaRouteProvider.Factory.sProvider.setCloseRouteWithErrorOnSend(true); - } - if (disableIsSupportsSource) { - MockMediaRouteProvider.Factory.sProvider.setIsSupportsSource(false); - } - if (createRouteErrorMessage != null) { - MockMediaRouteProvider.Factory.sProvider.setCreateRouteErrorMessage( - createRouteErrorMessage); - } - if (joinRouteErrorMessage != null) { - MockMediaRouteProvider.Factory.sProvider.setJoinRouteErrorMessage( - joinRouteErrorMessage); - } - } - - @Override - public IObjectWrapper getMediaRouteButton(String name) { - return null; - } - - @Override - public void crashTab(ITab tab) { - try { - TabImpl tabImpl = (TabImpl) tab; - WebContentsUtils.crashTabAndWait(tabImpl.getWebContents()); - } catch (TimeoutException e) { - throw new RuntimeException(e); - } - } - - @Override - public boolean isWindowOnSmallDevice(IBrowser browser) { - try { - return TestThreadUtils.runOnUiThreadBlocking( - () -> { return ((BrowserImpl) browser).isWindowOnSmallDevice(); }); - } catch (ExecutionException e) { - return true; - } - } - - @Override - public void fetchAccessToken(IProfile profile, IObjectWrapper /* Set<String> */ scopes, - IObjectWrapper /* ValueCallback<String> */ onTokenFetched) throws RemoteException { - ProfileImpl profileImpl = (ProfileImpl) profile; - profileImpl.fetchAccessTokenForTesting(scopes, onTokenFetched); - } - - @Override - public void addContentCaptureConsumer(IBrowser browser, - IObjectWrapper /* Runnable */ onNewEvents, - IObjectWrapper /* ArrayList<Integer>*/ eventsObserved) { - Runnable unwrappedOnNewEvents = ObjectWrapper.unwrap(onNewEvents, Runnable.class); - ArrayList<Integer> unwrappedEventsObserved = - ObjectWrapper.unwrap(eventsObserved, ArrayList.class); - TestThreadUtils.runOnUiThreadBlocking(() -> { - BrowserImpl browserImpl = (BrowserImpl) browser; - browserImpl.getBrowserFragment() - .getPossiblyNullViewController() - .addContentCaptureConsumerForTesting(new TestContentCaptureConsumer( - unwrappedOnNewEvents, unwrappedEventsObserved)); - }); - } - - @Override - public void notifyOfAutofillEvents(IBrowser browser, IObjectWrapper /* Runnable */ onNewEvents, - IObjectWrapper /* ArrayList<Integer>*/ eventsObserved) { - Runnable unwrappedOnNewEvents = ObjectWrapper.unwrap(onNewEvents, Runnable.class); - ArrayList<Integer> unwrappedEventsObserved = - ObjectWrapper.unwrap(eventsObserved, ArrayList.class); - - TestThreadUtils.runOnUiThreadBlocking(() -> { - AutofillProviderTestHelper.disableDownloadServerForTesting(); - BrowserImpl browserImpl = (BrowserImpl) browser; - TabImpl tab = browserImpl.getActiveTab(); - tab.getAutofillProviderForTesting().replaceAutofillManagerWrapperForTesting( - new TestAutofillManagerWrapper(browserImpl.getContext(), unwrappedOnNewEvents, - unwrappedEventsObserved)); - }); - } - - @Override - public void activateBackgroundFetchNotification(int id) { - TestThreadUtils.runOnUiThreadBlocking( - () -> DownloadImpl.activateNotificationForTesting(id)); - } - - @Override - public void expediteDownloadService() { - TestWebLayerImplJni.get().expediteDownloadService(); - } - - @Override - public void setMockWebAuthnEnabled(boolean enabled) { - if (enabled) { - AuthenticatorImpl.overrideFido2CredentialRequestForTesting( - new MockFido2CredentialRequest()); - } else { - AuthenticatorImpl.overrideFido2CredentialRequestForTesting(null); - } - } - - @Override - public void fireOnAccessTokenIdentifiedAsInvalid(IProfile profile, - IObjectWrapper /* Set<String> */ scopes, IObjectWrapper /* String */ token) - throws RemoteException { - ProfileImpl profileImpl = (ProfileImpl) profile; - profileImpl.fireOnAccessTokenIdentifiedAsInvalidForTesting(scopes, token); - } - - @Override - public void grantLocationPermission(String url) { - TestThreadUtils.runOnUiThreadBlocking( - () -> { TestWebLayerImplJni.get().grantLocationPermission(url); }); - } - - @Override - public void setTextScaling(IProfile profile, float value) { - ProfileImpl profileImpl = (ProfileImpl) profile; - FontSizePrefs.getInstance(profileImpl).setUserFontScaleFactor(value); - } - - @Override - public boolean getForceEnableZoom(IProfile profile) { - ProfileImpl profileImpl = (ProfileImpl) profile; - return FontSizePrefs.getInstance(profileImpl).getForceEnableZoom(); - } - - @NativeMethods - interface Natives { - void waitForBrowserControlsMetadataState( - long tabImpl, int top, int bottom, Runnable runnable); - void setIgnoreMissingKeyForTranslateManager(boolean ignore); - void expediteDownloadService(); - void grantLocationPermission(String url); - } -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/AutofillEventType.java b/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/AutofillEventType.java deleted file mode 100644 index 295711a9..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/AutofillEventType.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.test_interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({AutofillEventType.VIEW_ENTERED, AutofillEventType.VIEW_EXITED, - AutofillEventType.VALUE_CHANGED, AutofillEventType.COMMIT, AutofillEventType.CANCEL, - AutofillEventType.SESSION_STARTED, AutofillEventType.QUERY_DONE}) -@Retention(RetentionPolicy.SOURCE) -public @interface AutofillEventType { - int VIEW_ENTERED = 1; - int VIEW_EXITED = 2; - int VALUE_CHANGED = 3; - int COMMIT = 4; - int CANCEL = 5; - int SESSION_STARTED = 6; - int QUERY_DONE = 7; -}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl b/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl deleted file mode 100644 index 405e06b9..0000000 --- a/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl +++ /dev/null
@@ -1,103 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private.test_interfaces; - -import android.os.Bundle; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.ITab; - -interface ITestWebLayer { - // Force network connectivity state. - boolean isNetworkChangeAutoDetectOn() = 1; - // set mock location provider - void setMockLocationProvider(in boolean enable) = 2; - boolean isMockLocationProviderRunning() = 3; - - // Whether or not a permission dialog is currently showing. - boolean isPermissionDialogShown() = 4; - - // Clicks a button on the permission dialog. - void clickPermissionDialogButton(boolean allow) = 5; - - // Forces the system location setting to enabled. - void setSystemLocationSettingEnabled(boolean enabled) = 6; - - // See comments in TestWebLayer for details. - void waitForBrowserControlsMetadataState(in ITab tab, - in int top, - in int bottom, - in IObjectWrapper runnable) = 7; - - void setAccessibilityEnabled(in boolean enabled) = 8; - - // Creates and shows a test infobar in |tab|, calling |runnable| when the addition (including - // animations) is complete. - void addInfoBar(in ITab tab, in IObjectWrapper runnable) = 10; - - // Gets the infobar container view associated with |tab|. - IObjectWrapper /* View */ getInfoBarContainerView(in ITab tab) = 11; - - void setIgnoreMissingKeyForTranslateManager(in boolean ignore) = 12; - void forceNetworkConnectivityState(in boolean networkAvailable) = 13; - - boolean canInfoBarContainerScroll(in ITab tab) = 14; - - // Returns the target language of the currently-showing translate infobar, or null if no translate - // infobar is currently showing. - String getTranslateInfoBarTargetLanguage(in ITab tab) = 16; - - // Returns true if a fullscreen toast was shown for |tab|. - boolean didShowFullscreenToast(in ITab tab) = 17; - - // Does setup for MediaRouter tests, mocking out Chromecast devices. - void initializeMockMediaRouteProvider( - boolean closeRouteWithErrorOnSend, boolean disableIsSupportsSource, - in String createRouteErrorMessage, in String joinRouteErrorMessage) = 18; - - // Gets a button from the currently visible media route selection dialog. The button represents a - // route and contains the text |name|. Returns null if no such dialog or button exists. - IObjectWrapper /* View */ getMediaRouteButton(String name) = 19; - - // Causes the renderer process in the tab's main frame to crash. - void crashTab(in ITab tab) = 20; - - boolean isWindowOnSmallDevice(in IBrowser browser) = 21; - void fetchAccessToken(in IProfile profile, in IObjectWrapper /* Set<String */ scopes, in IObjectWrapper /* ValueCallback<String> */ onTokenFetched) = 23; - // Add a TestContentCaptureConsumer for the provided |browser|, with a Runnable |onNewEvent| to notify the - // caller when the events happened, the event ID will be received through |eventsObserved| list. - void addContentCaptureConsumer(in IBrowser browser, - in IObjectWrapper /* Runnable */ onNewEvent, - in IObjectWrapper /* ArrayList<Integer> */ eventsObserved) = 24; - - // Notifies the caller of autofill-related events that occur in |browser|. The caller is notified - // via |onNewEvent| when a new event occurs, at which point the list of events that have occurred - // since notifyOfAutofillEvents() was first invoked will be available via |eventsObserved|. - // Note: Calling this method results in stubbing out the actual system-level integration with - // Android Autofill. - void notifyOfAutofillEvents(in IBrowser browser, - in IObjectWrapper /* Runnable */ onNewEvent, - in IObjectWrapper /* ArrayList<Integer> */ eventsObserved) = 25; - - // Simulates tapping the download notification with `id`. - void activateBackgroundFetchNotification(int id) = 26; - - // Speeds up download service initialization. - void expediteDownloadService() = 27; - - // Mocks the GMSCore Fido calls used by WebAuthn. - void setMockWebAuthnEnabled(in boolean enabled) = 28; - - // Simulates the implementation-side event of an access token being - // identified as invalid. - void fireOnAccessTokenIdentifiedAsInvalid(in IProfile profile, in IObjectWrapper /* Set<String */ scopes, in IObjectWrapper /* String */ token) = 29; - - // Grants `url` location permission. - void grantLocationPermission(String url) = 30; - - void setTextScaling(in IProfile profile, float value) = 31; - boolean getForceEnableZoom(in IProfile profile) = 32; -}
diff --git a/weblayer/browser/java/res/drawable/weblayer_tab_indicator.xml b/weblayer/browser/java/res/drawable/weblayer_tab_indicator.xml deleted file mode 100644 index 57e7ee3..0000000 --- a/weblayer/browser/java/res/drawable/weblayer_tab_indicator.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2019 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:left="@dimen/weblayer_tab_indicator_padding" - android:right="@dimen/weblayer_tab_indicator_padding" > - <shape android:shape="rectangle" > - <corners - android:topRightRadius="@dimen/weblayer_tab_indicator_radius" - android:topLeftRadius="@dimen/weblayer_tab_indicator_radius" /> - </shape> - </item> -</layer-list>
diff --git a/weblayer/browser/java/res/layout/weblayer_infobar_translate_compact_content.xml b/weblayer/browser/java/res/layout/weblayer_infobar_translate_compact_content.xml deleted file mode 100644 index 7a1627e1..0000000 --- a/weblayer/browser/java/res/layout/weblayer_infobar_translate_compact_content.xml +++ /dev/null
@@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2017 The Chromium Authors -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:app="http://schemas.android.com/apk/res-auto" - android:id="@+id/weblayer_translate_infobar_content" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center_vertical" - android:orientation="horizontal"> - <!-- TODO(huayinz): Change app:tabIndicatorColor to some common color reference --> - <org.chromium.components.translate.TranslateTabLayout - android:id="@+id/weblayer_translate_infobar_tabs" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:requiresFadingEdge="horizontal" - android:fadingEdgeLength="@dimen/weblayer_infobar_translate_fade_edge_length" - app:tabIndicator="@drawable/weblayer_tab_indicator" - app:tabIndicatorFullWidth="false" - app:tabIndicatorHeight="3dp" - app:tabSelectedTextColor="@color/weblayer_tab_layout_selected_tab_color" - app:tabGravity="fill" - android:background="@android:color/transparent" - app:tabMode="scrollable" /> - - <org.chromium.ui.widget.ChromeImageButton - android:id="@+id/weblayer_translate_infobar_menu_button" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:minHeight="@dimen/min_touch_target_size" - android:minWidth="@dimen/min_touch_target_size" - android:scaleType="center" - android:background="?attr/selectableItemBackground" - android:contentDescription="@string/accessibility_toolbar_btn_menu" - android:src="@drawable/ic_more_vert_24dp" - app:tint="@color/default_icon_color_tint_list" /> -</LinearLayout>
diff --git a/weblayer/browser/java/res/values/colors.xml b/weblayer/browser/java/res/values/colors.xml deleted file mode 100644 index a3027d9..0000000 --- a/weblayer/browser/java/res/values/colors.xml +++ /dev/null
@@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2014 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools"> - <!-- Please see src/ui/android/java/res/values/colors.xml for the shared common colors. --> - - <color name="weblayer_tab_layout_selected_tab_color">@color/default_text_color_blue_baseline</color> - -</resources>
diff --git a/weblayer/browser/java/res/values/dimens.xml b/weblayer/browser/java/res/values/dimens.xml deleted file mode 100644 index a32f07a..0000000 --- a/weblayer/browser/java/res/values/dimens.xml +++ /dev/null
@@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources> - <!-- Dimensions for compact translate infobar. --> - <dimen name="weblayer_infobar_translate_fade_edge_length">18dp</dimen> - - <!-- Dimens of tab indicator --> - <dimen name="weblayer_tab_indicator_radius">3dp</dimen> - <dimen name="weblayer_tab_indicator_padding">2dp</dimen> - -</resources>
diff --git a/weblayer/browser/java/res/values/styles.xml b/weblayer/browser/java/res/values/styles.xml deleted file mode 100644 index bc372e2..0000000 --- a/weblayer/browser/java/res/values/styles.xml +++ /dev/null
@@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools"> - <style name="Theme.WebLayer" parent="Theme.BrowserUI.DayNight" /> - - <style name="Theme.WebLayer.Settings" parent="Theme.WebLayer"> - <item name="preferenceTheme">@style/PreferenceTheme</item> - <item name="alertDialogTheme">@style/ThemeOverlay.BrowserUI.AlertDialog</item> - - <!-- Text style attributes used by the preference_material.xml layout. --> - <item name="android:textAppearanceListItem">@style/TextAppearance.TextLarge.Primary</item> - <item name="android:textColorSecondary">@color/default_text_color_secondary_list</item> - </style> -</resources>
diff --git a/weblayer/browser/java/res_test/layout/test_layout.xml b/weblayer/browser/java/res_test/layout/test_layout.xml deleted file mode 100644 index e507be3..0000000 --- a/weblayer/browser/java/res_test/layout/test_layout.xml +++ /dev/null
@@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<View - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - tools:ignore="UnusedResources" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="?attr/testBasicColor"/>
diff --git a/weblayer/browser/java/res_test/values/values.xml b/weblayer/browser/java/res_test/values/values.xml deleted file mode 100644 index 723709a..0000000 --- a/weblayer/browser/java/res_test/values/values.xml +++ /dev/null
@@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources"> - <attr name="testBasicColor" format="color"/> - <attr name="testAttrColor" format="color"/> - - <style name="TestStyle"> - <item name="testBasicColor">#010101</item> - <item name="testAttrColor">?attr/testBasicColor</item> - </style> -</resources>
diff --git a/weblayer/browser/java/translations/weblayer_strings_af.xtb b/weblayer/browser/java/translations/weblayer_strings_af.xtb deleted file mode 100644 index 4036102..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_af.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="af"> -<translation id="8298278839890148234">Webblaaieraktiwiteit</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_am.xtb b/weblayer/browser/java/translations/weblayer_strings_am.xtb deleted file mode 100644 index 2fd6e46a..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_am.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="am"> -<translation id="8298278839890148234">የድር አሳሽ እንቅስቃሴ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ar.xtb b/weblayer/browser/java/translations/weblayer_strings_ar.xtb deleted file mode 100644 index 55fcefe..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ar.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ar"> -<translation id="8298278839890148234">نشاط التصفُّح على الويب</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_as.xtb b/weblayer/browser/java/translations/weblayer_strings_as.xtb deleted file mode 100644 index db63c41..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_as.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="as"> -<translation id="8298278839890148234">ৱেব ব্ৰাউজাৰৰ কার্যকলাপ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_az.xtb b/weblayer/browser/java/translations/weblayer_strings_az.xtb deleted file mode 100644 index 684871c..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_az.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="az"> -<translation id="8298278839890148234">Veb axtarış fəaliyyəti</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_be.xtb b/weblayer/browser/java/translations/weblayer_strings_be.xtb deleted file mode 100644 index 4c18cf2..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_be.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="be"> -<translation id="8298278839890148234">Дзеянні ў вэб-браўзеры</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_bg.xtb b/weblayer/browser/java/translations/weblayer_strings_bg.xtb deleted file mode 100644 index 1e7789939c0..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_bg.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="bg"> -<translation id="8298278839890148234">Активност в уеб браузъра</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_bn.xtb b/weblayer/browser/java/translations/weblayer_strings_bn.xtb deleted file mode 100644 index 374b817..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_bn.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="bn"> -<translation id="8298278839890148234">ওয়েব ব্রাউজার অ্যাক্টিভিটি</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_bs.xtb b/weblayer/browser/java/translations/weblayer_strings_bs.xtb deleted file mode 100644 index 4fb2dbb3..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_bs.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="bs"> -<translation id="8298278839890148234">Aktivnost web preglednika</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ca.xtb b/weblayer/browser/java/translations/weblayer_strings_ca.xtb deleted file mode 100644 index ba2d4e4..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ca.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ca"> -<translation id="8298278839890148234">Activitat del navegador web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_cs.xtb b/weblayer/browser/java/translations/weblayer_strings_cs.xtb deleted file mode 100644 index 5710c42..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_cs.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="cs"> -<translation id="8298278839890148234">Aktivita ve webovém prohlížeči</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_cy.xtb b/weblayer/browser/java/translations/weblayer_strings_cy.xtb deleted file mode 100644 index 701be26..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_cy.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="cy"> -<translation id="8298278839890148234">Gweithgarwch pori'r we</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_da.xtb b/weblayer/browser/java/translations/weblayer_strings_da.xtb deleted file mode 100644 index 63df7f5..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_da.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="da"> -<translation id="8298278839890148234">Webbrowseraktivitet</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_de.xtb b/weblayer/browser/java/translations/weblayer_strings_de.xtb deleted file mode 100644 index a6c724e0..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_de.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="de"> -<translation id="8298278839890148234">Webbrowseraktivitäten</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_el.xtb b/weblayer/browser/java/translations/weblayer_strings_el.xtb deleted file mode 100644 index 91f7efb7..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_el.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="el"> -<translation id="8298278839890148234">Δραστηριότητα προγράμματος περιήγησης στον ιστό</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb b/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb deleted file mode 100644 index 078cecb..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="en-GB"> -<translation id="8298278839890148234">Web browser activity</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_es-419.xtb b/weblayer/browser/java/translations/weblayer_strings_es-419.xtb deleted file mode 100644 index e529fa34..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_es-419.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="es-419"> -<translation id="8298278839890148234">Actividad del navegador web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_es.xtb b/weblayer/browser/java/translations/weblayer_strings_es.xtb deleted file mode 100644 index fcf6da5..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_es.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="es"> -<translation id="8298278839890148234">Actividad del navegador web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_et.xtb b/weblayer/browser/java/translations/weblayer_strings_et.xtb deleted file mode 100644 index 37ada0e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_et.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="et"> -<translation id="8298278839890148234">Veebibrauseri tegevused</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_eu.xtb b/weblayer/browser/java/translations/weblayer_strings_eu.xtb deleted file mode 100644 index 2698f9f..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_eu.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="eu"> -<translation id="8298278839890148234">Sareko arakatze-jarduerak</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_fa.xtb b/weblayer/browser/java/translations/weblayer_strings_fa.xtb deleted file mode 100644 index 77daea8..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_fa.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="fa"> -<translation id="8298278839890148234">فعالیت مرورگر وب</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_fi.xtb b/weblayer/browser/java/translations/weblayer_strings_fi.xtb deleted file mode 100644 index 78a8d79..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_fi.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="fi"> -<translation id="8298278839890148234">Verkon selaustoiminta</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_fil.xtb b/weblayer/browser/java/translations/weblayer_strings_fil.xtb deleted file mode 100644 index 08f97ff..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_fil.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="fil"> -<translation id="8298278839890148234">Aktibidad ng web browser</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb b/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb deleted file mode 100644 index 537978c..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="fr-CA"> -<translation id="8298278839890148234">Activité de navigation Web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_fr.xtb b/weblayer/browser/java/translations/weblayer_strings_fr.xtb deleted file mode 100644 index 9810a3e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_fr.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="fr"> -<translation id="8298278839890148234">Activité de navigation sur le Web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_gl.xtb b/weblayer/browser/java/translations/weblayer_strings_gl.xtb deleted file mode 100644 index c315bcb..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_gl.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="gl"> -<translation id="8298278839890148234">Actividade de navegación pola Web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_gu.xtb b/weblayer/browser/java/translations/weblayer_strings_gu.xtb deleted file mode 100644 index 9e2ee22..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_gu.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="gu"> -<translation id="8298278839890148234">વેબ બ્રાઉઝરની પ્રવૃત્તિ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_hi.xtb b/weblayer/browser/java/translations/weblayer_strings_hi.xtb deleted file mode 100644 index a9ae0e70..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_hi.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="hi"> -<translation id="8298278839890148234">वेब ब्राउज़र की गतिविधि</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_hr.xtb b/weblayer/browser/java/translations/weblayer_strings_hr.xtb deleted file mode 100644 index bc0817b9..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_hr.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="hr"> -<translation id="8298278839890148234">Aktivnost u web-pregledniku</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_hu.xtb b/weblayer/browser/java/translations/weblayer_strings_hu.xtb deleted file mode 100644 index 587b17f..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_hu.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="hu"> -<translation id="8298278839890148234">Böngészős tevékenységek</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_hy.xtb b/weblayer/browser/java/translations/weblayer_strings_hy.xtb deleted file mode 100644 index c5676da7..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_hy.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="hy"> -<translation id="8298278839890148234">Գործողություններ դիտարկիչում</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_id.xtb b/weblayer/browser/java/translations/weblayer_strings_id.xtb deleted file mode 100644 index 31b5fe5d..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_id.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="id"> -<translation id="8298278839890148234">Aktivitas penjelajahan web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_is.xtb b/weblayer/browser/java/translations/weblayer_strings_is.xtb deleted file mode 100644 index 923602b..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_is.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="is"> -<translation id="8298278839890148234">Vafranotkun</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_it.xtb b/weblayer/browser/java/translations/weblayer_strings_it.xtb deleted file mode 100644 index c4dc6e6..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_it.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="it"> -<translation id="8298278839890148234">Attività del browser web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_iw.xtb b/weblayer/browser/java/translations/weblayer_strings_iw.xtb deleted file mode 100644 index bea498fe..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_iw.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="iw"> -<translation id="8298278839890148234">פעילות דפדפן אינטרנט</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ja.xtb b/weblayer/browser/java/translations/weblayer_strings_ja.xtb deleted file mode 100644 index 091fdcc..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ja.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ja"> -<translation id="8298278839890148234">ウェブブラウザのアクティビティ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ka.xtb b/weblayer/browser/java/translations/weblayer_strings_ka.xtb deleted file mode 100644 index 57bc785..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ka.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ka"> -<translation id="8298278839890148234">ვებ-ბრაუზერის აქტივობა</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_kk.xtb b/weblayer/browser/java/translations/weblayer_strings_kk.xtb deleted file mode 100644 index d18117e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_kk.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="kk"> -<translation id="8298278839890148234">Браузерді қолдану мәліметі</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_km.xtb b/weblayer/browser/java/translations/weblayer_strings_km.xtb deleted file mode 100644 index 312955f..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_km.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="km"> -<translation id="8298278839890148234">សកម្មភាពកម្មវិធីរុករកតាមអ៊ីនធឺណិត</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_kn.xtb b/weblayer/browser/java/translations/weblayer_strings_kn.xtb deleted file mode 100644 index 91524cd..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_kn.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="kn"> -<translation id="8298278839890148234">ವೆಬ್ ಬ್ರೌಸಿಂಗ್ ಚಟುವಟಿಕೆ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ko.xtb b/weblayer/browser/java/translations/weblayer_strings_ko.xtb deleted file mode 100644 index 742a533..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ko.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ko"> -<translation id="8298278839890148234">웹브라우저 활동</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ky.xtb b/weblayer/browser/java/translations/weblayer_strings_ky.xtb deleted file mode 100644 index 2d0f4b4..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ky.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ky"> -<translation id="8298278839890148234">Көрүлгөн вебсайттар</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_lo.xtb b/weblayer/browser/java/translations/weblayer_strings_lo.xtb deleted file mode 100644 index fba8f18..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_lo.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="lo"> -<translation id="8298278839890148234">ການເຄື່ອນໄຫວໃນໂປຣແກຣມທ່ອງເວັບ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_lt.xtb b/weblayer/browser/java/translations/weblayer_strings_lt.xtb deleted file mode 100644 index a1a90e6f..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_lt.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="lt"> -<translation id="8298278839890148234">Žiniatinklio naršyklės veikla</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_lv.xtb b/weblayer/browser/java/translations/weblayer_strings_lv.xtb deleted file mode 100644 index 5d96547..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_lv.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="lv"> -<translation id="8298278839890148234">Pārlūkošanas darbības</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_mk.xtb b/weblayer/browser/java/translations/weblayer_strings_mk.xtb deleted file mode 100644 index 2f2d3c2..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_mk.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="mk"> -<translation id="8298278839890148234">Активност на прелистувачот</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ml.xtb b/weblayer/browser/java/translations/weblayer_strings_ml.xtb deleted file mode 100644 index d4a0180..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ml.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ml"> -<translation id="8298278839890148234">വെബ് ബ്രൗസർ ആക്റ്റിവിറ്റി</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_mn.xtb b/weblayer/browser/java/translations/weblayer_strings_mn.xtb deleted file mode 100644 index 79d5dac..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_mn.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="mn"> -<translation id="8298278839890148234">Хөтчийн үйл ажиллагаа</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_mr.xtb b/weblayer/browser/java/translations/weblayer_strings_mr.xtb deleted file mode 100644 index 5a3e682075..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_mr.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="mr"> -<translation id="8298278839890148234">वेब ब्राउझर अॅक्टिव्हिटी</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ms.xtb b/weblayer/browser/java/translations/weblayer_strings_ms.xtb deleted file mode 100644 index e105952..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ms.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ms"> -<translation id="8298278839890148234">Aktiviti penyemakan imbas</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_my.xtb b/weblayer/browser/java/translations/weblayer_strings_my.xtb deleted file mode 100644 index e8bf710e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_my.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="my"> -<translation id="8298278839890148234">ဝဘ်ဘရောင်ဇာ လုပ်ဆောင်ချက်</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ne.xtb b/weblayer/browser/java/translations/weblayer_strings_ne.xtb deleted file mode 100644 index 06ec47e4..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ne.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ne"> -<translation id="8298278839890148234">ब्राउजर प्रयोग गरी गरिएको क्रियाकलाप</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_nl.xtb b/weblayer/browser/java/translations/weblayer_strings_nl.xtb deleted file mode 100644 index 759b04e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_nl.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="nl"> -<translation id="8298278839890148234">Webbrowseractivititeit</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_no.xtb b/weblayer/browser/java/translations/weblayer_strings_no.xtb deleted file mode 100644 index 409a800e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_no.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="no"> -<translation id="8298278839890148234">Nettleseraktivitet</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_or.xtb b/weblayer/browser/java/translations/weblayer_strings_or.xtb deleted file mode 100644 index f88f14b..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_or.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="or"> -<translation id="8298278839890148234">ୱେବ୍ ବ୍ରାଉଜର୍ କାର୍ଯ୍ୟକଳାପ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_pa.xtb b/weblayer/browser/java/translations/weblayer_strings_pa.xtb deleted file mode 100644 index 0d4c8c7..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_pa.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="pa"> -<translation id="8298278839890148234">ਵੈੱਬ ਬ੍ਰਾਊਜ਼ਰ ਸਰਗਰਮੀ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_pl.xtb b/weblayer/browser/java/translations/weblayer_strings_pl.xtb deleted file mode 100644 index 52a394f..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_pl.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="pl"> -<translation id="8298278839890148234">Aktywność w przeglądarce</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb b/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb deleted file mode 100644 index dd6972f7..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="pt-BR"> -<translation id="8298278839890148234">Atividade do navegador da Web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb b/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb deleted file mode 100644 index 7696656..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="pt-PT"> -<translation id="8298278839890148234">Atividade do navegador de Internet</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ro.xtb b/weblayer/browser/java/translations/weblayer_strings_ro.xtb deleted file mode 100644 index 12f45d2..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ro.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ro"> -<translation id="8298278839890148234">Activitatea în browserul web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ru.xtb b/weblayer/browser/java/translations/weblayer_strings_ru.xtb deleted file mode 100644 index 401647d..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ru.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ru"> -<translation id="8298278839890148234">Действия в веб-браузере</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_si.xtb b/weblayer/browser/java/translations/weblayer_strings_si.xtb deleted file mode 100644 index 1e95ef5..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_si.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="si"> -<translation id="8298278839890148234">වෙබ් බ්රවුසර ක්රියාකාරකම</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_sk.xtb b/weblayer/browser/java/translations/weblayer_strings_sk.xtb deleted file mode 100644 index 53b2d4e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_sk.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="sk"> -<translation id="8298278839890148234">Aktivita webového prehliadača</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_sl.xtb b/weblayer/browser/java/translations/weblayer_strings_sl.xtb deleted file mode 100644 index 152968e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_sl.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="sl"> -<translation id="8298278839890148234">Dejavnost brskalnika</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_sq.xtb b/weblayer/browser/java/translations/weblayer_strings_sq.xtb deleted file mode 100644 index 2e0a695..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_sq.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="sq"> -<translation id="8298278839890148234">Aktiviteti i shfletuesit të uebit</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb b/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb deleted file mode 100644 index 24f2600..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="sr-Latn"> -<translation id="8298278839890148234">Aktivnosti u veb-pregledaču</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_sr.xtb b/weblayer/browser/java/translations/weblayer_strings_sr.xtb deleted file mode 100644 index 9008032..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_sr.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="sr"> -<translation id="8298278839890148234">Активности у веб-прегледачу</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_sv.xtb b/weblayer/browser/java/translations/weblayer_strings_sv.xtb deleted file mode 100644 index 610cb47e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_sv.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="sv"> -<translation id="8298278839890148234">Webbläsaraktivitet</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_sw.xtb b/weblayer/browser/java/translations/weblayer_strings_sw.xtb deleted file mode 100644 index cf0a4b7..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_sw.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="sw"> -<translation id="8298278839890148234">Shughuli za kivinjari</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ta.xtb b/weblayer/browser/java/translations/weblayer_strings_ta.xtb deleted file mode 100644 index 8a47545a..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ta.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ta"> -<translation id="8298278839890148234">இணைய உலாவியின் செயல்பாடு</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_te.xtb b/weblayer/browser/java/translations/weblayer_strings_te.xtb deleted file mode 100644 index 3894c53..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_te.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="te"> -<translation id="8298278839890148234">బ్రౌజింగ్ యాక్టివిటీ</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_th.xtb b/weblayer/browser/java/translations/weblayer_strings_th.xtb deleted file mode 100644 index 1c8e14c..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_th.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="th"> -<translation id="8298278839890148234">กิจกรรมของเว็บเบราว์เซอร์</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_tr.xtb b/weblayer/browser/java/translations/weblayer_strings_tr.xtb deleted file mode 100644 index 11d4ab4..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_tr.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="tr"> -<translation id="8298278839890148234">Web tarayıcısı etkinliği</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_uk.xtb b/weblayer/browser/java/translations/weblayer_strings_uk.xtb deleted file mode 100644 index f863045..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_uk.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="uk"> -<translation id="8298278839890148234">Дії у веб-переглядачі</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_ur.xtb b/weblayer/browser/java/translations/weblayer_strings_ur.xtb deleted file mode 100644 index 57e4688..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_ur.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="ur"> -<translation id="8298278839890148234">ویب براؤزر کی سرگرمی</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_uz.xtb b/weblayer/browser/java/translations/weblayer_strings_uz.xtb deleted file mode 100644 index 92655c7..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_uz.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="uz"> -<translation id="8298278839890148234">Veb-brauzerdagi faoliyat</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_vi.xtb b/weblayer/browser/java/translations/weblayer_strings_vi.xtb deleted file mode 100644 index 2f57bd6..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_vi.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="vi"> -<translation id="8298278839890148234">Hoạt động duyệt web</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb b/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb deleted file mode 100644 index 84075ec..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="zh-CN"> -<translation id="8298278839890148234">网络浏览器活动</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb b/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb deleted file mode 100644 index abd42fb..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="zh-HK"> -<translation id="8298278839890148234">網絡瀏覽器活動</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb b/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb deleted file mode 100644 index ecea64e..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="zh-TW"> -<translation id="8298278839890148234">網路瀏覽器活動</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/translations/weblayer_strings_zu.xtb b/weblayer/browser/java/translations/weblayer_strings_zu.xtb deleted file mode 100644 index 1da5d91..0000000 --- a/weblayer/browser/java/translations/weblayer_strings_zu.xtb +++ /dev/null
@@ -1,5 +0,0 @@ -<?xml version="1.0" ?> -<!DOCTYPE translationbundle> -<translationbundle lang="zu"> -<translation id="8298278839890148234">Umsebenzi wesiphequluli sewebhu</translation> -</translationbundle> \ No newline at end of file
diff --git a/weblayer/browser/java/weblayer_strings.grd b/weblayer/browser/java/weblayer_strings.grd deleted file mode 100644 index 27e5f79c..0000000 --- a/weblayer/browser/java/weblayer_strings.grd +++ /dev/null
@@ -1,181 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<grit latest_public_release="0" current_release="1" - output_all_resource_defines="false" source_lang_id="en" enc_check="möl"> - <outputs> - <output filename="values-af/weblayer_strings.xml" lang="af" type="android" /> - <output filename="values-am/weblayer_strings.xml" lang="am" type="android" /> - <output filename="values-ar/weblayer_strings.xml" lang="ar" type="android" /> - <output filename="values-as/weblayer_strings.xml" lang="as" type="android" /> - <output filename="values-az/weblayer_strings.xml" lang="az" type="android" /> - <output filename="values-be/weblayer_strings.xml" lang="be" type="android" /> - <output filename="values-bg/weblayer_strings.xml" lang="bg" type="android" /> - <output filename="values-bn/weblayer_strings.xml" lang="bn" type="android" /> - <output filename="values-bs/weblayer_strings.xml" lang="bs" type="android" /> - <output filename="values-ca/weblayer_strings.xml" lang="ca" type="android" /> - <output filename="values-cs/weblayer_strings.xml" lang="cs" type="android" /> - <output filename="values-da/weblayer_strings.xml" lang="da" type="android" /> - <output filename="values-de/weblayer_strings.xml" lang="de" type="android" /> - <output filename="values-el/weblayer_strings.xml" lang="el" type="android" /> - <output filename="values/weblayer_strings.xml" lang="en" type="android" /> - <output filename="values-en-rGB/weblayer_strings.xml" lang="en-GB" type="android" /> - <output filename="values-es/weblayer_strings.xml" lang="es" type="android" /> - <output filename="values-es-rUS/weblayer_strings.xml" lang="es-419" type="android" /> - <output filename="values-et/weblayer_strings.xml" lang="et" type="android" /> - <output filename="values-eu/weblayer_strings.xml" lang="eu" type="android" /> - <output filename="values-fa/weblayer_strings.xml" lang="fa" type="android" /> - <output filename="values-fi/weblayer_strings.xml" lang="fi" type="android" /> - <output filename="values-tl/weblayer_strings.xml" lang="fil" type="android" /> - <output filename="values-fr/weblayer_strings.xml" lang="fr" type="android" /> - <output filename="values-fr-rCA/weblayer_strings.xml" lang="fr-CA" type="android" /> - <output filename="values-gl/weblayer_strings.xml" lang="gl" type="android" /> - <output filename="values-gu/weblayer_strings.xml" lang="gu" type="android" /> - <output filename="values-hi/weblayer_strings.xml" lang="hi" type="android" /> - <output filename="values-hr/weblayer_strings.xml" lang="hr" type="android" /> - <output filename="values-hu/weblayer_strings.xml" lang="hu" type="android" /> - <output filename="values-hy/weblayer_strings.xml" lang="hy" type="android" /> - <output filename="values-in/weblayer_strings.xml" lang="id" type="android" /> - <output filename="values-is/weblayer_strings.xml" lang="is" type="android" /> - <output filename="values-it/weblayer_strings.xml" lang="it" type="android" /> - <output filename="values-iw/weblayer_strings.xml" lang="iw" type="android" /> - <output filename="values-ja/weblayer_strings.xml" lang="ja" type="android" /> - <output filename="values-ka/weblayer_strings.xml" lang="ka" type="android" /> - <output filename="values-kk/weblayer_strings.xml" lang="kk" type="android" /> - <output filename="values-km/weblayer_strings.xml" lang="km" type="android" /> - <output filename="values-kn/weblayer_strings.xml" lang="kn" type="android" /> - <output filename="values-ko/weblayer_strings.xml" lang="ko" type="android" /> - <output filename="values-ky/weblayer_strings.xml" lang="ky" type="android" /> - <output filename="values-lo/weblayer_strings.xml" lang="lo" type="android" /> - <output filename="values-lt/weblayer_strings.xml" lang="lt" type="android" /> - <output filename="values-lv/weblayer_strings.xml" lang="lv" type="android" /> - <output filename="values-mk/weblayer_strings.xml" lang="mk" type="android" /> - <output filename="values-ml/weblayer_strings.xml" lang="ml" type="android" /> - <output filename="values-mn/weblayer_strings.xml" lang="mn" type="android" /> - <output filename="values-mr/weblayer_strings.xml" lang="mr" type="android" /> - <output filename="values-ms/weblayer_strings.xml" lang="ms" type="android" /> - <output filename="values-my/weblayer_strings.xml" lang="my" type="android" /> - <output filename="values-ne/weblayer_strings.xml" lang="ne" type="android" /> - <output filename="values-nl/weblayer_strings.xml" lang="nl" type="android" /> - <output filename="values-nb/weblayer_strings.xml" lang="no" type="android" /> - <output filename="values-or/weblayer_strings.xml" lang="or" type="android" /> - <output filename="values-pa/weblayer_strings.xml" lang="pa" type="android" /> - <output filename="values-pl/weblayer_strings.xml" lang="pl" type="android" /> - <output filename="values-pt-rBR/weblayer_strings.xml" lang="pt-BR" type="android" /> - <output filename="values-pt-rPT/weblayer_strings.xml" lang="pt-PT" type="android" /> - <output filename="values-ro/weblayer_strings.xml" lang="ro" type="android" /> - <output filename="values-ru/weblayer_strings.xml" lang="ru" type="android" /> - <output filename="values-si/weblayer_strings.xml" lang="si" type="android" /> - <output filename="values-sk/weblayer_strings.xml" lang="sk" type="android" /> - <output filename="values-sl/weblayer_strings.xml" lang="sl" type="android" /> - <output filename="values-sq/weblayer_strings.xml" lang="sq" type="android" /> - <output filename="values-sr/weblayer_strings.xml" lang="sr" type="android" /> - <output filename="values-b+sr+Latn/weblayer_strings.xml" lang="sr-Latn" type="android" /> - <output filename="values-sv/weblayer_strings.xml" lang="sv" type="android" /> - <output filename="values-sw/weblayer_strings.xml" lang="sw" type="android" /> - <output filename="values-ta/weblayer_strings.xml" lang="ta" type="android" /> - <output filename="values-te/weblayer_strings.xml" lang="te" type="android" /> - <output filename="values-th/weblayer_strings.xml" lang="th" type="android" /> - <output filename="values-tr/weblayer_strings.xml" lang="tr" type="android" /> - <output filename="values-uk/weblayer_strings.xml" lang="uk" type="android" /> - <output filename="values-ur/weblayer_strings.xml" lang="ur" type="android" /> - <output filename="values-uz/weblayer_strings.xml" lang="uz" type="android" /> - <output filename="values-vi/weblayer_strings.xml" lang="vi" type="android" /> - <output filename="values-zh-rCN/weblayer_strings.xml" lang="zh-CN" type="android" /> - <output filename="values-zh-rHK/weblayer_strings.xml" lang="zh-HK" type="android" /> - <output filename="values-zh-rTW/weblayer_strings.xml" lang="zh-TW" type="android" /> - <output filename="values-zu/weblayer_strings.xml" lang="zu" type="android" /> - <!-- Pseudolocales --> - <output filename="values-ar-rXB/weblayer_strings.xml" lang="ar-XB" type="android" /> - <output filename="values-en-rXA/weblayer_strings.xml" lang="en-XA" type="android" /> - </outputs> - <translations> - <file path="translations/weblayer_strings_af.xtb" lang="af" /> - <file path="translations/weblayer_strings_am.xtb" lang="am" /> - <file path="translations/weblayer_strings_ar.xtb" lang="ar" /> - <file path="translations/weblayer_strings_as.xtb" lang="as" /> - <file path="translations/weblayer_strings_az.xtb" lang="az" /> - <file path="translations/weblayer_strings_be.xtb" lang="be" /> - <file path="translations/weblayer_strings_bg.xtb" lang="bg" /> - <file path="translations/weblayer_strings_bn.xtb" lang="bn" /> - <file path="translations/weblayer_strings_bs.xtb" lang="bs" /> - <file path="translations/weblayer_strings_ca.xtb" lang="ca" /> - <file path="translations/weblayer_strings_cs.xtb" lang="cs" /> - <file path="translations/weblayer_strings_cy.xtb" lang="cy" /> - <file path="translations/weblayer_strings_da.xtb" lang="da" /> - <file path="translations/weblayer_strings_de.xtb" lang="de" /> - <file path="translations/weblayer_strings_el.xtb" lang="el" /> - <file path="translations/weblayer_strings_en-GB.xtb" lang="en-GB" /> - <file path="translations/weblayer_strings_es.xtb" lang="es" /> - <file path="translations/weblayer_strings_es-419.xtb" lang="es-419" /> - <file path="translations/weblayer_strings_et.xtb" lang="et" /> - <file path="translations/weblayer_strings_eu.xtb" lang="eu" /> - <file path="translations/weblayer_strings_fa.xtb" lang="fa" /> - <file path="translations/weblayer_strings_fi.xtb" lang="fi" /> - <file path="translations/weblayer_strings_fil.xtb" lang="fil" /> - <file path="translations/weblayer_strings_fr.xtb" lang="fr" /> - <file path="translations/weblayer_strings_fr-CA.xtb" lang="fr-CA" /> - <file path="translations/weblayer_strings_gl.xtb" lang="gl" /> - <file path="translations/weblayer_strings_gu.xtb" lang="gu" /> - <file path="translations/weblayer_strings_hi.xtb" lang="hi" /> - <file path="translations/weblayer_strings_hr.xtb" lang="hr" /> - <file path="translations/weblayer_strings_hu.xtb" lang="hu" /> - <file path="translations/weblayer_strings_hy.xtb" lang="hy" /> - <file path="translations/weblayer_strings_id.xtb" lang="id" /> - <file path="translations/weblayer_strings_is.xtb" lang="is" /> - <file path="translations/weblayer_strings_it.xtb" lang="it" /> - <file path="translations/weblayer_strings_iw.xtb" lang="iw" /> - <file path="translations/weblayer_strings_ja.xtb" lang="ja" /> - <file path="translations/weblayer_strings_ka.xtb" lang="ka" /> - <file path="translations/weblayer_strings_kk.xtb" lang="kk" /> - <file path="translations/weblayer_strings_km.xtb" lang="km" /> - <file path="translations/weblayer_strings_kn.xtb" lang="kn" /> - <file path="translations/weblayer_strings_ko.xtb" lang="ko" /> - <file path="translations/weblayer_strings_ky.xtb" lang="ky" /> - <file path="translations/weblayer_strings_lo.xtb" lang="lo" /> - <file path="translations/weblayer_strings_lt.xtb" lang="lt" /> - <file path="translations/weblayer_strings_lv.xtb" lang="lv" /> - <file path="translations/weblayer_strings_mk.xtb" lang="mk" /> - <file path="translations/weblayer_strings_ml.xtb" lang="ml" /> - <file path="translations/weblayer_strings_mn.xtb" lang="mn" /> - <file path="translations/weblayer_strings_mr.xtb" lang="mr" /> - <file path="translations/weblayer_strings_ms.xtb" lang="ms" /> - <file path="translations/weblayer_strings_my.xtb" lang="my" /> - <file path="translations/weblayer_strings_ne.xtb" lang="ne" /> - <file path="translations/weblayer_strings_nl.xtb" lang="nl" /> - <file path="translations/weblayer_strings_no.xtb" lang="no" /> - <file path="translations/weblayer_strings_or.xtb" lang="or" /> - <file path="translations/weblayer_strings_pa.xtb" lang="pa" /> - <file path="translations/weblayer_strings_pl.xtb" lang="pl" /> - <file path="translations/weblayer_strings_pt-BR.xtb" lang="pt-BR" /> - <file path="translations/weblayer_strings_pt-PT.xtb" lang="pt-PT" /> - <file path="translations/weblayer_strings_ro.xtb" lang="ro" /> - <file path="translations/weblayer_strings_ru.xtb" lang="ru" /> - <file path="translations/weblayer_strings_si.xtb" lang="si" /> - <file path="translations/weblayer_strings_sk.xtb" lang="sk" /> - <file path="translations/weblayer_strings_sl.xtb" lang="sl" /> - <file path="translations/weblayer_strings_sq.xtb" lang="sq" /> - <file path="translations/weblayer_strings_sr.xtb" lang="sr" /> - <file path="translations/weblayer_strings_sr-Latn.xtb" lang="sr-Latn" /> - <file path="translations/weblayer_strings_sv.xtb" lang="sv" /> - <file path="translations/weblayer_strings_sw.xtb" lang="sw" /> - <file path="translations/weblayer_strings_ta.xtb" lang="ta" /> - <file path="translations/weblayer_strings_te.xtb" lang="te" /> - <file path="translations/weblayer_strings_th.xtb" lang="th" /> - <file path="translations/weblayer_strings_tr.xtb" lang="tr" /> - <file path="translations/weblayer_strings_uk.xtb" lang="uk" /> - <file path="translations/weblayer_strings_ur.xtb" lang="ur" /> - <file path="translations/weblayer_strings_uz.xtb" lang="uz" /> - <file path="translations/weblayer_strings_vi.xtb" lang="vi" /> - <file path="translations/weblayer_strings_zh-CN.xtb" lang="zh-CN" /> - <file path="translations/weblayer_strings_zh-HK.xtb" lang="zh-HK" /> - <file path="translations/weblayer_strings_zh-TW.xtb" lang="zh-TW" /> - <file path="translations/weblayer_strings_zu.xtb" lang="zu" /> - </translations> - <release seq="1"> - <messages fallback_to_english="true"> - <message name="IDS_WEBLAYER_NOTIFICATION_CHANNEL_GROUP_NAME" desc="The user-facing label for the notification channel group used for notifications arising from web browsing activity."> - Web browser activity - </message> - </messages> - </release> -</grit>
diff --git a/weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.cc b/weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.cc deleted file mode 100644 index 5baad5d..0000000 --- a/weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.cc +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h" - -#include "components/javascript_dialogs/android/tab_modal_dialog_view_android.h" -#include "weblayer/browser/tab_impl.h" - -namespace weblayer { - -JavaScriptTabModalDialogManagerDelegateAndroid:: - JavaScriptTabModalDialogManagerDelegateAndroid( - content::WebContents* web_contents) - : web_contents_(web_contents) {} - -JavaScriptTabModalDialogManagerDelegateAndroid:: - ~JavaScriptTabModalDialogManagerDelegateAndroid() = default; - -base::WeakPtr<javascript_dialogs::TabModalDialogView> -JavaScriptTabModalDialogManagerDelegateAndroid::CreateNewDialog( - content::WebContents* alerting_web_contents, - const std::u16string& title, - content::JavaScriptDialogType dialog_type, - const std::u16string& message_text, - const std::u16string& default_prompt_text, - content::JavaScriptDialogManager::DialogClosedCallback - callback_on_button_clicked, - base::OnceClosure callback_on_cancelled) { - return javascript_dialogs::TabModalDialogViewAndroid::Create( - web_contents_, alerting_web_contents, title, dialog_type, message_text, - default_prompt_text, std::move(callback_on_button_clicked), - std::move(callback_on_cancelled)); -} - -void JavaScriptTabModalDialogManagerDelegateAndroid::WillRunDialog() {} - -void JavaScriptTabModalDialogManagerDelegateAndroid::DidCloseDialog() {} - -void JavaScriptTabModalDialogManagerDelegateAndroid::SetTabNeedsAttention( - bool attention) {} - -bool JavaScriptTabModalDialogManagerDelegateAndroid::IsWebContentsForemost() { - // TODO(estade): this should also check if the browser is active/showing. - DCHECK(TabImpl::FromWebContents(web_contents_)); - return TabImpl::FromWebContents(web_contents_)->IsActive(); -} - -bool JavaScriptTabModalDialogManagerDelegateAndroid::IsApp() { - return false; -} - -} // namespace weblayer
diff --git a/weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h b/weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h deleted file mode 100644 index 37dd1e4..0000000 --- a/weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_JAVASCRIPT_TAB_MODAL_DIALOG_MANAGER_DELEGATE_ANDROID_H_ -#define WEBLAYER_BROWSER_JAVASCRIPT_TAB_MODAL_DIALOG_MANAGER_DELEGATE_ANDROID_H_ - -#include "base/memory/raw_ptr.h" -#include "components/javascript_dialogs/tab_modal_dialog_manager_delegate.h" - -namespace content { -class WebContents; -} - -namespace weblayer { - -class JavaScriptTabModalDialogManagerDelegateAndroid - : public javascript_dialogs::TabModalDialogManagerDelegate { - public: - explicit JavaScriptTabModalDialogManagerDelegateAndroid( - content::WebContents* web_contents); - JavaScriptTabModalDialogManagerDelegateAndroid( - const JavaScriptTabModalDialogManagerDelegateAndroid& other) = delete; - JavaScriptTabModalDialogManagerDelegateAndroid& operator=( - const JavaScriptTabModalDialogManagerDelegateAndroid& other) = delete; - ~JavaScriptTabModalDialogManagerDelegateAndroid() override; - - // javascript_dialogs::TabModalDialogManagerDelegate - base::WeakPtr<javascript_dialogs::TabModalDialogView> CreateNewDialog( - content::WebContents* alerting_web_contents, - const std::u16string& title, - content::JavaScriptDialogType dialog_type, - const std::u16string& message_text, - const std::u16string& default_prompt_text, - content::JavaScriptDialogManager::DialogClosedCallback dialog_callback, - base::OnceClosure dialog_closed_callback) override; - void WillRunDialog() override; - void DidCloseDialog() override; - void SetTabNeedsAttention(bool attention) override; - bool IsWebContentsForemost() override; - bool IsApp() override; - - private: - raw_ptr<content::WebContents> web_contents_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_JAVASCRIPT_TAB_MODAL_DIALOG_MANAGER_DELEGATE_ANDROID_H_
diff --git a/weblayer/browser/large_sticky_ad_intervention_browsertest.cc b/weblayer/browser/large_sticky_ad_intervention_browsertest.cc deleted file mode 100644 index 9d4ad9c..0000000 --- a/weblayer/browser/large_sticky_ad_intervention_browsertest.cc +++ /dev/null
@@ -1,150 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/test/scoped_feature_list.h" -#include "components/page_load_metrics/browser/observers/ad_metrics/ad_intervention_browser_test_utils.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" -#include "components/subresource_filter/core/browser/subresource_filter_features.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "components/subresource_filter/core/common/test_ruleset_utils.h" -#include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/features.h" -#include "url/gurl.h" -#include "weblayer/test/subresource_filter_browser_test_harness.h" - -namespace weblayer { - -namespace { - -const char kAdsInterventionRecordedHistogram[] = - "SubresourceFilter.PageLoad.AdsInterventionTriggered"; - -} // namespace - -class LargeStickyAdViolationBrowserTest : public SubresourceFilterBrowserTest { - public: - LargeStickyAdViolationBrowserTest() = default; - - void SetUp() override { - std::vector<base::test::FeatureRef> enabled = { - subresource_filter::kAdTagging, - subresource_filter::kAdsInterventionsEnforced}; - std::vector<base::test::FeatureRef> disabled = { - blink::features::kFrequencyCappingForLargeStickyAdDetection}; - - feature_list_.InitWithFeatures(enabled, disabled); - SubresourceFilterBrowserTest::SetUp(); - } - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")}); - } - - protected: - base::test::ScopedFeatureList feature_list_; -}; - -IN_PROC_BROWSER_TEST_F(LargeStickyAdViolationBrowserTest, - NoLargeStickyAd_AdInterventionNotTriggered) { - base::HistogramTester histogram_tester; - - GURL url = embedded_test_server()->GetURL( - "a.com", "/ads_observer/large_scrollable_page_with_adiframe_writer.html"); - - page_load_metrics::NavigateAndWaitForFirstContentfulPaint(web_contents(), - url); - - // Reload the page. Since we haven't seen any ad violations, expect that the - // ad script is loaded and that the subresource filter UI doesn't show up. - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kLargeStickyAd, 0); -} - -IN_PROC_BROWSER_TEST_F(LargeStickyAdViolationBrowserTest, - LargeStickyAd_AdInterventionTriggered) { - base::HistogramTester histogram_tester; - - GURL url = embedded_test_server()->GetURL( - "a.com", "/ads_observer/large_scrollable_page_with_adiframe_writer.html"); - - page_load_metrics::NavigateAndWaitForFirstContentfulPaint(web_contents(), - url); - - page_load_metrics::TriggerAndDetectLargeStickyAd(web_contents()); - - // Reload the page. Since we are enforcing ad blocking on ads violations, - // expect that the ad script is not loaded and that the subresource filter UI - // shows up. - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 1); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kLargeStickyAd, 1); -} - -class LargeStickyAdViolationBrowserTestWithoutEnforcement - : public LargeStickyAdViolationBrowserTest { - public: - LargeStickyAdViolationBrowserTestWithoutEnforcement() = default; - - void SetUp() override { - std::vector<base::test::FeatureRef> enabled = { - subresource_filter::kAdTagging}; - std::vector<base::test::FeatureRef> disabled = { - subresource_filter::kAdsInterventionsEnforced, - blink::features::kFrequencyCappingForLargeStickyAdDetection}; - - feature_list_.InitWithFeatures(enabled, disabled); - SubresourceFilterBrowserTest::SetUp(); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -IN_PROC_BROWSER_TEST_F(LargeStickyAdViolationBrowserTestWithoutEnforcement, - LargeStickyAd_NoAdInterventionTriggered) { - base::HistogramTester histogram_tester; - - GURL url = embedded_test_server()->GetURL( - "a.com", "/ads_observer/large_scrollable_page_with_adiframe_writer.html"); - - page_load_metrics::NavigateAndWaitForFirstContentfulPaint(web_contents(), - url); - - page_load_metrics::TriggerAndDetectLargeStickyAd(web_contents()); - - // Reload the page. Since we are not enforcing ad blocking on ads violations, - // expect that the ad script is loaded and that the subresource filter UI - // doesn't show up. Expect a histogram recording as the intervention is - // running in dry run mode. - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kLargeStickyAd, 1); -} - -} // namespace weblayer
diff --git a/weblayer/browser/media/local_presentation_manager_factory.cc b/weblayer/browser/media/local_presentation_manager_factory.cc deleted file mode 100644 index 02c7cf08..0000000 --- a/weblayer/browser/media/local_presentation_manager_factory.cc +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/media/local_presentation_manager_factory.h" - -#include "base/no_destructor.h" - -namespace weblayer { - -// static -LocalPresentationManagerFactory* -LocalPresentationManagerFactory::GetInstance() { - static base::NoDestructor<LocalPresentationManagerFactory> instance; - return instance.get(); -} - -LocalPresentationManagerFactory::LocalPresentationManagerFactory() = default; -LocalPresentationManagerFactory::~LocalPresentationManagerFactory() = default; - -content::BrowserContext* -LocalPresentationManagerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/media/local_presentation_manager_factory.h b/weblayer/browser/media/local_presentation_manager_factory.h deleted file mode 100644 index b0a29b2..0000000 --- a/weblayer/browser/media/local_presentation_manager_factory.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_MEDIA_LOCAL_PRESENTATION_MANAGER_FACTORY_H_ -#define WEBLAYER_BROWSER_MEDIA_LOCAL_PRESENTATION_MANAGER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/media_router/browser/presentation/local_presentation_manager_factory.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -// A version of LocalPresentationManagerFactory that does not redirect from -// incognito to normal context. -class LocalPresentationManagerFactory - : public media_router::LocalPresentationManagerFactory { - public: - LocalPresentationManagerFactory(const LocalPresentationManagerFactory&) = - delete; - LocalPresentationManagerFactory& operator=( - const LocalPresentationManagerFactory&) = delete; - - static LocalPresentationManagerFactory* GetInstance(); - - private: - friend base::NoDestructor<LocalPresentationManagerFactory>; - - LocalPresentationManagerFactory(); - ~LocalPresentationManagerFactory() override; - - // BrowserContextKeyedServiceFactory interface. - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_MEDIA_LOCAL_PRESENTATION_MANAGER_FACTORY_H_
diff --git a/weblayer/browser/media/media_router_factory.cc b/weblayer/browser/media/media_router_factory.cc deleted file mode 100644 index 456625b..0000000 --- a/weblayer/browser/media/media_router_factory.cc +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/media/media_router_factory.h" - -#include "base/android/jni_android.h" -#include "base/no_destructor.h" -#include "components/media_router/browser/android/media_router_android.h" -#include "components/media_router/browser/android/media_router_dialog_controller_android.h" -#include "components/media_router/browser/media_router_dialog_controller.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/java/jni/MediaRouterClientImpl_jni.h" - -namespace weblayer { - -// static -MediaRouterFactory* MediaRouterFactory::GetInstance() { - static base::NoDestructor<MediaRouterFactory> instance; - return instance.get(); -} - -// static -bool MediaRouterFactory::IsFeatureEnabled() { - static bool enabled = Java_MediaRouterClientImpl_isMediaRouterEnabled( - base::android::AttachCurrentThread()); - return enabled; -} - -// static -void MediaRouterFactory::DoPlatformInitIfNeeded() { - static bool init_done = false; - if (init_done) - return; - - Java_MediaRouterClientImpl_initialize(base::android::AttachCurrentThread()); - - media_router::MediaRouterDialogController::SetGetOrCreate( - base::BindRepeating([](content::WebContents* web_contents) { - DCHECK(web_contents); - // This call does nothing if the controller already exists. - media_router::MediaRouterDialogControllerAndroid::CreateForWebContents( - web_contents); - return static_cast<media_router::MediaRouterDialogController*>( - media_router::MediaRouterDialogControllerAndroid::FromWebContents( - web_contents)); - })); - init_done = true; -} - -MediaRouterFactory::MediaRouterFactory() = default; -MediaRouterFactory::~MediaRouterFactory() = default; - -content::BrowserContext* MediaRouterFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -std::unique_ptr<KeyedService> -MediaRouterFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - std::unique_ptr<media_router::MediaRouterBase> media_router = - std::make_unique<media_router::MediaRouterAndroid>(); - media_router->Initialize(); - return media_router; -} - -} // namespace weblayer
diff --git a/weblayer/browser/media/media_router_factory.h b/weblayer/browser/media/media_router_factory.h deleted file mode 100644 index 0f5d3a8..0000000 --- a/weblayer/browser/media/media_router_factory.h +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_MEDIA_MEDIA_ROUTER_FACTORY_H_ -#define WEBLAYER_BROWSER_MEDIA_MEDIA_ROUTER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/media_router/browser/media_router_factory.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -class MediaRouterFactory : public media_router::MediaRouterFactory { - public: - MediaRouterFactory(const MediaRouterFactory&) = delete; - MediaRouterFactory& operator=(const MediaRouterFactory&) = delete; - - static MediaRouterFactory* GetInstance(); - - // Determines if media router related features should be enabled. - static bool IsFeatureEnabled(); - - // Performs platform and WebLayer-specific initialization for media_router. - static void DoPlatformInitIfNeeded(); - - private: - friend base::NoDestructor<MediaRouterFactory>; - - MediaRouterFactory(); - ~MediaRouterFactory() override; - - // MediaRouterFactory: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_MEDIA_MEDIA_ROUTER_FACTORY_H_
diff --git a/weblayer/browser/navigation_browsertest.cc b/weblayer/browser/navigation_browsertest.cc deleted file mode 100644 index d18f534..0000000 --- a/weblayer/browser/navigation_browsertest.cc +++ /dev/null
@@ -1,1249 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/functional/callback.h" -#include "base/functional/callback_helpers.h" -#include "base/memory/raw_ptr.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/single_thread_task_runner.h" -#include "base/test/bind.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/variations/net/variations_http_headers.h" -#include "components/variations/variations_ids_provider.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/url_loader_interceptor.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/controllable_http_response.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/embedded_test_server/http_response.h" -#include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/common/web_preferences/web_preferences.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/browser.h" -#include "weblayer/public/browser_observer.h" -#include "weblayer/public/navigation.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/navigation_observer.h" -#include "weblayer/public/new_tab_delegate.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/interstitial_utils.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -// NavigationObserver that allows registering a callback for various -// NavigationObserver functions. -class NavigationObserverImpl : public NavigationObserver { - public: - explicit NavigationObserverImpl(NavigationController* controller) - : controller_(controller) { - controller_->AddObserver(this); - } - ~NavigationObserverImpl() override { controller_->RemoveObserver(this); } - - using Callback = base::RepeatingCallback<void(Navigation*)>; - using PageLanguageDeterminedCallback = - base::RepeatingCallback<void(Page*, std::string)>; - - void SetStartedCallback(Callback callback) { - started_callback_ = std::move(callback); - } - - void SetRedirectedCallback(Callback callback) { - redirected_callback_ = std::move(callback); - } - - void SetFailedCallback(Callback callback) { - failed_callback_ = std::move(callback); - } - - void SetCompletedClosure(Callback callback) { - completed_callback_ = std::move(callback); - } - - void SetOnPageLanguageDeterminedCallback( - PageLanguageDeterminedCallback callback) { - on_page_language_determined_callback_ = std::move(callback); - } - - // NavigationObserver: - void NavigationStarted(Navigation* navigation) override { - if (started_callback_) - started_callback_.Run(navigation); - } - void NavigationRedirected(Navigation* navigation) override { - if (redirected_callback_) - redirected_callback_.Run(navigation); - } - void NavigationCompleted(Navigation* navigation) override { - if (completed_callback_) - completed_callback_.Run(navigation); - } - void NavigationFailed(Navigation* navigation) override { - // As |this| may be deleted when running the callback, the callback must be - // copied before running. To do otherwise results in use-after-free. - auto callback = failed_callback_; - if (callback) - callback.Run(navigation); - } - void OnPageLanguageDetermined(Page* page, - const std::string& language) override { - if (on_page_language_determined_callback_) - on_page_language_determined_callback_.Run(page, language); - } - - private: - raw_ptr<NavigationController> controller_; - Callback started_callback_; - Callback redirected_callback_; - Callback completed_callback_; - Callback failed_callback_; - PageLanguageDeterminedCallback on_page_language_determined_callback_; -}; - -} // namespace - -class NavigationBrowserTest : public WebLayerBrowserTest { - public: - NavigationController* GetNavigationController() { - return shell()->tab()->GetNavigationController(); - } - void SetUpOnMainThread() override { - host_resolver()->AddRule("*", "127.0.0.1"); - content::SetupCrossSiteRedirector(embedded_test_server()); - } -}; - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, NoError) { - EXPECT_TRUE(embedded_test_server()->Start()); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/simple_page.html")); - - observer.WaitForNavigation(); - EXPECT_TRUE(observer.completed()); - EXPECT_FALSE(observer.is_error_page()); - EXPECT_FALSE(observer.is_download()); - EXPECT_FALSE(observer.is_reload()); - EXPECT_FALSE(observer.was_stop_called()); - EXPECT_EQ(observer.load_error(), Navigation::kNoError); - EXPECT_EQ(observer.http_status_code(), 200); - EXPECT_EQ(observer.navigation_state(), NavigationState::kComplete); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - IsPageInitiatedTrueForWindowHistoryBack) { - EXPECT_TRUE(embedded_test_server()->Start()); - - std::unique_ptr<OneShotNavigationObserver> observer = - std::make_unique<OneShotNavigationObserver>(shell()); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("a.com", "/simple_page.html")); - observer->WaitForNavigation(); - ASSERT_TRUE(observer->completed()); - EXPECT_FALSE(observer->is_page_initiated()); - - observer = std::make_unique<OneShotNavigationObserver>(shell()); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("b.com", "/simple_page.html")); - observer->WaitForNavigation(); - ASSERT_TRUE(observer->completed()); - EXPECT_FALSE(observer->is_page_initiated()); - - observer = std::make_unique<OneShotNavigationObserver>(shell()); - shell()->tab()->ExecuteScript( - u"window.history.back();", false, - base::BindLambdaForTesting( - [&](base::Value value) { LOG(ERROR) << "executescript result"; })); - observer->WaitForNavigation(); - ASSERT_TRUE(observer->completed()); - EXPECT_TRUE(observer->is_page_initiated()); -} - -// Http client error when the server returns a non-empty response. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpClientError) { - EXPECT_TRUE(embedded_test_server()->Start()); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/non_empty404.html")); - - observer.WaitForNavigation(); - EXPECT_TRUE(observer.completed()); - EXPECT_FALSE(observer.is_error_page()); - EXPECT_EQ(observer.load_error(), Navigation::kHttpClientError); - EXPECT_EQ(observer.http_status_code(), 404); - EXPECT_EQ(observer.navigation_state(), NavigationState::kComplete); -} - -// Http client error when the server returns an empty response. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpClientErrorEmptyResponse) { - EXPECT_TRUE(embedded_test_server()->Start()); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/empty404.html")); - - observer.WaitForNavigation(); - EXPECT_FALSE(observer.completed()); - EXPECT_TRUE(observer.is_error_page()); - EXPECT_EQ(observer.load_error(), Navigation::kHttpClientError); - EXPECT_EQ(observer.http_status_code(), 404); - EXPECT_EQ(observer.navigation_state(), NavigationState::kFailed); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpServerError) { - EXPECT_TRUE(embedded_test_server()->Start()); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/echo?status=500")); - - observer.WaitForNavigation(); - EXPECT_TRUE(observer.completed()); - EXPECT_FALSE(observer.is_error_page()); - EXPECT_EQ(observer.load_error(), Navigation::kHttpServerError); - EXPECT_EQ(observer.http_status_code(), 500); - EXPECT_EQ(observer.navigation_state(), NavigationState::kComplete); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SSLError) { - net::EmbeddedTestServer https_server_mismatched( - net::EmbeddedTestServer::TYPE_HTTPS); - https_server_mismatched.SetSSLConfig( - net::EmbeddedTestServer::CERT_MISMATCHED_NAME); - https_server_mismatched.AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - - ASSERT_TRUE(https_server_mismatched.Start()); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate( - https_server_mismatched.GetURL("/simple_page.html")); - - observer.WaitForNavigation(); - EXPECT_FALSE(observer.completed()); - EXPECT_TRUE(observer.is_error_page()); - EXPECT_EQ(observer.load_error(), Navigation::kSSLError); - EXPECT_EQ(observer.navigation_state(), NavigationState::kFailed); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpConnectivityError) { - GURL url("http://doesntexist.com/foo"); - auto interceptor = content::URLLoaderInterceptor::SetupRequestFailForURL( - url, net::ERR_NAME_NOT_RESOLVED); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate(url); - - observer.WaitForNavigation(); - EXPECT_FALSE(observer.completed()); - EXPECT_TRUE(observer.is_error_page()); - EXPECT_EQ(observer.load_error(), Navigation::kConnectivityError); - EXPECT_EQ(observer.navigation_state(), NavigationState::kFailed); -} - -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -// https://crbug.com/1296643 -#define MAYBE_Download DISABLED_Download -#else -#define MAYBE_Download Download -#endif - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, MAYBE_Download) { - EXPECT_TRUE(embedded_test_server()->Start()); - GURL url(embedded_test_server()->GetURL("/content-disposition.html")); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate(url); - - observer.WaitForNavigation(); - EXPECT_FALSE(observer.completed()); - EXPECT_FALSE(observer.is_error_page()); - EXPECT_TRUE(observer.is_download()); - EXPECT_FALSE(observer.was_stop_called()); - EXPECT_EQ(observer.load_error(), Navigation::kOtherError); - EXPECT_EQ(observer.navigation_state(), NavigationState::kFailed); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, StopInOnStart) { - ASSERT_TRUE(embedded_test_server()->Start()); - base::RunLoop run_loop; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback(base::BindLambdaForTesting( - [&](Navigation*) { GetNavigationController()->Stop(); })); - observer.SetFailedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - ASSERT_TRUE(navigation->WasStopCalled()); - run_loop.Quit(); - })); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/simple_page.html")); - - run_loop.Run(); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, DestroyTabInNavigation) { - ASSERT_TRUE(embedded_test_server()->Start()); - Tab* new_tab = shell()->browser()->CreateTab(); - base::RunLoop run_loop; - std::unique_ptr<NavigationObserverImpl> observer = - std::make_unique<NavigationObserverImpl>( - new_tab->GetNavigationController()); - observer->SetFailedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - observer.reset(); - shell()->browser()->DestroyTab(new_tab); - // Destroying the tab posts a task to delete the WebContents, which must - // be run before the test shuts down lest it access deleted state. - base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, run_loop.QuitClosure()); - })); - new_tab->GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/simple_pageX.html")); - - run_loop.Run(); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, StopInOnRedirect) { - ASSERT_TRUE(embedded_test_server()->Start()); - base::RunLoop run_loop; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetRedirectedCallback(base::BindLambdaForTesting( - [&](Navigation*) { GetNavigationController()->Stop(); })); - observer.SetFailedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - ASSERT_TRUE(navigation->WasStopCalled()); - run_loop.Quit(); - })); - const GURL original_url = embedded_test_server()->GetURL("/simple_page.html"); - GetNavigationController()->Navigate(embedded_test_server()->GetURL( - "/server-redirect?" + original_url.spec())); - - run_loop.Run(); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - NavigateFromRendererInitiatedNavigation) { - ASSERT_TRUE(embedded_test_server()->Start()); - NavigationController* controller = shell()->tab()->GetNavigationController(); - const GURL final_url = embedded_test_server()->GetURL("/simple_page2.html"); - int failed_count = 0; - int completed_count = 0; - NavigationObserverImpl observer(controller); - base::RunLoop run_loop; - observer.SetFailedCallback( - base::BindLambdaForTesting([&](Navigation*) { failed_count++; })); - observer.SetCompletedClosure( - base::BindLambdaForTesting([&](Navigation* navigation) { - completed_count++; - if (navigation->GetURL().path() == "/simple_page2.html") - run_loop.Quit(); - })); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - if (navigation->GetURL().path() == "/simple_page.html") - controller->Navigate(final_url); - })); - controller->Navigate(embedded_test_server()->GetURL("/simple_page4.html")); - run_loop.Run(); - EXPECT_EQ(1, failed_count); - EXPECT_EQ(2, completed_count); - ASSERT_EQ(2, controller->GetNavigationListSize()); - EXPECT_EQ(final_url, controller->GetNavigationEntryDisplayURL(1)); -} - -class BrowserObserverImpl : public BrowserObserver { - public: - explicit BrowserObserverImpl(Browser* browser) : browser_(browser) { - browser->AddObserver(this); - } - - ~BrowserObserverImpl() override { browser_->RemoveObserver(this); } - - void SetNewTabCallback(base::RepeatingCallback<void(Tab*)> callback) { - new_tab_callback_ = callback; - } - - // BrowserObserver: - void OnTabAdded(Tab* tab) override { new_tab_callback_.Run(tab); } - - private: - base::RepeatingCallback<void(Tab*)> new_tab_callback_; - raw_ptr<Browser> browser_; -}; - -class NewTabDelegateImpl : public NewTabDelegate { - public: - // NewTabDelegate: - void OnNewTab(Tab* new_tab, NewTabType type) override {} -}; - -// Ensures calling Navigate() from within NavigationStarted() for a popup does -// not crash. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, NavigateFromNewWindow) { - ASSERT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page2.html"), shell()); - NewTabDelegate* old_new_tab_delegate = - static_cast<TabImpl*>(shell()->tab())->new_tab_delegate(); - NewTabDelegateImpl new_tab_delegate; - shell()->tab()->SetNewTabDelegate(&new_tab_delegate); - BrowserObserverImpl browser_observer(shell()->tab()->GetBrowser()); - std::unique_ptr<NavigationObserverImpl> popup_navigation_observer; - base::RunLoop run_loop; - Tab* popup_tab = nullptr; - auto popup_started_navigation = [&](Navigation* navigation) { - if (navigation->GetURL().path() == "/simple_page.html") { - popup_tab->GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/simple_page3.html")); - } else if (navigation->GetURL().path() == "/simple_page3.html") { - run_loop.Quit(); - } - }; - browser_observer.SetNewTabCallback(base::BindLambdaForTesting([&](Tab* tab) { - popup_tab = tab; - popup_navigation_observer = std::make_unique<NavigationObserverImpl>( - tab->GetNavigationController()); - popup_navigation_observer->SetStartedCallback( - base::BindLambdaForTesting(popup_started_navigation)); - })); - // 'noopener' is key to triggering the problematic case. - const std::string window_open = base::StringPrintf( - "window.open('%s', '', 'noopener')", - embedded_test_server()->GetURL("/simple_page.html").spec().c_str()); - ExecuteScriptWithUserGesture(shell()->tab(), window_open); - run_loop.Run(); - - // Restore the old delegate to make sure it is cleaned up on Android. - shell()->tab()->SetNewTabDelegate(old_new_tab_delegate); -} - -// Verifies calling Navigate() from NavigationRedirected() works. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, NavigateFromRedirect) { - net::test_server::ControllableHttpResponse response_1(embedded_test_server(), - "", true); - net::test_server::ControllableHttpResponse response_2(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - NavigationObserverImpl observer(GetNavigationController()); - bool got_redirect = false; - const GURL url_to_load_on_redirect = - embedded_test_server()->GetURL("/url_to_load_on_redirect.html"); - observer.SetRedirectedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - shell()->LoadURL(url_to_load_on_redirect); - got_redirect = true; - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/initial_url.html")); - response_1.WaitForRequest(); - response_1.Send( - "HTTP/1.1 302 Moved Temporarily\r\nLocation: /redirect_dest_url\r\n\r\n"); - response_1.Done(); - response_2.WaitForRequest(); - response_2.Done(); - EXPECT_EQ(url_to_load_on_redirect, response_2.http_request()->GetURL()); - EXPECT_TRUE(got_redirect); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeader) { - net::test_server::ControllableHttpResponse response_1(embedded_test_server(), - "", true); - net::test_server::ControllableHttpResponse response_2(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string header_name = "header"; - const std::string header_value = "value"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(header_name, header_value); - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response_1.WaitForRequest(); - - // Header should be present in initial request. - EXPECT_EQ(header_value, response_1.http_request()->headers.at(header_name)); - response_1.Send( - "HTTP/1.1 302 Moved Temporarily\r\nLocation: /new_doc\r\n\r\n"); - response_1.Done(); - - // Header should carry through to redirect. - response_2.WaitForRequest(); - EXPECT_EQ(header_value, response_2.http_request()->headers.at(header_name)); -} - -// Verifies setting the 'referer' via SetRequestHeader() works as expected. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeaderWithReferer) { - net::test_server::ControllableHttpResponse response(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string header_name = "Referer"; - const std::string header_value = "http://request.com"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(header_name, header_value); - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response.WaitForRequest(); - - // Verify 'referer' matches expected value. - EXPECT_EQ(GURL(header_value), - GURL(response.http_request()->headers.at(header_name))); -} - -// Like above but checks that referer isn't sent when it's https and the target -// url is http. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - SetRequestHeaderWithRefererDowngrade) { - net::test_server::ControllableHttpResponse response(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string header_name = "Referer"; - const std::string header_value = "https://request.com"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(header_name, header_value); - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response.WaitForRequest(); - - EXPECT_EQ(0u, response.http_request()->headers.count(header_name)); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeaderInRedirect) { - net::test_server::ControllableHttpResponse response_1(embedded_test_server(), - "", true); - net::test_server::ControllableHttpResponse response_2(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string header_name = "header"; - const std::string header_value = "value"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetRedirectedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(header_name, header_value); - })); - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response_1.WaitForRequest(); - - // Header should not be present in initial request. - EXPECT_FALSE(base::Contains(response_1.http_request()->headers, header_name)); - - response_1.Send( - "HTTP/1.1 302 Moved Temporarily\r\nLocation: /new_doc\r\n\r\n"); - response_1.Done(); - - response_2.WaitForRequest(); - - // Header should be in redirect. - ASSERT_TRUE(base::Contains(response_2.http_request()->headers, header_name)); - EXPECT_EQ(header_value, response_2.http_request()->headers.at(header_name)); -} - -class NavigationBrowserTestUserAgentOverrideSubstring - : public NavigationBrowserTest { - public: - void SetUp() override { - scoped_feature_list_.InitWithFeatures({blink::features::kUACHOverrideBlank}, - {}); - NavigationBrowserTest::SetUp(); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTestUserAgentOverrideSubstring, - PageSeesUserAgentString) { - net::test_server::EmbeddedTestServer https_server( - net::test_server::EmbeddedTestServer::TYPE_HTTPS); - https_server.AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - - ASSERT_TRUE(https_server.Start()); - - const std::string custom_ua = "custom"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua); - })); - OneShotNavigationObserver navigation_observer(shell()); - shell()->LoadURL(https_server.GetURL("/simple_page.html")); - navigation_observer.WaitForNavigation(); - - base::RunLoop run_loop; - shell()->tab()->ExecuteScript( - u"navigator.userAgent;", false, - base::BindLambdaForTesting([&](base::Value value) { - ASSERT_TRUE(value.is_string()); - EXPECT_EQ(custom_ua, value.GetString()); - run_loop.Quit(); - })); - run_loop.Run(); - - // Ensure that userAgentData is blank when custom user agent is set. - base::RunLoop run_loop2; - shell()->tab()->ExecuteScript( - u"navigator.userAgentData.platform;", false, - base::BindLambdaForTesting([&](base::Value value) { - ASSERT_TRUE(value.is_string()); - EXPECT_EQ("", value.GetString()); - run_loop2.Quit(); - })); - run_loop2.Run(); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, Reload) { - ASSERT_TRUE(embedded_test_server()->Start()); - - OneShotNavigationObserver observer(shell()); - GetNavigationController()->Navigate( - embedded_test_server()->GetURL("/simple_page.html")); - observer.WaitForNavigation(); - - OneShotNavigationObserver observer2(shell()); - shell()->tab()->ExecuteScript(u"location.reload();", false, - base::DoNothing()); - observer2.WaitForNavigation(); - EXPECT_TRUE(observer2.completed()); - EXPECT_TRUE(observer2.is_reload()); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTestUserAgentOverrideSubstring, - SetUserAgentString) { - std::unique_ptr<net::test_server::EmbeddedTestServer> https_server = - std::make_unique<net::test_server::EmbeddedTestServer>( - net::test_server::EmbeddedTestServer::TYPE_HTTPS); - https_server->AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - - net::test_server::ControllableHttpResponse response_1(https_server.get(), "", - true); - net::test_server::ControllableHttpResponse response_2(https_server.get(), "", - true); - ASSERT_TRUE(https_server->Start()); - - const std::string custom_ua = "CUSTOM"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua); - })); - - shell()->LoadURL(https_server->GetURL("/simple_page.html")); - response_1.WaitForRequest(); - - // |custom_ua| should be present in initial request. - ASSERT_TRUE(base::Contains(response_1.http_request()->headers, - net::HttpRequestHeaders::kUserAgent)); - const std::string new_header = response_1.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent); - EXPECT_EQ(custom_ua, new_header); - - ASSERT_TRUE(base::Contains(response_1.http_request()->headers, "sec-ch-ua")); - const std::string new_ch_header = - response_1.http_request()->headers.at("Sec-CH-UA"); - EXPECT_EQ("", new_ch_header); - content::FetchHistogramsFromChildProcesses(); - - // Header should carry through to redirect. - response_1.Send( - "HTTP/1.1 302 Moved Temporarily\r\nLocation: /new_doc\r\n\r\n"); - response_1.Done(); - response_2.WaitForRequest(); - EXPECT_EQ(custom_ua, response_2.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent)); - EXPECT_EQ("", response_2.http_request()->headers.at("Sec-CH-UA")); -} - -#if BUILDFLAG(IS_ANDROID) -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - SetUserAgentStringDoesntChangeViewportMetaTag) { - ASSERT_TRUE(embedded_test_server()->Start()); - - NavigationObserverImpl observer(GetNavigationController()); - const std::string custom_ua = "custom-ua"; - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua); - })); - - OneShotNavigationObserver load_observer(shell()); - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - load_observer.WaitForNavigation(); - - // Just because we set a custom user agent doesn't mean we should ignore - // viewport meta tags. - auto* tab = static_cast<TabImpl*>(shell()->tab()); - auto* web_contents = tab->web_contents(); - ASSERT_TRUE(web_contents->GetOrCreateWebPreferences().viewport_meta_enabled); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - RequestDesktopSiteChangesViewportMetaTag) { - ASSERT_TRUE(embedded_test_server()->Start()); - - OneShotNavigationObserver load_observer(shell()); - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - load_observer.WaitForNavigation(); - - auto* tab = static_cast<TabImpl*>(shell()->tab()); - - OneShotNavigationObserver load_observer2(shell()); - tab->SetDesktopUserAgentEnabled(nullptr, true); - load_observer2.WaitForNavigation(); - - auto* web_contents = tab->web_contents(); - ASSERT_FALSE(web_contents->GetOrCreateWebPreferences().viewport_meta_enabled); -} - -#endif - -// Verifies changing the user agent twice in a row works. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, UserAgentDoesntCarryThrough1) { - net::test_server::ControllableHttpResponse response_1(embedded_test_server(), - "", true); - net::test_server::ControllableHttpResponse response_2(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string custom_ua1 = "my ua1"; - const std::string custom_ua2 = "my ua2"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua1); - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response_1.WaitForRequest(); - EXPECT_EQ(custom_ua1, response_1.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent)); - - // Before the request is done, start another navigation. - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua2); - })); - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page2.html")); - response_2.WaitForRequest(); - EXPECT_EQ(custom_ua2, response_2.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent)); -} - -// Verifies changing the user agent doesn't bleed through to next navigation. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, UserAgentDoesntCarryThrough2) { - net::test_server::ControllableHttpResponse response_1(embedded_test_server(), - "", true); - net::test_server::ControllableHttpResponse response_2(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string custom_ua = "my ua1"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua); - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response_1.WaitForRequest(); - EXPECT_EQ(custom_ua, response_1.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent)); - - // Before the request is done, start another navigation. - observer.SetStartedCallback(base::DoNothing()); - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page2.html")); - response_2.WaitForRequest(); - EXPECT_NE(custom_ua, response_2.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent)); - EXPECT_FALSE(response_2.http_request() - ->headers.at(net::HttpRequestHeaders::kUserAgent) - .empty()); -} - -// Verifies changing the user-agent applies to child resources, such as an -// <img>. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - UserAgentAppliesToChildResources) { - net::test_server::ControllableHttpResponse response_1(embedded_test_server(), - "", true); - net::test_server::ControllableHttpResponse response_2(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string custom_ua = "custom-ua"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua); - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/foo.html")); - response_1.WaitForRequest(); - response_1.Send(net::HTTP_OK, "text/html", "<img src=\"image.png\">"); - response_1.Done(); - EXPECT_EQ(custom_ua, response_1.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent)); - observer.SetStartedCallback(base::DoNothing()); - - response_2.WaitForRequest(); - EXPECT_EQ(custom_ua, response_2.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent)); -} - -// https://crbug.com/1446050 -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - DISABLED_SetUserAgentStringRendererInitiated) { - net::test_server::ControllableHttpResponse response_1(embedded_test_server(), - "", true); - net::test_server::ControllableHttpResponse response_2(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - OneShotNavigationObserver load_observer(shell()); - NavigationObserverImpl observer(GetNavigationController()); - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response_1.WaitForRequest(); - response_1.Send(net::HTTP_OK, "text/html", "<html>"); - response_1.Done(); - load_observer.WaitForNavigation(); - - const std::string custom_ua = "custom-ua"; - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetUserAgentString(custom_ua); - })); - const GURL target_url = embedded_test_server()->GetURL("/foo.html"); - shell()->tab()->ExecuteScript( - u"location.href='" + base::ASCIIToUTF16(target_url.spec()) + u"';", false, - base::DoNothing()); - response_2.WaitForRequest(); - // |custom_ua| should be present in the renderer initiated navigation. - ASSERT_TRUE(base::Contains(response_2.http_request()->headers, - net::HttpRequestHeaders::kUserAgent)); - const std::string new_ua = response_2.http_request()->headers.at( - net::HttpRequestHeaders::kUserAgent); - EXPECT_EQ(custom_ua, new_ua); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, AutoPlayDefault) { - ASSERT_TRUE(embedded_test_server()->Start()); - - GURL url(embedded_test_server()->GetURL("/autoplay.html")); - auto* tab = static_cast<TabImpl*>(shell()->tab()); - NavigateAndWaitForCompletion(url, tab); - - auto* web_contents = tab->web_contents(); - // There's no notification to watch that would signal video wasn't autoplayed, - // so instead check once through javascript. - ASSERT_EQ(false, content::EvalJs(web_contents, - "!document.getElementById('vid').paused")); -} - -namespace { - -class WaitForMediaPlaying : public content::WebContentsObserver { - public: - explicit WaitForMediaPlaying(content::WebContents* web_contents) - : WebContentsObserver(web_contents) {} - - WaitForMediaPlaying(const WaitForMediaPlaying&) = delete; - WaitForMediaPlaying& operator=(const WaitForMediaPlaying&) = delete; - - // WebContentsObserver override. - void MediaStartedPlaying(const MediaPlayerInfo& info, - const content::MediaPlayerId&) final { - run_loop_.Quit(); - CHECK(info.has_audio); - CHECK(info.has_video); - } - - void Wait() { run_loop_.Run(); } - - private: - base::RunLoop run_loop_; -}; - -} // namespace - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, AutoPlayEnabled) { - ASSERT_TRUE(embedded_test_server()->Start()); - - GURL url(embedded_test_server()->GetURL("/autoplay.html")); - NavigationController::NavigateParams params; - params.enable_auto_play = true; - GetNavigationController()->Navigate(url, params); - - auto* tab = static_cast<TabImpl*>(shell()->tab()); - WaitForMediaPlaying wait_for_media(tab->web_contents()); - wait_for_media.Wait(); -} - -class NavigationBrowserTest2 : public NavigationBrowserTest { - public: - void SetUp() override { - // HTTPS server only serves a valid cert for localhost, so this is needed to - // load pages from "www.google.com" without an interstitial. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - "ignore-certificate-errors"); - - NavigationBrowserTest::SetUp(); - } - void SetUpOnMainThread() override { - NavigationBrowserTest::SetUpOnMainThread(); - https_server_ = std::make_unique<net::EmbeddedTestServer>( - net::EmbeddedTestServer::TYPE_HTTPS); - // The test makes requests to google.com which we want to redirect to the - // test server. - host_resolver()->AddRule("*", "127.0.0.1"); - - // Forces variations code to set the header. - auto* variations_provider = - variations::VariationsIdsProvider::GetInstance(); - variations_provider->ForceVariationIds({"12", "456", "t789"}, ""); - } - - net::EmbeddedTestServer* https_server() { return https_server_.get(); } - - private: - std::unique_ptr<net::EmbeddedTestServer> https_server_; -}; - -// This test verifies the embedder can replace the X-Client-Data header that -// is also set by //components/variations. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest2, ReplaceXClientDataHeader) { - std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); - std::string last_header_value; - auto main_task_runner = base::SequencedTaskRunner::GetCurrentDefault(); - https_server()->RegisterRequestHandler(base::BindLambdaForTesting( - [&, main_task_runner](const net::test_server::HttpRequest& request) - -> std::unique_ptr<net::test_server::HttpResponse> { - auto iter = request.headers.find(variations::kClientDataHeader); - if (iter != request.headers.end()) { - main_task_runner->PostTask( - FROM_HERE, base::BindOnce(base::BindLambdaForTesting( - [&](const std::string& value) { - last_header_value = value; - run_loop->Quit(); - }), - iter->second)); - } - return std::make_unique<net::test_server::BasicHttpResponse>(); - })); - ASSERT_TRUE(https_server()->Start()); - - // Verify the header is set by default. - const GURL url = https_server()->GetURL("www.google.com", "/"); - shell()->LoadURL(url); - run_loop->Run(); - EXPECT_FALSE(last_header_value.empty()); - - // Repeat, but clobber the header when navigating. - const std::string header_value = "value"; - EXPECT_NE(last_header_value, header_value); - last_header_value.clear(); - run_loop = std::make_unique<base::RunLoop>(); - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(variations::kClientDataHeader, - header_value); - })); - - shell()->LoadURL(https_server()->GetURL("www.google.com", "/foo")); - run_loop->Run(); - EXPECT_EQ(header_value, last_header_value); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest2, - SetXClientDataHeaderCarriesThroughToRedirect) { - std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); - std::string last_header_value; - bool should_redirect = true; - auto main_task_runner = base::SequencedTaskRunner::GetCurrentDefault(); - https_server()->RegisterRequestHandler(base::BindLambdaForTesting( - [&, main_task_runner](const net::test_server::HttpRequest& request) - -> std::unique_ptr<net::test_server::HttpResponse> { - auto response = std::make_unique<net::test_server::BasicHttpResponse>(); - if (should_redirect) { - should_redirect = false; - response->set_code(net::HTTP_MOVED_PERMANENTLY); - response->AddCustomHeader( - "Location", - https_server()->GetURL("www.google.com", "/redirect").spec()); - } else { - auto iter = request.headers.find(variations::kClientDataHeader); - main_task_runner->PostTask( - FROM_HERE, base::BindOnce(base::BindLambdaForTesting( - [&](const std::string& value) { - last_header_value = value; - run_loop->Quit(); - }), - iter->second)); - } - return response; - })); - ASSERT_TRUE(https_server()->Start()); - - const std::string header_value = "value"; - run_loop = std::make_unique<base::RunLoop>(); - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(variations::kClientDataHeader, - header_value); - })); - - shell()->LoadURL(https_server()->GetURL("www.google.com", "/foo")); - run_loop->Run(); - EXPECT_EQ(header_value, last_header_value); -} - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest2, SetXClientDataHeaderInRedirect) { - std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); - std::string last_header_value; - bool should_redirect = true; - auto main_task_runner = base::SequencedTaskRunner::GetCurrentDefault(); - https_server()->RegisterRequestHandler(base::BindLambdaForTesting( - [&, main_task_runner](const net::test_server::HttpRequest& request) - -> std::unique_ptr<net::test_server::HttpResponse> { - auto response = std::make_unique<net::test_server::BasicHttpResponse>(); - if (should_redirect) { - should_redirect = false; - response->set_code(net::HTTP_MOVED_PERMANENTLY); - response->AddCustomHeader( - "Location", - https_server()->GetURL("www.google.com", "/redirect").spec()); - } else { - auto iter = request.headers.find(variations::kClientDataHeader); - main_task_runner->PostTask( - FROM_HERE, base::BindOnce(base::BindLambdaForTesting( - [&](const std::string& value) { - last_header_value = value; - run_loop->Quit(); - }), - iter->second)); - } - return response; - })); - ASSERT_TRUE(https_server()->Start()); - - const std::string header_value = "value"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetRedirectedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(variations::kClientDataHeader, - header_value); - })); - - shell()->LoadURL(https_server()->GetURL("www.google.com", "/foo")); - run_loop->Run(); - EXPECT_EQ(header_value, last_header_value); -} - -#if BUILDFLAG(IS_ANDROID) -// Verifies setting the 'referer' to an android-app url works. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, AndroidAppReferer) { - net::test_server::ControllableHttpResponse response(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - const std::string header_name = "Referer"; - const std::string header_value = "android-app://google.com/"; - NavigationObserverImpl observer(GetNavigationController()); - observer.SetStartedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - navigation->SetRequestHeader(header_name, header_value); - })); - - shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html")); - response.WaitForRequest(); - - // Verify 'referer' matches expected value. - EXPECT_EQ(header_value, response.http_request()->headers.at(header_name)); -} -#endif - -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - OnPageLanguageDeterminedCallback) { - ASSERT_TRUE(embedded_test_server()->Start()); - - NavigationController* controller = shell()->tab()->GetNavigationController(); - NavigationObserverImpl observer(controller); - - Page* committed_page = nullptr; - Page* page_with_language_determined = nullptr; - std::string determined_language = ""; - - base::RunLoop navigation_run_loop1; - base::RunLoop page_language_determination_run_loop1; - - base::RunLoop* navigation_run_loop = &navigation_run_loop1; - base::RunLoop* page_language_determination_run_loop = - &page_language_determination_run_loop1; - - observer.SetCompletedClosure( - base::BindLambdaForTesting([&](Navigation* navigation) { - committed_page = navigation->GetPage(); - navigation_run_loop->Quit(); - })); - observer.SetOnPageLanguageDeterminedCallback( - base::BindLambdaForTesting([&](Page* page, std::string language) { - page_with_language_determined = page; - determined_language = language; - page_language_determination_run_loop->Quit(); - })); - - // Navigate to a page in English. - controller->Navigate(embedded_test_server()->GetURL("/english_page.html")); - navigation_run_loop1.Run(); - EXPECT_TRUE(committed_page); - - // Verify that the language determined event fires as expected. - page_language_determination_run_loop1.Run(); - EXPECT_EQ(committed_page, page_with_language_determined); - EXPECT_EQ("en", determined_language); - - // Now navigate to a page in French. - committed_page = nullptr; - page_with_language_determined = nullptr; - base::RunLoop navigation_run_loop2; - base::RunLoop page_language_determination_run_loop2; - - navigation_run_loop = &navigation_run_loop2; - page_language_determination_run_loop = &page_language_determination_run_loop2; - - controller->Navigate(embedded_test_server()->GetURL("/french_page.html")); - navigation_run_loop2.Run(); - EXPECT_TRUE(committed_page); - - // Verify that the language determined event fires as expected. - page_language_determination_run_loop2.Run(); - EXPECT_EQ(committed_page, page_with_language_determined); - EXPECT_EQ("fr", determined_language); -} - -// Verifies that closing a tab when a navigation is waiting for a response -// causes the navigation to be marked as failed to the embedder. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - CloseTabWithNavigationWaitingForResponse) { - net::test_server::ControllableHttpResponse response(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - GURL url = embedded_test_server()->GetURL("/initial_url.html"); - base::RunLoop run_loop; - Navigation* ongoing_navigation = nullptr; - - auto observer = - std::make_unique<NavigationObserverImpl>(GetNavigationController()); - observer->SetStartedCallback(base::BindLambdaForTesting( - [&](Navigation* navigation) { ongoing_navigation = navigation; })); - observer->SetFailedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - EXPECT_EQ(url, navigation->GetURL()); - EXPECT_EQ(NavigationState::kFailed, navigation->GetState()); - - run_loop.Quit(); - - // The NavigationControllerImpl that |observer| is observing will - // be destroyed before control returns to the test, so destroy - // |observer| now to avoid UaF. - observer.reset(); - })); - - shell()->LoadURL(url); - response.WaitForRequest(); - - EXPECT_EQ(NavigationState::kWaitingResponse, ongoing_navigation->GetState()); - shell()->browser()->DestroyTab(shell()->tab()); - - run_loop.Run(); -} - -// Verifies that closing a tab when a navigation is in the middle of receiving a -// response causes the navigation to be marked as failed to the embedder. -IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, - CloseTabWithNavigationReceivingBytes) { - net::test_server::ControllableHttpResponse response(embedded_test_server(), - "", true); - ASSERT_TRUE(embedded_test_server()->Start()); - - GURL url = embedded_test_server()->GetURL("/initial_url.html"); - base::RunLoop run_loop; - Navigation* ongoing_navigation = nullptr; - - auto observer = - std::make_unique<NavigationObserverImpl>(GetNavigationController()); - observer->SetStartedCallback(base::BindLambdaForTesting( - [&](Navigation* navigation) { ongoing_navigation = navigation; })); - observer->SetFailedCallback( - base::BindLambdaForTesting([&](Navigation* navigation) { - EXPECT_EQ(url, navigation->GetURL()); - EXPECT_EQ(NavigationState::kFailed, navigation->GetState()); - - run_loop.Quit(); - - // The NavigationControllerImpl that |observer| is observing will - // be destroyed before control returns to the test, so destroy - // |observer| now to avoid UaF. - observer.reset(); - })); - - auto* tab = static_cast<TabImpl*>(shell()->tab()); - auto wait_for_response_start = - std::make_unique<content::TestNavigationManager>(tab->web_contents(), - url); - shell()->LoadURL(url); - // Wait until request is ready to start. - EXPECT_TRUE(wait_for_response_start->WaitForRequestStart()); - // Start the request. - wait_for_response_start->ResumeNavigation(); - // Wait for the request to arrive to ControllableHttpResponse. - response.WaitForRequest(); - - response.Send(net::HTTP_OK, "text/html", "<html>"); - - ASSERT_TRUE(wait_for_response_start->WaitForResponse()); - - EXPECT_EQ(NavigationState::kReceivingBytes, ongoing_navigation->GetState()); - - // Destroy |wait_for_response_start| before we indirectly destroy the - // WebContents it's observing. - wait_for_response_start.reset(); - - shell()->browser()->DestroyTab(tab); - - run_loop.Run(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/navigation_controller_impl.cc b/weblayer/browser/navigation_controller_impl.cc deleted file mode 100644 index 625a742..0000000 --- a/weblayer/browser/navigation_controller_impl.cc +++ /dev/null
@@ -1,785 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/navigation_controller_impl.h" - -#include <utility> - -#include "base/auto_reset.h" -#include "base/containers/contains.h" -#include "base/memory/raw_ptr.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/sequenced_task_runner.h" -#include "build/build_config.h" -#include "components/content_relationship_verification/response_header_verifier.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/navigation_throttle.h" -#include "content/public/browser/web_contents.h" -#include "third_party/blink/public/mojom/navigation/was_activated_option.mojom-shared.h" -#include "ui/base/page_transition_types.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/navigation_entry_data.h" -#include "weblayer/browser/navigation_ui_data_impl.h" -#include "weblayer/browser/page_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/navigation_observer.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/jni_string.h" -#include "base/trace_event/trace_event.h" -#include "components/embedder_support/android/util/web_resource_response.h" -#include "weblayer/browser/java/jni/NavigationControllerImpl_jni.h" -#endif - -#if BUILDFLAG(IS_ANDROID) -using base::android::AttachCurrentThread; -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; -#endif - -namespace weblayer { - -class NavigationControllerImpl::DelayDeletionHelper { - public: - explicit DelayDeletionHelper(NavigationControllerImpl* controller) - : controller_(controller->weak_ptr_factory_.GetWeakPtr()) { - // This should never be called reentrantly. - DCHECK(!controller->should_delay_web_contents_deletion_); - controller->should_delay_web_contents_deletion_ = true; - } - - DelayDeletionHelper(const DelayDeletionHelper&) = delete; - DelayDeletionHelper& operator=(const DelayDeletionHelper&) = delete; - - ~DelayDeletionHelper() { - if (controller_) - controller_->should_delay_web_contents_deletion_ = false; - } - - bool WasControllerDeleted() { return controller_.get() == nullptr; } - - private: - base::WeakPtr<NavigationControllerImpl> controller_; -}; - -// NavigationThrottle implementation responsible for delaying certain -// operations and performing them when safe. This is necessary as content -// does allow certain operations to be called at certain times. For example, -// content does not allow calling WebContents::Stop() from -// WebContentsObserver::DidStartNavigation() (to do so crashes). To work around -// this NavigationControllerImpl detects these scenarios and delays processing -// until safe. -// -// Most of the support for these scenarios is handled by a custom -// NavigationThrottle. To make things interesting, the NavigationThrottle is -// created after some of the scenarios this code wants to handle. As such, -// NavigationImpl does some amount of caching until the NavigationThrottle is -// created. -class NavigationControllerImpl::NavigationThrottleImpl - : public content::NavigationThrottle { - public: - NavigationThrottleImpl(NavigationControllerImpl* controller, - content::NavigationHandle* handle) - : NavigationThrottle(handle), controller_(controller) {} - NavigationThrottleImpl(const NavigationThrottleImpl&) = delete; - NavigationThrottleImpl& operator=(const NavigationThrottleImpl&) = delete; - ~NavigationThrottleImpl() override = default; - - void ScheduleCancel() { should_cancel_ = true; } - void ScheduleBlock() { should_block_ = true; } - - // content::NavigationThrottle: - ThrottleCheckResult WillStartRequest() override { - if (should_cancel_) { - return CANCEL; - } - - if (should_block_) { - return BLOCK_REQUEST; - } - - return PROCEED; - } - - ThrottleCheckResult WillRedirectRequest() override { - controller_->WillRedirectRequest(this, navigation_handle()); - if (should_cancel_) { - return CANCEL; - } - - if (should_block_) { - return BLOCK_REQUEST; - } - - return PROCEED; - } - - const char* GetNameForLogging() override { - return "WebLayerNavigationControllerThrottle"; - } - - private: - raw_ptr<NavigationControllerImpl> controller_; - bool should_cancel_ = false; - bool should_block_ = false; -}; - -NavigationControllerImpl::NavigationControllerImpl(TabImpl* tab) - : WebContentsObserver(tab->web_contents()), tab_(tab) {} - -NavigationControllerImpl::~NavigationControllerImpl() = default; - -std::unique_ptr<content::NavigationThrottle> -NavigationControllerImpl::CreateNavigationThrottle( - content::NavigationHandle* handle) { - if (!handle->IsInMainFrame()) - return nullptr; - - auto throttle = std::make_unique<NavigationThrottleImpl>(this, handle); - DCHECK(navigation_map_.find(handle) != navigation_map_.end()); - auto* navigation = navigation_map_[handle].get(); - if (navigation->should_stop_when_throttle_created()) - throttle->ScheduleCancel(); - if (navigation->should_block_when_throttle_created()) { - throttle->ScheduleBlock(); - } - return throttle; -} - -NavigationImpl* NavigationControllerImpl::GetNavigationImplFromHandle( - content::NavigationHandle* handle) { - auto iter = navigation_map_.find(handle); - return iter == navigation_map_.end() ? nullptr : iter->second.get(); -} - -NavigationImpl* NavigationControllerImpl::GetNavigationImplFromId( - int64_t navigation_id) { - for (const auto& iter : navigation_map_) { - if (iter.first->GetNavigationId() == navigation_id) - return iter.second.get(); - } - - return nullptr; -} - -void NavigationControllerImpl::OnFirstContentfulPaint( - const base::TimeTicks& navigation_start, - const base::TimeDelta& first_contentful_paint) { -#if BUILDFLAG(IS_ANDROID) - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_onFirstContentfulPaint2"); - int64_t first_contentful_paint_ms = first_contentful_paint.InMilliseconds(); - Java_NavigationControllerImpl_onFirstContentfulPaint2( - AttachCurrentThread(), java_controller_, - navigation_start.ToUptimeMillis(), first_contentful_paint_ms); -#endif - - for (auto& observer : observers_) - observer.OnFirstContentfulPaint(navigation_start, first_contentful_paint); -} - -void NavigationControllerImpl::OnLargestContentfulPaint( - const base::TimeTicks& navigation_start, - const base::TimeDelta& largest_contentful_paint) { -#if BUILDFLAG(IS_ANDROID) - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_onLargestContentfulPaint2"); - int64_t largest_contentful_paint_ms = - largest_contentful_paint.InMilliseconds(); - Java_NavigationControllerImpl_onLargestContentfulPaint( - AttachCurrentThread(), java_controller_, - navigation_start.ToUptimeMillis(), largest_contentful_paint_ms); -#endif - - for (auto& observer : observers_) - observer.OnLargestContentfulPaint(navigation_start, - largest_contentful_paint); -} - -void NavigationControllerImpl::OnPageDestroyed(Page* page) { - for (auto& observer : observers_) - observer.OnPageDestroyed(page); -} - -void NavigationControllerImpl::OnPageLanguageDetermined( - Page* page, - const std::string& language) { -#if BUILDFLAG(IS_ANDROID) - JNIEnv* env = AttachCurrentThread(); - Java_NavigationControllerImpl_onPageLanguageDetermined( - env, java_controller_, static_cast<PageImpl*>(page)->java_page(), - base::android::ConvertUTF8ToJavaString(env, language)); -#endif - - for (auto& observer : observers_) - observer.OnPageLanguageDetermined(page, language); -} - -#if BUILDFLAG(IS_ANDROID) -void NavigationControllerImpl::SetNavigationControllerImpl( - JNIEnv* env, - const JavaParamRef<jobject>& java_controller) { - java_controller_ = java_controller; -} - -void NavigationControllerImpl::Navigate( - JNIEnv* env, - const JavaParamRef<jstring>& url, - jboolean should_replace_current_entry, - jboolean disable_intent_processing, - jboolean allow_intent_launches_in_background, - jboolean disable_network_error_auto_reload, - jboolean enable_auto_play, - const base::android::JavaParamRef<jobject>& response) { - auto params = std::make_unique<content::NavigationController::LoadURLParams>( - GURL(base::android::ConvertJavaStringToUTF8(env, url))); - params->should_replace_current_entry = should_replace_current_entry; - // On android, the transition type largely dictates whether intent processing - // happens. PAGE_TRANSITION_TYPED does not process intents, where as - // PAGE_TRANSITION_LINK will (with the caveat that even links may not trigger - // intent processing under some circumstances). - params->transition_type = disable_intent_processing - ? ui::PAGE_TRANSITION_TYPED - : ui::PAGE_TRANSITION_LINK; - auto data = std::make_unique<NavigationUIDataImpl>(); - - if (disable_network_error_auto_reload) - data->set_disable_network_error_auto_reload(true); - - data->set_allow_intent_launches_in_background( - allow_intent_launches_in_background); - - if (!response.is_null()) { - data->SetResponse( - std::make_unique<embedder_support::WebResourceResponse>(response)); - } - - params->navigation_ui_data = std::move(data); - - if (enable_auto_play) - params->was_activated = blink::mojom::WasActivatedOption::kYes; - - DoNavigate(std::move(params)); -} - -ScopedJavaLocalRef<jstring> -NavigationControllerImpl::GetNavigationEntryDisplayUri(JNIEnv* env, int index) { - return ScopedJavaLocalRef<jstring>(base::android::ConvertUTF8ToJavaString( - env, GetNavigationEntryDisplayURL(index).spec())); -} - -ScopedJavaLocalRef<jstring> NavigationControllerImpl::GetNavigationEntryTitle( - JNIEnv* env, - int index) { - return ScopedJavaLocalRef<jstring>(base::android::ConvertUTF8ToJavaString( - env, GetNavigationEntryTitle(index))); -} - -bool NavigationControllerImpl::IsNavigationEntrySkippable(JNIEnv* env, - int index) { - return IsNavigationEntrySkippable(index); -} - -base::android::ScopedJavaGlobalRef<jobject> -NavigationControllerImpl::GetNavigationImplFromId(JNIEnv* env, int64_t id) { - auto* navigation_impl = GetNavigationImplFromId(id); - return navigation_impl ? navigation_impl->java_navigation() : nullptr; -} - -#endif - -void NavigationControllerImpl::WillRedirectRequest( - NavigationThrottleImpl* throttle, - content::NavigationHandle* navigation_handle) { - DCHECK(navigation_handle->IsInMainFrame()); - DCHECK(navigation_map_.find(navigation_handle) != navigation_map_.end()); - auto* navigation = navigation_map_[navigation_handle].get(); - navigation->set_safe_to_set_request_headers(true); - DCHECK(!active_throttle_); - base::AutoReset<NavigationThrottleImpl*> auto_reset(&active_throttle_, - throttle); -#if BUILDFLAG(IS_ANDROID) - if (java_controller_) { - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_navigationRedirected"); - Java_NavigationControllerImpl_navigationRedirected( - AttachCurrentThread(), java_controller_, navigation->java_navigation()); - } -#endif - for (auto& observer : observers_) - observer.NavigationRedirected(navigation); - navigation->set_safe_to_set_request_headers(false); -} - -void NavigationControllerImpl::AddObserver(NavigationObserver* observer) { - observers_.AddObserver(observer); -} - -void NavigationControllerImpl::RemoveObserver(NavigationObserver* observer) { - observers_.RemoveObserver(observer); -} - -void NavigationControllerImpl::Navigate(const GURL& url) { - DoNavigate( - std::make_unique<content::NavigationController::LoadURLParams>(url)); -} - -void NavigationControllerImpl::Navigate( - const GURL& url, - const NavigationController::NavigateParams& params) { - auto load_params = - std::make_unique<content::NavigationController::LoadURLParams>(url); - load_params->should_replace_current_entry = - params.should_replace_current_entry; - if (params.enable_auto_play) - load_params->was_activated = blink::mojom::WasActivatedOption::kYes; - - DoNavigate(std::move(load_params)); -} - -void NavigationControllerImpl::GoBack() { - web_contents()->GetController().GoBack(); -} - -void NavigationControllerImpl::GoForward() { - web_contents()->GetController().GoForward(); -} - -bool NavigationControllerImpl::CanGoBack() { - return web_contents()->GetController().CanGoBack(); -} - -bool NavigationControllerImpl::CanGoForward() { - return web_contents()->GetController().CanGoForward(); -} - -void NavigationControllerImpl::GoToIndex(int index) { - web_contents()->GetController().GoToIndex(index); -} - -void NavigationControllerImpl::Reload() { - web_contents()->GetController().Reload(content::ReloadType::NORMAL, true); -} - -void NavigationControllerImpl::Stop() { - CancelDelayedLoad(); - - NavigationImpl* navigation = nullptr; - if (navigation_starting_) { - navigation_starting_->set_should_stop_when_throttle_created(); - navigation = navigation_starting_; - } else if (active_throttle_) { - active_throttle_->ScheduleCancel(); - DCHECK(navigation_map_.find(active_throttle_->navigation_handle()) != - navigation_map_.end()); - navigation = navigation_map_[active_throttle_->navigation_handle()].get(); - } else { - web_contents()->Stop(); - } - - if (navigation) - navigation->set_was_stopped(); -} - -int NavigationControllerImpl::GetNavigationListSize() { - if (web_contents() - ->GetController() - .GetLastCommittedEntry() - ->IsInitialEntry()) { - // If we're currently on the initial NavigationEntry, no navigation has - // committed, so the initial NavigationEntry should not be part of the - // "Navigation List", and we should return 0 as the navigation list size. - // This also preserves the old behavior where we used to not have the - // initial NavigationEntry. - return 0; - } - - return web_contents()->GetController().GetEntryCount(); -} - -int NavigationControllerImpl::GetNavigationListCurrentIndex() { - if (web_contents() - ->GetController() - .GetLastCommittedEntry() - ->IsInitialEntry()) { - // If we're currently on the initial NavigationEntry, no navigation has - // committed, so the initial NavigationEntry should not be part of the - // "Navigation List", and we should return -1 as the current index. This - // also preserves the old behavior where we used to not have the initial - // NavigationEntry. - return -1; - } - - return web_contents()->GetController().GetCurrentEntryIndex(); -} - -GURL NavigationControllerImpl::GetNavigationEntryDisplayURL(int index) { - auto* entry = web_contents()->GetController().GetEntryAtIndex(index); - // This function should never be called when GetNavigationListSize() is 0 - // because `index` should be between 0 and GetNavigationListSize() - 1, which - // also means `entry` must not be the initial NavigationEntry. - DCHECK_NE(0, GetNavigationListSize()); - DCHECK(!entry->IsInitialEntry()); - return entry->GetVirtualURL(); -} - -std::string NavigationControllerImpl::GetNavigationEntryTitle(int index) { - auto* entry = web_contents()->GetController().GetEntryAtIndex(index); - // This function should never be called when GetNavigationListSize() is 0 - // because `index` should be between 0 and GetNavigationListSize() - 1, which - // also means `entry` must not be the initial NavigationEntry. - DCHECK_NE(0, GetNavigationListSize()); - DCHECK(!entry->IsInitialEntry()); - return base::UTF16ToUTF8(entry->GetTitle()); -} - -bool NavigationControllerImpl::IsNavigationEntrySkippable(int index) { - return web_contents()->GetController().IsEntryMarkedToBeSkipped(index); -} - -void NavigationControllerImpl::DidStartNavigation( - content::NavigationHandle* navigation_handle) { - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. - if (!navigation_handle->IsInPrimaryMainFrame()) - return; - - // This function should not be called reentrantly. - DCHECK(!navigation_starting_); - - DCHECK(!base::Contains(navigation_map_, navigation_handle)); - navigation_map_[navigation_handle] = - std::make_unique<NavigationImpl>(navigation_handle); - auto* navigation = navigation_map_[navigation_handle].get(); - base::AutoReset<NavigationImpl*> auto_reset(&navigation_starting_, - navigation); - navigation->set_safe_to_set_request_headers(true); - navigation->set_safe_to_disable_network_error_auto_reload(true); - navigation->set_safe_to_disable_intent_processing(true); - -#if BUILDFLAG(IS_ANDROID) - // Desktop mode and per-navigation UA use the same mechanism and so don't - // interact well. It's not possible to support both at the same time since - // if there's a per-navigation UA active and desktop mode is turned on, or - // was on previously, the WebContent's state would have to change before - // navigation even though that would be wrong for the previous navigation if - // the new navigation didn't commit. - if (!TabImpl::FromWebContents(web_contents())->desktop_user_agent_enabled()) -#endif - navigation->set_safe_to_set_user_agent(true); - -#if BUILDFLAG(IS_ANDROID) - NavigationUIDataImpl* navigation_ui_data = static_cast<NavigationUIDataImpl*>( - navigation_handle->GetNavigationUIData()); - if (navigation_ui_data) { - auto response = navigation_ui_data->TakeResponse(); - if (response) - navigation->SetResponse(std::move(response)); - } - - if (java_controller_) { - JNIEnv* env = AttachCurrentThread(); - - if (navigation->GetURL().SchemeIsHTTPOrHTTPS()) { - TRACE_EVENT0("weblayer", "Java_NavigationControllerImpl_isUrlAllowed"); - - ScopedJavaLocalRef<jstring> jstring_url = - base::android::ConvertUTF8ToJavaString(env, - navigation->GetURL().spec()); - - jboolean is_allowed = Java_NavigationControllerImpl_isUrlAllowed( - env, java_controller_, jstring_url); - - if (!is_allowed) { - navigation->set_should_block_when_throttle_created(); - } - } - - { - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_createNavigation"); - ScopedJavaLocalRef<jobject> java_navigation = - Java_NavigationControllerImpl_createNavigation( - env, java_controller_, reinterpret_cast<jlong>(navigation)); - navigation->SetJavaNavigation( - base::android::ScopedJavaGlobalRef<jobject>(java_navigation)); - } - TRACE_EVENT0("weblayer", "Java_NavigationControllerImpl_navigationStarted"); - Java_NavigationControllerImpl_navigationStarted( - env, java_controller_, navigation->java_navigation()); - } -#endif - for (auto& observer : observers_) - observer.NavigationStarted(navigation); - navigation->set_safe_to_set_user_agent(false); - navigation->set_safe_to_set_request_headers(false); - navigation->set_safe_to_disable_network_error_auto_reload(false); - navigation->set_safe_to_disable_intent_processing(false); -} - -void NavigationControllerImpl::DidRedirectNavigation( - content::NavigationHandle* navigation_handle) { - // NOTE: this implementation should remain empty. Real implementation is in - // WillRedirectNavigation(). See description of NavigationThrottleImpl for - // more information. -} - -void NavigationControllerImpl::ReadyToCommitNavigation( - content::NavigationHandle* navigation_handle) { -#if BUILDFLAG(IS_ANDROID) - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. - if (!navigation_handle->IsInPrimaryMainFrame()) - return; - - DCHECK(navigation_map_.find(navigation_handle) != navigation_map_.end()); - auto* navigation = navigation_map_[navigation_handle].get(); - if (java_controller_) { - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_readyToCommitNavigation"); - Java_NavigationControllerImpl_readyToCommitNavigation( - AttachCurrentThread(), java_controller_, navigation->java_navigation()); - } -#endif -} - -void NavigationControllerImpl::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. - if (!navigation_handle->IsInPrimaryMainFrame()) - return; - - DelayDeletionHelper deletion_helper(this); - DCHECK(navigation_map_.find(navigation_handle) != navigation_map_.end()); - auto* navigation = navigation_map_[navigation_handle].get(); - - navigation->set_finished(); - - if (navigation_handle->HasCommitted()) { - // Set state on NavigationEntry user data if a per-navigation user agent was - // specified. This can't be done earlier because a NavigationEntry might not - // have existed at the time that SetUserAgentString was called. - if (navigation->set_user_agent_string_called()) { - auto* entry = web_contents()->GetController().GetLastCommittedEntry(); - if (entry) { - auto* entry_data = NavigationEntryData::Get(entry); - if (entry_data) - entry_data->set_per_navigation_user_agent_override(true); - } - } - - auto* rfh = navigation_handle->GetRenderFrameHost(); - PageImpl::GetOrCreateForPage(rfh->GetPage()); - navigation->set_safe_to_get_page(); - -#if BUILDFLAG(IS_ANDROID) - // Ensure that the Java-side Page object for this navigation is - // populated from and linked to the native Page object. Without this - // call, the Java-side navigation object won't be created and linked to - // the native object until/unless the client calls Navigation#getPage(), - // which is problematic when implementation-side callers need to bridge - // the C++ Page object into Java (e.g., to fire - // NavigationCallback#onPageLanguageDetermined()). - Java_NavigationControllerImpl_getOrCreatePageForNavigation( - AttachCurrentThread(), java_controller_, navigation->java_navigation()); -#endif - } - - // In some corner cases (e.g., a tab closing with an ongoing navigation) - // navigations finish without committing but without any other error state. - // Such navigations are regarded as failed by WebLayer. - if (navigation_handle->HasCommitted() && - navigation_handle->GetNetErrorCode() == net::OK && - !navigation_handle->IsErrorPage()) { - if (!navigation_handle->IsSameDocument()) { - content_relationship_verification::ResponseHeaderVerificationResult - header_verification_result = - content_relationship_verification::ResponseHeaderVerifier::Verify( - tab_->browser()->GetPackageName(), - navigation->GetNormalizedHeader( - content_relationship_verification:: - kEmbedderAncestorHeader)); - - bool allowed_or_missing_consent = - header_verification_result == - content_relationship_verification:: - ResponseHeaderVerificationResult::kAllow || - header_verification_result == - content_relationship_verification:: - ResponseHeaderVerificationResult::kMissing; - navigation->set_consenting_content(allowed_or_missing_consent); - } -#if BUILDFLAG(IS_ANDROID) - if (java_controller_) { - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_navigationCompleted"); - Java_NavigationControllerImpl_navigationCompleted( - AttachCurrentThread(), java_controller_, - navigation->java_navigation()); - if (deletion_helper.WasControllerDeleted()) - return; - } -#endif - for (auto& observer : observers_) { - observer.NavigationCompleted(navigation); - if (deletion_helper.WasControllerDeleted()) - return; - } - } else { -#if BUILDFLAG(IS_ANDROID) - navigation->set_consenting_content(false); - if (java_controller_) { - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_navigationFailed"); - Java_NavigationControllerImpl_navigationFailed( - AttachCurrentThread(), java_controller_, - navigation->java_navigation()); - if (deletion_helper.WasControllerDeleted()) - return; - } -#endif - for (auto& observer : observers_) { - observer.NavigationFailed(navigation); - if (deletion_helper.WasControllerDeleted()) - return; - } - } - - // Note InsertVisualStateCallback currently does not take into account - // any delays from surface sync, ie a frame submitted by renderer may not - // be displayed immediately. Such situations should be rare however, so - // this should be good enough for the purposes needed. - web_contents()->GetPrimaryMainFrame()->InsertVisualStateCallback( - base::BindOnce(&NavigationControllerImpl::OldPageNoLongerRendered, - weak_ptr_factory_.GetWeakPtr(), - navigation_handle->GetURL())); - - navigation_map_.erase(navigation_map_.find(navigation_handle)); -} - -void NavigationControllerImpl::DidStartLoading() { - NotifyLoadStateChanged(); -} - -void NavigationControllerImpl::DidStopLoading() { - NotifyLoadStateChanged(); -} - -void NavigationControllerImpl::LoadProgressChanged(double progress) { -#if BUILDFLAG(IS_ANDROID) - if (java_controller_) { - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_loadProgressChanged"); - Java_NavigationControllerImpl_loadProgressChanged( - AttachCurrentThread(), java_controller_, progress); - } -#endif - for (auto& observer : observers_) - observer.LoadProgressChanged(progress); -} - -void NavigationControllerImpl::DidFirstVisuallyNonEmptyPaint() { -#if BUILDFLAG(IS_ANDROID) - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_onFirstContentfulPaint"); - Java_NavigationControllerImpl_onFirstContentfulPaint(AttachCurrentThread(), - java_controller_); -#endif - - for (auto& observer : observers_) - observer.OnFirstContentfulPaint(); -} - -void NavigationControllerImpl::OldPageNoLongerRendered(const GURL& url, - bool success) { -#if BUILDFLAG(IS_ANDROID) - TRACE_EVENT0("weblayer", - "Java_NavigationControllerImpl_onOldPageNoLongerRendered"); - JNIEnv* env = AttachCurrentThread(); - Java_NavigationControllerImpl_onOldPageNoLongerRendered( - env, java_controller_, - base::android::ConvertUTF8ToJavaString(env, url.spec())); -#endif - for (auto& observer : observers_) - observer.OnOldPageNoLongerRendered(url); -} - -void NavigationControllerImpl::NotifyLoadStateChanged() { -#if BUILDFLAG(IS_ANDROID) - if (java_controller_) { - TRACE_EVENT0("weblayer", "Java_NavigationControllerImpl_loadStateChanged"); - Java_NavigationControllerImpl_loadStateChanged( - AttachCurrentThread(), java_controller_, web_contents()->IsLoading(), - web_contents()->ShouldShowLoadingUI()); - } -#endif - for (auto& observer : observers_) { - observer.LoadStateChanged(web_contents()->IsLoading(), - web_contents()->ShouldShowLoadingUI()); - } -} - -void NavigationControllerImpl::DoNavigate( - std::unique_ptr<content::NavigationController::LoadURLParams> params) { - CancelDelayedLoad(); - - // Navigations should use the default user-agent (which may be overridden if - // desktop mode is turned on). If the embedder wants a custom user-agent, the - // embedder will call Navigation::SetUserAgentString() in DidStartNavigation. -#if BUILDFLAG(IS_ANDROID) - // We need to set UA_OVERRIDE_FALSE if per navigation UA is set. However at - // this point we don't know if the embedder will call that later. Since we - // ensure that the two can't be set at the same time, it's sufficient to - // not enable it if desktop mode is turned on. - if (!TabImpl::FromWebContents(web_contents())->desktop_user_agent_enabled()) -#endif - params->override_user_agent = - content::NavigationController::UA_OVERRIDE_FALSE; - if (navigation_starting_ || active_throttle_) { - // DoNavigate() is being called reentrantly. Delay processing until it's - // safe. - Stop(); - ScheduleDelayedLoad(std::move(params)); - return; - } - - params->has_user_gesture = true; - web_contents()->GetController().LoadURLWithParams(*params); - // So that if the user had entered the UI in a bar it stops flashing the - // caret. - web_contents()->Focus(); -} - -void NavigationControllerImpl::ScheduleDelayedLoad( - std::unique_ptr<content::NavigationController::LoadURLParams> params) { - delayed_load_params_ = std::move(params); - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(&NavigationControllerImpl::ProcessDelayedLoad, - weak_ptr_factory_.GetWeakPtr())); -} - -void NavigationControllerImpl::CancelDelayedLoad() { - delayed_load_params_.reset(); -} - -void NavigationControllerImpl::ProcessDelayedLoad() { - if (delayed_load_params_) - DoNavigate(std::move(delayed_load_params_)); -} - -#if BUILDFLAG(IS_ANDROID) -static jlong JNI_NavigationControllerImpl_GetNavigationController(JNIEnv* env, - jlong tab) { - return reinterpret_cast<jlong>( - reinterpret_cast<Tab*>(tab)->GetNavigationController()); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/navigation_controller_impl.h b/weblayer/browser/navigation_controller_impl.h deleted file mode 100644 index 70ae4f1..0000000 --- a/weblayer/browser/navigation_controller_impl.h +++ /dev/null
@@ -1,206 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_ -#define WEBLAYER_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_ - -#include <map> - -#include <memory> -#include "base/memory/raw_ptr.h" -#include "base/memory/raw_ptr_exclusion.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "build/build_config.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/web_contents_observer.h" -#include "weblayer/browser/navigation_impl.h" -#include "weblayer/public/navigation_controller.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/scoped_java_ref.h" -#endif - -namespace content { -class NavigationHandle; -class NavigationThrottle; -} // namespace content - -namespace weblayer { -class NavigationImpl; -class TabImpl; - -class NavigationControllerImpl : public NavigationController, - public content::WebContentsObserver { - public: - explicit NavigationControllerImpl(TabImpl* tab); - - NavigationControllerImpl(const NavigationControllerImpl&) = delete; - NavigationControllerImpl& operator=(const NavigationControllerImpl&) = delete; - - ~NavigationControllerImpl() override; - - // Creates the NavigationThrottle used to ensure WebContents::Stop() is called - // at safe times. See NavigationControllerImpl for details. - std::unique_ptr<content::NavigationThrottle> CreateNavigationThrottle( - content::NavigationHandle* handle); - - // Returns the NavigationImpl for |handle|, or null if there isn't one. - NavigationImpl* GetNavigationImplFromHandle( - content::NavigationHandle* handle); - - // Returns the NavigationImpl for |navigation_id|, or null if there isn't one. - NavigationImpl* GetNavigationImplFromId(int64_t navigation_id); - - // Called when the first contentful paint page load metric is available. - // |navigation_start| is the navigation start time. - // |first_contentful_paint_ms| is the duration to first contentful paint from - // navigation start. - void OnFirstContentfulPaint(const base::TimeTicks& navigation_start, - const base::TimeDelta& first_contentful_paint); - - // Called when the largest contentful paint page load metric is available. - // |navigation_start| is the navigation start time. - // |largest_contentful_paint| is the duration to largest contentful paint from - // navigation start. - void OnLargestContentfulPaint( - const base::TimeTicks& navigation_start, - const base::TimeDelta& largest_contentful_paint); - - void OnPageDestroyed(Page* page); - void OnPageLanguageDetermined(Page* page, const std::string& language); - -#if BUILDFLAG(IS_ANDROID) - void SetNavigationControllerImpl( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& java_controller); - void Navigate(JNIEnv* env, - const base::android::JavaParamRef<jstring>& url, - jboolean should_replace_current_entry, - jboolean disable_intent_processing, - jboolean allow_intent_launches_in_background, - jboolean disable_network_error_auto_reload, - jboolean enable_auto_play, - const base::android::JavaParamRef<jobject>& response); - void GoBack(JNIEnv* env) { GoBack(); } - void GoForward(JNIEnv* env) { GoForward(); } - bool CanGoBack(JNIEnv* env) { return CanGoBack(); } - bool CanGoForward(JNIEnv* env) { return CanGoForward(); } - void GoToIndex(JNIEnv* env, int index) { return GoToIndex(index); } - void Reload(JNIEnv* env) { Reload(); } - void Stop(JNIEnv* env) { Stop(); } - int GetNavigationListSize(JNIEnv* env) { return GetNavigationListSize(); } - int GetNavigationListCurrentIndex(JNIEnv* env) { - return GetNavigationListCurrentIndex(); - } - base::android::ScopedJavaLocalRef<jstring> GetNavigationEntryDisplayUri( - JNIEnv* env, - int index); - base::android::ScopedJavaLocalRef<jstring> GetNavigationEntryTitle( - JNIEnv* env, - int index); - bool IsNavigationEntrySkippable(JNIEnv* env, int index); - base::android::ScopedJavaGlobalRef<jobject> GetNavigationImplFromId( - JNIEnv* env, - int64_t id); -#endif - - bool should_delay_web_contents_deletion() { - return should_delay_web_contents_deletion_; - } - - private: - class DelayDeletionHelper; - - class NavigationThrottleImpl; - - // Called from NavigationControllerImpl::WillRedirectRequest(). See - // description of NavigationControllerImpl for details. - void WillRedirectRequest(NavigationThrottleImpl* throttle, - content::NavigationHandle* navigation_handle); - - // NavigationController implementation: - void AddObserver(NavigationObserver* observer) override; - void RemoveObserver(NavigationObserver* observer) override; - void Navigate(const GURL& url) override; - void Navigate(const GURL& url, const NavigateParams& params) override; - void GoBack() override; - void GoForward() override; - bool CanGoBack() override; - bool CanGoForward() override; - void GoToIndex(int index) override; - void Reload() override; - void Stop() override; - int GetNavigationListSize() override; - int GetNavigationListCurrentIndex() override; - GURL GetNavigationEntryDisplayURL(int index) override; - std::string GetNavigationEntryTitle(int index) override; - bool IsNavigationEntrySkippable(int index) override; - - // content::WebContentsObserver implementation: - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override; - void DidRedirectNavigation( - content::NavigationHandle* navigation_handle) override; - void ReadyToCommitNavigation( - content::NavigationHandle* navigation_handle) override; - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; - void DidStartLoading() override; - void DidStopLoading() override; - void LoadProgressChanged(double progress) override; - void DidFirstVisuallyNonEmptyPaint() override; - - void OldPageNoLongerRendered(const GURL& url, bool success); - void NotifyLoadStateChanged(); - - void DoNavigate( - std::unique_ptr<content::NavigationController::LoadURLParams> params); - - // Schedules a load to happen as soon as possible. This is used in cases - // where it is not safe to call load. In particular, if a load was just - // started. Content is generally not reentrant when starting a load and has - // CHECKs to ensure it doesn't happen. - void ScheduleDelayedLoad( - std::unique_ptr<content::NavigationController::LoadURLParams> params); - void CancelDelayedLoad(); - void ProcessDelayedLoad(); - - // |tab_| owns |this|. - raw_ptr<TabImpl> tab_; - - base::ObserverList<NavigationObserver>::Unchecked observers_; - std::map<content::NavigationHandle*, std::unique_ptr<NavigationImpl>> - navigation_map_; - - // If non-null then processing is inside DidStartNavigation() and - // |navigation_starting_| is the NavigationImpl that was created. - // This field is not a raw_ptr<> because it was filtered by the rewriter for: - // #addr-of - RAW_PTR_EXCLUSION NavigationImpl* navigation_starting_ = nullptr; - - // Set to non-null while in WillRedirectRequest(). - // This field is not a raw_ptr<> because it was filtered by the rewriter for: - // #addr-of - RAW_PTR_EXCLUSION NavigationThrottleImpl* active_throttle_ = nullptr; - -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> java_controller_; -#endif - - // Set to true while processing an observer/callback and it's unsafe to - // delete the WebContents. This is not used for all callbacks, just the - // ones that we need to allow deletion from (such as completed/failed). - bool should_delay_web_contents_deletion_ = false; - - // See comment in ScheduleDelayedLoad() for details. - std::unique_ptr<content::NavigationController::LoadURLParams> - delayed_load_params_; - - base::WeakPtrFactory<NavigationControllerImpl> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_
diff --git a/weblayer/browser/navigation_entry_data.cc b/weblayer/browser/navigation_entry_data.cc deleted file mode 100644 index ccbeeb83..0000000 --- a/weblayer/browser/navigation_entry_data.cc +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/navigation_entry_data.h" - -#include "base/memory/ptr_util.h" -#include "content/public/browser/navigation_entry.h" - -namespace weblayer { - -namespace { - -const char kCacheKey[] = "weblayer_navigation_entry_data"; - -} // namespace - -NavigationEntryData::ResponseData::ResponseData() = default; -NavigationEntryData::ResponseData::~ResponseData() = default; - -NavigationEntryData::NavigationEntryData() = default; -NavigationEntryData::~NavigationEntryData() = default; - -std::unique_ptr<base::SupportsUserData::Data> NavigationEntryData::Clone() { - auto rv = base::WrapUnique(new NavigationEntryData); - rv->per_navigation_user_agent_override_ = per_navigation_user_agent_override_; - if (response_data_) { - rv->response_data_ = std::make_unique<ResponseData>(); - rv->response_data_->response_head = response_data_->response_head.Clone(); - rv->response_data_->data = response_data_->data; - rv->response_data_->request_time = response_data_->request_time; - rv->response_data_->response_time = response_data_->response_time; - } - return rv; -} - -NavigationEntryData* NavigationEntryData::Get(content::NavigationEntry* entry) { - auto* data = static_cast<NavigationEntryData*>(entry->GetUserData(kCacheKey)); - if (!data) { - auto data_object = base::WrapUnique(new NavigationEntryData); - data = data_object.get(); - entry->SetUserData(kCacheKey, std::move(data_object)); - } - return data; -} - -} // namespace weblayer
diff --git a/weblayer/browser/navigation_entry_data.h b/weblayer/browser/navigation_entry_data.h deleted file mode 100644 index 4f8b585..0000000 --- a/weblayer/browser/navigation_entry_data.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NAVIGATION_ENTRY_DATA_H_ -#define WEBLAYER_BROWSER_NAVIGATION_ENTRY_DATA_H_ - -#include "base/supports_user_data.h" -#include "base/time/time.h" -#include "services/network/public/mojom/url_response_head.mojom.h" - -namespace content { -class NavigationEntry; -} - -namespace weblayer { - -// Holds extra data stored on content::NavigationEntry. -class NavigationEntryData : public base::SupportsUserData::Data { - public: - ~NavigationEntryData() override; - - // base::SupportsUserData::Data implementation: - std::unique_ptr<Data> Clone() override; - - static NavigationEntryData* Get(content::NavigationEntry* entry); - - // Stored on the NavigationEntry when we have a cached response from an - // InputStream. - struct ResponseData { - ResponseData(); - ~ResponseData(); - network::mojom::URLResponseHeadPtr response_head; - std::string data; - base::Time request_time; - base::Time response_time; - }; - - void set_response_data(std::unique_ptr<ResponseData> data) { - response_data_ = std::move(data); - } - - void reset_response_data() { response_data_.reset(); } - - ResponseData* response_data() { return response_data_.get(); } - - void set_per_navigation_user_agent_override(bool value) { - per_navigation_user_agent_override_ = value; - } - bool per_navigation_user_agent_override() { - return per_navigation_user_agent_override_; - } - - private: - NavigationEntryData(); - - std::unique_ptr<ResponseData> response_data_; - bool per_navigation_user_agent_override_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NAVIGATION_ENTRY_DATA_H_
diff --git a/weblayer/browser/navigation_error_navigation_throttle.cc b/weblayer/browser/navigation_error_navigation_throttle.cc deleted file mode 100644 index 45aea8bb9..0000000 --- a/weblayer/browser/navigation_error_navigation_throttle.cc +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/navigation_error_navigation_throttle.h" - -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/render_frame_host.h" -#include "net/base/net_errors.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" -#include "weblayer/browser/navigation_controller_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/common/error_page_helper.mojom.h" -#include "weblayer/public/error_page.h" -#include "weblayer/public/error_page_delegate.h" - -using content::NavigationThrottle; - -namespace weblayer { - -NavigationErrorNavigationThrottle::NavigationErrorNavigationThrottle( - content::NavigationHandle* handle) - : NavigationThrottle(handle) { - // As this calls to the delegate, and the delegate only knows about main - // frames, this should only be used for main frames. - DCHECK(handle->IsInMainFrame()); -} - -NavigationErrorNavigationThrottle::~NavigationErrorNavigationThrottle() = - default; - -NavigationThrottle::ThrottleCheckResult -NavigationErrorNavigationThrottle::WillFailRequest() { - // The embedder is not allowed to replace ssl error pages. - if (navigation_handle()->GetNetErrorCode() == net::Error::OK || - net::IsCertificateError(navigation_handle()->GetNetErrorCode())) { - return NavigationThrottle::PROCEED; - } - - TabImpl* tab = - TabImpl::FromWebContents(navigation_handle()->GetWebContents()); - // Instances of this class are only created if there is a Tab associated - // with the WebContents. - DCHECK(tab); - if (!tab->error_page_delegate()) - return NavigationThrottle::PROCEED; - - NavigationImpl* navigation = - static_cast<NavigationControllerImpl*>(tab->GetNavigationController()) - ->GetNavigationImplFromHandle(navigation_handle()); - // The navigation this was created for should always outlive this. - DCHECK(navigation); - auto error_page = tab->error_page_delegate()->GetErrorPageContent(navigation); - if (!error_page) - return NavigationThrottle::PROCEED; - - mojo::AssociatedRemote<mojom::ErrorPageHelper> remote_error_page_helper; - navigation_handle() - ->GetRenderFrameHost() - ->GetRemoteAssociatedInterfaces() - ->GetInterface(&remote_error_page_helper); - remote_error_page_helper->DisableErrorPageHelperForNextError(); - - return NavigationThrottle::ThrottleCheckResult( - NavigationThrottle::BLOCK_REQUEST, navigation_handle()->GetNetErrorCode(), - error_page->html); -} - -const char* NavigationErrorNavigationThrottle::GetNameForLogging() { - return "NavigationErrorNavigationThrottle"; -} - -} // namespace weblayer
diff --git a/weblayer/browser/navigation_error_navigation_throttle.h b/weblayer/browser/navigation_error_navigation_throttle.h deleted file mode 100644 index 2b7f0408..0000000 --- a/weblayer/browser/navigation_error_navigation_throttle.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NAVIGATION_ERROR_NAVIGATION_THROTTLE_H_ -#define WEBLAYER_BROWSER_NAVIGATION_ERROR_NAVIGATION_THROTTLE_H_ - -#include "content/public/browser/navigation_throttle.h" - -namespace weblayer { - -// NavigationThrottle implementation that allows the embedder to inject an -// error page for non-ssl errors. -class NavigationErrorNavigationThrottle : public content::NavigationThrottle { - public: - explicit NavigationErrorNavigationThrottle(content::NavigationHandle* handle); - NavigationErrorNavigationThrottle(const NavigationErrorNavigationThrottle&) = - delete; - NavigationErrorNavigationThrottle& operator=( - const NavigationErrorNavigationThrottle&) = delete; - ~NavigationErrorNavigationThrottle() override; - - // content::NavigationThrottle: - ThrottleCheckResult WillFailRequest() override; - const char* GetNameForLogging() override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NAVIGATION_ERROR_NAVIGATION_THROTTLE_H_
diff --git a/weblayer/browser/navigation_error_navigation_throttle_browsertest.cc b/weblayer/browser/navigation_error_navigation_throttle_browsertest.cc deleted file mode 100644 index 694952d..0000000 --- a/weblayer/browser/navigation_error_navigation_throttle_browsertest.cc +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "content/public/test/url_loader_interceptor.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/error_page.h" -#include "weblayer/public/error_page_delegate.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -#include "base/run_loop.h" - -namespace weblayer { - -namespace { - -class TestErrorPageDelegate : public ErrorPageDelegate { - public: - void set_error_page_content(const std::string& value) { content_ = value; } - // ErrorPageDelegate: - bool OnBackToSafety() override { return false; } - std::unique_ptr<ErrorPage> GetErrorPageContent( - Navigation* navigation) override { - if (!content_.has_value()) - return nullptr; - auto error_page = std::make_unique<ErrorPage>(); - error_page->html = *content_; - return error_page; - } - - private: - absl::optional<std::string> content_; -}; - -} // namespace - -using NavigationErrorNavigationThrottleBrowserTest = WebLayerBrowserTest; - -// Verifies the delegate can inject an error page. -IN_PROC_BROWSER_TEST_F(NavigationErrorNavigationThrottleBrowserTest, - InjectErrorPage) { - GURL url("http://doesntexist.com/foo"); - auto interceptor = content::URLLoaderInterceptor::SetupRequestFailForURL( - url, net::ERR_NAME_NOT_RESOLVED); - TestErrorPageDelegate delegate; - delegate.set_error_page_content("<html><head><title>test error</title>"); - shell()->tab()->SetErrorPageDelegate(&delegate); - NavigateAndWaitForFailure(url, shell()); - EXPECT_EQ(u"test error", GetTitle(shell())); -} - -// Verifies the delegate can inject an empty page. -IN_PROC_BROWSER_TEST_F(NavigationErrorNavigationThrottleBrowserTest, - InjectEmptyErrorPage) { - GURL url("http://doesntexist.com/foo"); - auto interceptor = content::URLLoaderInterceptor::SetupRequestFailForURL( - url, net::ERR_NAME_NOT_RESOLVED); - TestErrorPageDelegate delegate; - delegate.set_error_page_content(std::string()); - shell()->tab()->SetErrorPageDelegate(&delegate); - NavigateAndWaitForFailure(url, shell()); - base::Value body_text = - ExecuteScript(shell()->tab(), "document.body.textContent", false); - ASSERT_TRUE(body_text.is_string()); - EXPECT_TRUE(body_text.GetString().empty()); -} - -// Verifies a null return value results in a default error page. -// Network errors only have non-empty error pages on android. -#if BUILDFLAG(IS_ANDROID) -IN_PROC_BROWSER_TEST_F(NavigationErrorNavigationThrottleBrowserTest, - DefaultErrorPage) { - GURL url("http://doesntexist.com/foo"); - auto interceptor = content::URLLoaderInterceptor::SetupRequestFailForURL( - url, net::ERR_NAME_NOT_RESOLVED); - TestErrorPageDelegate delegate; - shell()->tab()->SetErrorPageDelegate(&delegate); - NavigateAndWaitForFailure(url, shell()); - base::Value body_text = - ExecuteScript(shell()->tab(), "document.body.textContent", false); - ASSERT_TRUE(body_text.is_string()); - EXPECT_FALSE(body_text.GetString().empty()); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/navigation_impl.cc b/weblayer/browser/navigation_impl.cc deleted file mode 100644 index 0ad54edb..0000000 --- a/weblayer/browser/navigation_impl.cc +++ /dev/null
@@ -1,340 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/navigation_impl.h" - -#include "build/build_config.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/web_contents.h" -#include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" -#include "net/http/http_util.h" -#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" -#include "third_party/blink/public/mojom/loader/referrer.mojom.h" -#include "weblayer/browser/navigation_ui_data_impl.h" -#include "weblayer/browser/page_impl.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "components/embedder_support/android/util/web_resource_response.h" -#include "weblayer/browser/java/jni/NavigationImpl_jni.h" -#endif - -#if BUILDFLAG(IS_ANDROID) -using base::android::AttachCurrentThread; -using base::android::ScopedJavaLocalRef; -#endif - -namespace weblayer { - -NavigationImpl::NavigationImpl(content::NavigationHandle* navigation_handle) - : navigation_handle_(navigation_handle) { - auto* navigation_entry = navigation_handle->GetNavigationEntry(); - if (navigation_entry && - navigation_entry->GetURL() == navigation_handle->GetURL()) { - navigation_entry_unique_id_ = navigation_entry->GetUniqueID(); - } -} - -NavigationImpl::~NavigationImpl() { -#if BUILDFLAG(IS_ANDROID) - if (java_navigation_) { - Java_NavigationImpl_onNativeDestroyed(AttachCurrentThread(), - java_navigation_); - } -#endif -} - -#if BUILDFLAG(IS_ANDROID) -ScopedJavaLocalRef<jstring> NavigationImpl::GetUri(JNIEnv* env) { - return ScopedJavaLocalRef<jstring>( - base::android::ConvertUTF8ToJavaString(env, GetURL().spec())); -} - -ScopedJavaLocalRef<jobjectArray> NavigationImpl::GetRedirectChain(JNIEnv* env) { - std::vector<std::string> jni_redirects; - for (const GURL& redirect : GetRedirectChain()) - jni_redirects.push_back(redirect.spec()); - return base::android::ToJavaArrayOfStrings(env, jni_redirects); -} - -ScopedJavaLocalRef<jobjectArray> NavigationImpl::GetResponseHeaders( - JNIEnv* env) { - std::vector<std::string> jni_headers; - auto* headers = GetResponseHeaders(); - if (headers) { - size_t iterator = 0; - std::string name; - std::string value; - while (headers->EnumerateHeaderLines(&iterator, &name, &value)) { - jni_headers.push_back(name); - jni_headers.push_back(value); - } - } - - return base::android::ToJavaArrayOfStrings(env, jni_headers); -} - -jboolean NavigationImpl::GetIsConsentingContent(JNIEnv* env) { - if (GetState() != NavigationState::kComplete) { - return false; - } - return is_consenting_content_; -} - -jboolean NavigationImpl::SetRequestHeader( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& name, - const base::android::JavaParamRef<jstring>& value) { - if (!safe_to_set_request_headers_) - return false; - - SetRequestHeader(ConvertJavaStringToUTF8(name), - ConvertJavaStringToUTF8(value)); - return true; -} - -jboolean NavigationImpl::SetUserAgentString( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& value) { - if (!safe_to_set_user_agent_) - return false; - SetUserAgentString(ConvertJavaStringToUTF8(value)); - return true; -} - -jboolean NavigationImpl::DisableNetworkErrorAutoReload(JNIEnv* env) { - if (!safe_to_disable_network_error_auto_reload_) - return false; - DisableNetworkErrorAutoReload(); - return true; -} - -jboolean NavigationImpl::DisableIntentProcessing(JNIEnv* env) { - if (!safe_to_disable_intent_processing_) - return false; - disable_intent_processing_ = true; - return true; -} - -jboolean NavigationImpl::AreIntentLaunchesAllowedInBackground(JNIEnv* env) { - NavigationUIDataImpl* navigation_ui_data = static_cast<NavigationUIDataImpl*>( - navigation_handle_->GetNavigationUIData()); - - if (!navigation_ui_data) - return false; - - return navigation_ui_data->are_intent_launches_allowed_in_background(); -} - -base::android::ScopedJavaLocalRef<jstring> NavigationImpl::GetReferrer( - JNIEnv* env) { - return ScopedJavaLocalRef<jstring>( - base::android::ConvertUTF8ToJavaString(env, GetReferrer().spec())); -} - -jlong NavigationImpl::GetPage(JNIEnv* env) { - if (!safe_to_get_page_) - return -1; - return reinterpret_cast<intptr_t>(GetPage()); -} - -jint NavigationImpl::GetNavigationEntryOffset(JNIEnv* env) { - return GetNavigationEntryOffset(); -} - -jboolean NavigationImpl::WasFetchedFromCache(JNIEnv* env) { - return WasFetchedFromCache(); -} - -void NavigationImpl::SetResponse( - std::unique_ptr<embedder_support::WebResourceResponse> response) { - response_ = std::move(response); -} - -std::unique_ptr<embedder_support::WebResourceResponse> -NavigationImpl::TakeResponse() { - return std::move(response_); -} - -void NavigationImpl::SetJavaNavigation( - const base::android::ScopedJavaGlobalRef<jobject>& java_navigation) { - // SetJavaNavigation() should only be called once. - DCHECK(!java_navigation_); - java_navigation_ = java_navigation; -} - -#endif - -bool NavigationImpl::IsPageInitiated() { - return navigation_handle_->IsRendererInitiated(); -} - -bool NavigationImpl::IsReload() { - return navigation_handle_->GetReloadType() != content::ReloadType::NONE; -} - -bool NavigationImpl::IsServedFromBackForwardCache() { - return navigation_handle_->IsServedFromBackForwardCache(); -} - -Page* NavigationImpl::GetPage() { - if (!safe_to_get_page_) - return nullptr; - - return PageImpl::GetForPage( - navigation_handle_->GetRenderFrameHost()->GetPage()); -} - -int NavigationImpl::GetNavigationEntryOffset() { - return navigation_handle_->GetNavigationEntryOffset(); -} - -bool NavigationImpl::WasFetchedFromCache() { - return navigation_handle_->WasResponseCached(); -} - -GURL NavigationImpl::GetURL() { - return navigation_handle_->GetURL(); -} - -const std::vector<GURL>& NavigationImpl::GetRedirectChain() { - return navigation_handle_->GetRedirectChain(); -} - -NavigationState NavigationImpl::GetState() { - if (navigation_handle_->IsErrorPage() || navigation_handle_->IsDownload() || - (finished_ && !navigation_handle_->HasCommitted())) - return NavigationState::kFailed; - if (navigation_handle_->HasCommitted()) - return NavigationState::kComplete; - if (navigation_handle_->GetResponseHeaders()) - return NavigationState::kReceivingBytes; - return NavigationState::kWaitingResponse; -} - -int NavigationImpl::GetHttpStatusCode() { - auto* response_headers = navigation_handle_->GetResponseHeaders(); - return response_headers ? response_headers->response_code() : 0; -} - -const net::HttpResponseHeaders* NavigationImpl::GetResponseHeaders() { - return navigation_handle_->GetResponseHeaders(); -} - -std::string NavigationImpl::GetNormalizedHeader(const std::string& name) { - std::string header_value; - if (GetResponseHeaders()) { - GetResponseHeaders()->GetNormalizedHeader(name, &header_value); - } - return header_value; -} - -bool NavigationImpl::IsSameDocument() { - return navigation_handle_->IsSameDocument(); -} - -bool NavigationImpl::IsErrorPage() { - return navigation_handle_->IsErrorPage(); -} - -bool NavigationImpl::IsDownload() { - return navigation_handle_->IsDownload(); -} - -bool NavigationImpl::IsKnownProtocol() { - return !navigation_handle_->IsExternalProtocol(); -} - -bool NavigationImpl::WasStopCalled() { - return was_stopped_; -} - -Navigation::LoadError NavigationImpl::GetLoadError() { - auto error_code = navigation_handle_->GetNetErrorCode(); - if (auto* response_headers = navigation_handle_->GetResponseHeaders()) { - auto response_code = response_headers->response_code(); - if (response_code >= 400 && response_code < 500) - return kHttpClientError; - if (response_code >= 500 && response_code < 600) - return kHttpServerError; - } - - if (error_code == net::OK) - return kNoError; - - // The safe browsing navigation throttle fails navigations with - // ERR_BLOCKED_BY_CLIENT when showing safe browsing interstitials. - if (error_code == net::ERR_BLOCKED_BY_CLIENT) - return kSafeBrowsingError; - - if (net::IsCertificateError(error_code)) - return kSSLError; - - if (error_code <= -100 && error_code > -200) - return kConnectivityError; - - return kOtherError; -} - -void NavigationImpl::SetRequestHeader(const std::string& name, - const std::string& value) { - if (base::ToLowerASCII(name) == "referer") { - // The referrer needs to be special cased as content maintains it - // separately. - auto referrer = blink::mojom::Referrer::New(); - referrer->url = GURL(value); - referrer->policy = network::mojom::ReferrerPolicy::kDefault; - navigation_handle_->SetReferrer(std::move(referrer)); - } else { - // Any headers coming from the client should be exempt from CORS checks. - navigation_handle_->SetCorsExemptRequestHeader(name, value); - } -} - -void NavigationImpl::SetUserAgentString(const std::string& value) { - DCHECK(safe_to_set_user_agent_); - // By default renderer initiated navigations inherit the user-agent override - // of the current NavigationEntry. But we don't want this per-navigation UA to - // be inherited. - navigation_handle_->GetWebContents() - ->SetRendererInitiatedUserAgentOverrideOption( - content::NavigationController::UA_OVERRIDE_FALSE); - navigation_handle_->GetWebContents()->SetUserAgentOverride( - blink::UserAgentOverride::UserAgentOnly(value), - /* override_in_new_tabs */ false); - navigation_handle_->SetIsOverridingUserAgent(!value.empty()); - set_user_agent_string_called_ = true; -} - -void NavigationImpl::DisableNetworkErrorAutoReload() { - DCHECK(safe_to_disable_network_error_auto_reload_); - disable_network_error_auto_reload_ = true; -} - -bool NavigationImpl::IsFormSubmission() { - return navigation_handle_->IsFormSubmission(); -} - -GURL NavigationImpl::GetReferrer() { - return navigation_handle_->GetReferrer().url; -} - -#if BUILDFLAG(IS_ANDROID) -static jboolean JNI_NavigationImpl_IsValidRequestHeaderName( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& name) { - return net::HttpUtil::IsValidHeaderName(ConvertJavaStringToUTF8(name)); -} - -static jboolean JNI_NavigationImpl_IsValidRequestHeaderValue( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& value) { - return net::HttpUtil::IsValidHeaderValue(ConvertJavaStringToUTF8(value)); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/navigation_impl.h b/weblayer/browser/navigation_impl.h deleted file mode 100644 index c7bdaf7..0000000 --- a/weblayer/browser/navigation_impl.h +++ /dev/null
@@ -1,206 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NAVIGATION_IMPL_H_ -#define WEBLAYER_BROWSER_NAVIGATION_IMPL_H_ - -#include <memory> - -#include "base/memory/raw_ptr.h" -#include "build/build_config.h" -#include "weblayer/public/navigation.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/scoped_java_ref.h" -#endif - -namespace content { -class NavigationHandle; -} - -namespace embedder_support { -class WebResourceResponse; -} - -namespace weblayer { - -class NavigationImpl : public Navigation { - public: - explicit NavigationImpl(content::NavigationHandle* navigation_handle); - NavigationImpl(const NavigationImpl&) = delete; - NavigationImpl& operator=(const NavigationImpl&) = delete; - ~NavigationImpl() override; - - int navigation_entry_unique_id() const { return navigation_entry_unique_id_; } - - void set_should_stop_when_throttle_created() { - should_stop_when_throttle_created_ = true; - } - bool should_stop_when_throttle_created() const { - return should_stop_when_throttle_created_; - } - void set_should_block_when_throttle_created() { - should_block_when_throttle_created_ = true; - } - bool should_block_when_throttle_created() const { - return should_block_when_throttle_created_; - } - - void set_safe_to_set_request_headers(bool value) { - safe_to_set_request_headers_ = value; - } - - void set_safe_to_set_user_agent(bool value) { - safe_to_set_user_agent_ = value; - } - - void set_safe_to_disable_network_error_auto_reload(bool value) { - safe_to_disable_network_error_auto_reload_ = value; - } - - void set_safe_to_disable_intent_processing(bool value) { - safe_to_disable_intent_processing_ = value; - } - - void set_safe_to_get_page() { safe_to_get_page_ = true; } - - void set_was_stopped() { was_stopped_ = true; } - - bool set_user_agent_string_called() { return set_user_agent_string_called_; } - - bool disable_network_error_auto_reload() { - return disable_network_error_auto_reload_; - } - - bool disable_intent_processing() { return disable_intent_processing_; } - - void set_finished() { finished_ = true; } - - void set_consenting_content(bool value) { is_consenting_content_ = value; } - -#if BUILDFLAG(IS_ANDROID) - int GetState(JNIEnv* env) { return static_cast<int>(GetState()); } - base::android::ScopedJavaLocalRef<jstring> GetUri(JNIEnv* env); - base::android::ScopedJavaLocalRef<jobjectArray> GetRedirectChain(JNIEnv* env); - int GetHttpStatusCode(JNIEnv* env) { return GetHttpStatusCode(); } - base::android::ScopedJavaLocalRef<jobjectArray> GetResponseHeaders( - JNIEnv* env); - jboolean GetIsConsentingContent(JNIEnv* env); - bool IsSameDocument(JNIEnv* env) { return IsSameDocument(); } - bool IsErrorPage(JNIEnv* env) { return IsErrorPage(); } - bool IsDownload(JNIEnv* env) { return IsDownload(); } - bool IsKnownProtocol(JNIEnv* env) { return IsKnownProtocol(); } - bool WasStopCalled(JNIEnv* env) { return WasStopCalled(); } - int GetLoadError(JNIEnv* env) { return static_cast<int>(GetLoadError()); } - jboolean SetRequestHeader(JNIEnv* env, - const base::android::JavaParamRef<jstring>& name, - const base::android::JavaParamRef<jstring>& value); - jboolean SetUserAgentString( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& value); - jboolean IsPageInitiated(JNIEnv* env) { return IsPageInitiated(); } - jboolean IsReload(JNIEnv* env) { return IsReload(); } - jboolean IsServedFromBackForwardCache(JNIEnv* env) { - return IsServedFromBackForwardCache(); - } - jboolean DisableNetworkErrorAutoReload(JNIEnv* env); - jboolean DisableIntentProcessing(JNIEnv* env); - jboolean AreIntentLaunchesAllowedInBackground(JNIEnv* env); - jboolean IsFormSubmission(JNIEnv* env) { return IsFormSubmission(); } - base::android::ScopedJavaLocalRef<jstring> GetReferrer(JNIEnv* env); - jlong GetPage(JNIEnv* env); - int GetNavigationEntryOffset(JNIEnv* env); - jboolean WasFetchedFromCache(JNIEnv* env); - - void SetResponse( - std::unique_ptr<embedder_support::WebResourceResponse> response); - std::unique_ptr<embedder_support::WebResourceResponse> TakeResponse(); - - void SetJavaNavigation( - const base::android::ScopedJavaGlobalRef<jobject>& java_navigation); - base::android::ScopedJavaGlobalRef<jobject> java_navigation() { - return java_navigation_; - } -#endif - - std::string GetNormalizedHeader(const std::string& name); - - // Navigation implementation: - GURL GetURL() override; - const std::vector<GURL>& GetRedirectChain() override; - NavigationState GetState() override; - int GetHttpStatusCode() override; - const net::HttpResponseHeaders* GetResponseHeaders() override; - bool IsSameDocument() override; - bool IsErrorPage() override; - bool IsDownload() override; - bool IsKnownProtocol() override; - bool WasStopCalled() override; - LoadError GetLoadError() override; - void SetRequestHeader(const std::string& name, - const std::string& value) override; - void SetUserAgentString(const std::string& value) override; - void DisableNetworkErrorAutoReload() override; - bool IsPageInitiated() override; - bool IsReload() override; - bool IsServedFromBackForwardCache() override; - bool IsFormSubmission() override; - GURL GetReferrer() override; - Page* GetPage() override; - int GetNavigationEntryOffset() override; - bool WasFetchedFromCache() override; - - private: - raw_ptr<content::NavigationHandle> navigation_handle_; - - // The NavigationEntry's unique ID for this navigation, or -1 if there isn't - // one. - int navigation_entry_unique_id_ = -1; - - // Used to delay calling Stop() until safe. See - // NavigationControllerImpl::NavigationThrottleImpl for details. - bool should_stop_when_throttle_created_ = false; - - // Used to prevent URLs from loading. Only set when starting navigation. - bool should_block_when_throttle_created_ = false; - - // Whether SetRequestHeader() is allowed at this time. - bool safe_to_set_request_headers_ = false; - - // Whether SetUserAgentString() is allowed at this time. - bool safe_to_set_user_agent_ = false; - - // Whether NavigationController::Stop() was called for this navigation. - bool was_stopped_ = false; - - // Whether SetUserAgentString was called. - bool set_user_agent_string_called_ = false; - - // Whether DisableNetworkErrorAutoReload is allowed at this time. - bool safe_to_disable_network_error_auto_reload_ = false; - - // Whether DisableIntentProcessing is allowed at this time. - bool safe_to_disable_intent_processing_ = false; - - // Whether GetPage is allowed at this time. - bool safe_to_get_page_ = false; - - bool disable_network_error_auto_reload_ = false; - - bool disable_intent_processing_ = false; - - // Whether this navigation has finished. - bool finished_ = false; - - bool is_consenting_content_ = false; - -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> java_navigation_; - std::unique_ptr<embedder_support::WebResourceResponse> response_; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NAVIGATION_IMPL_H_
diff --git a/weblayer/browser/navigation_ui_data_impl.cc b/weblayer/browser/navigation_ui_data_impl.cc deleted file mode 100644 index d073cf5..0000000 --- a/weblayer/browser/navigation_ui_data_impl.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/navigation_ui_data_impl.h" - -#include "build/build_config.h" - -namespace weblayer { - -#if BUILDFLAG(IS_ANDROID) -NavigationUIDataImpl::ResponseHolder::ResponseHolder( - std::unique_ptr<embedder_support::WebResourceResponse> response) - : response_(std::move(response)) {} - -NavigationUIDataImpl::ResponseHolder::~ResponseHolder() = default; - -std::unique_ptr<embedder_support::WebResourceResponse> -NavigationUIDataImpl::ResponseHolder::TakeResponse() { - return std::move(response_); -} - -#endif // BUILDFLAG(IS_ANDROID) - -NavigationUIDataImpl::NavigationUIDataImpl() = default; -NavigationUIDataImpl::~NavigationUIDataImpl() = default; - -std::unique_ptr<content::NavigationUIData> NavigationUIDataImpl::Clone() { - auto rv = std::make_unique<NavigationUIDataImpl>(); - rv->disable_network_error_auto_reload_ = disable_network_error_auto_reload_; -#if BUILDFLAG(IS_ANDROID) - rv->intent_launches_allowed_in_background_ = - intent_launches_allowed_in_background_; - rv->response_holder_ = response_holder_; -#endif // BUILDFLAG(IS_ANDROID) - return rv; -} - -#if BUILDFLAG(IS_ANDROID) -void NavigationUIDataImpl::SetResponse( - std::unique_ptr<embedder_support::WebResourceResponse> response) { - DCHECK(!response_holder_); - response_holder_ = base::MakeRefCounted<ResponseHolder>(std::move(response)); -} - -std::unique_ptr<embedder_support::WebResourceResponse> -NavigationUIDataImpl::TakeResponse() { - if (!response_holder_) - return nullptr; - - return response_holder_->TakeResponse(); -} -#endif // BUILDFLAG(IS_ANDROID) - -} // namespace weblayer
diff --git a/weblayer/browser/navigation_ui_data_impl.h b/weblayer/browser/navigation_ui_data_impl.h deleted file mode 100644 index 712c2ba..0000000 --- a/weblayer/browser/navigation_ui_data_impl.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NAVIGATION_UI_DATA_IMPL_H_ -#define WEBLAYER_BROWSER_NAVIGATION_UI_DATA_IMPL_H_ - -#include "base/memory/ref_counted.h" -#include "build/build_config.h" -#include "content/public/browser/navigation_ui_data.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/embedder_support/android/util/web_resource_response.h" -#endif - -namespace weblayer { - -// Data that we pass to content::NavigationController::LoadURLWithParams -// and can access from content::NavigationHandle later. -class NavigationUIDataImpl : public content::NavigationUIData { - public: - NavigationUIDataImpl(); - NavigationUIDataImpl(const NavigationUIDataImpl&) = delete; - NavigationUIDataImpl& operator=(const NavigationUIDataImpl&) = delete; - ~NavigationUIDataImpl() override; - - // content::NavigationUIData implementation: - std::unique_ptr<content::NavigationUIData> Clone() override; - - void set_disable_network_error_auto_reload(bool value) { - disable_network_error_auto_reload_ = value; - } - bool disable_network_error_auto_reload() const { - return disable_network_error_auto_reload_; - } - -#if BUILDFLAG(IS_ANDROID) - void set_allow_intent_launches_in_background(bool value) { - intent_launches_allowed_in_background_ = value; - } - bool are_intent_launches_allowed_in_background() const { - return intent_launches_allowed_in_background_; - } - - void SetResponse( - std::unique_ptr<embedder_support::WebResourceResponse> response); - std::unique_ptr<embedder_support::WebResourceResponse> TakeResponse(); -#endif - - private: - bool disable_network_error_auto_reload_ = false; - -#if BUILDFLAG(IS_ANDROID) - bool intent_launches_allowed_in_background_ = false; - - // Even though NavigationUIData is copyable, the WebResourceResponse would - // only be used once since there are no network-retries applicable in this - // case. - class ResponseHolder : public base::RefCounted<ResponseHolder> { - public: - explicit ResponseHolder( - std::unique_ptr<embedder_support::WebResourceResponse> response_); - std::unique_ptr<embedder_support::WebResourceResponse> TakeResponse(); - - private: - friend class base::RefCounted<ResponseHolder>; - virtual ~ResponseHolder(); - - std::unique_ptr<embedder_support::WebResourceResponse> response_; - }; - - scoped_refptr<ResponseHolder> response_holder_; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NAVIGATION_UI_DATA_IMPL_H_
diff --git a/weblayer/browser/new_tab_callback_proxy.cc b/weblayer/browser/new_tab_callback_proxy.cc deleted file mode 100644 index 8ddab67..0000000 --- a/weblayer/browser/new_tab_callback_proxy.cc +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/new_tab_callback_proxy.h" - -#include "base/trace_event/trace_event.h" -#include "url/gurl.h" -#include "weblayer/browser/java/jni/NewTabCallbackProxy_jni.h" -#include "weblayer/browser/tab_impl.h" - -using base::android::AttachCurrentThread; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -NewTabCallbackProxy::NewTabCallbackProxy(JNIEnv* env, jobject obj, TabImpl* tab) - : tab_(tab), java_impl_(env, obj) { - DCHECK(!tab_->has_new_tab_delegate()); - tab_->SetNewTabDelegate(this); -} - -NewTabCallbackProxy::~NewTabCallbackProxy() { - tab_->SetNewTabDelegate(nullptr); -} - -void NewTabCallbackProxy::OnNewTab(Tab* tab, NewTabType type) { - JNIEnv* env = AttachCurrentThread(); - TRACE_EVENT0("weblayer", "Java_NewTabCallbackProxy_onNewTab"); - Java_NewTabCallbackProxy_onNewTab(env, java_impl_, - static_cast<TabImpl*>(tab)->GetJavaTab(), - static_cast<int>(type)); -} - -static jlong JNI_NewTabCallbackProxy_CreateNewTabCallbackProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong tab) { - return reinterpret_cast<jlong>( - new NewTabCallbackProxy(env, proxy, reinterpret_cast<TabImpl*>(tab))); -} - -static void JNI_NewTabCallbackProxy_DeleteNewTabCallbackProxy(JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<NewTabCallbackProxy*>(proxy); -} - -} // namespace weblayer
diff --git a/weblayer/browser/new_tab_callback_proxy.h b/weblayer/browser/new_tab_callback_proxy.h deleted file mode 100644 index 117613a..0000000 --- a/weblayer/browser/new_tab_callback_proxy.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NEW_TAB_CALLBACK_PROXY_H_ -#define WEBLAYER_BROWSER_NEW_TAB_CALLBACK_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/memory/raw_ptr.h" -#include "weblayer/public/new_tab_delegate.h" - -namespace weblayer { - -class TabImpl; - -// NewTabCallbackProxy forwards all NewTabDelegate functions to the Java -// side. There is one NewTabCallbackProxy per Tab. -class NewTabCallbackProxy : public NewTabDelegate { - public: - NewTabCallbackProxy(JNIEnv* env, jobject obj, TabImpl* tab); - - NewTabCallbackProxy(const NewTabCallbackProxy&) = delete; - NewTabCallbackProxy& operator=(const NewTabCallbackProxy&) = delete; - - ~NewTabCallbackProxy() override; - - // NewTabDelegate: - void OnNewTab(Tab* tab, NewTabType type) override; - - private: - raw_ptr<TabImpl> tab_; - base::android::ScopedJavaGlobalRef<jobject> java_impl_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NEW_TAB_CALLBACK_PROXY_H_
diff --git a/weblayer/browser/new_tab_delegate_browsertest.cc b/weblayer/browser/new_tab_delegate_browsertest.cc deleted file mode 100644 index c3853bd0..0000000 --- a/weblayer/browser/new_tab_delegate_browsertest.cc +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/public/new_tab_delegate.h" - -#include "base/strings/stringprintf.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/browser.h" -#include "weblayer/public/new_tab_delegate.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -class DestroyingNewTabDelegate : public NewTabDelegate { - public: - void WaitForOnNewTab() { run_loop_.Run(); } - - bool was_on_new_tab_called() const { return was_on_new_tab_called_; } - - // NewTabDelegate: - void OnNewTab(Tab* new_tab, NewTabType type) override { - was_on_new_tab_called_ = true; - new_tab->GetBrowser()->DestroyTab(new_tab); - run_loop_.Quit(); - } - - private: - base::RunLoop run_loop_; - bool was_on_new_tab_called_ = false; -}; - -} // namespace - -using NewTabDelegateTest = WebLayerBrowserTest; - -IN_PROC_BROWSER_TEST_F(NewTabDelegateTest, DestroyTabOnNewTab) { - ASSERT_TRUE(embedded_test_server()->Start()); - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"), - shell()->tab()); - DestroyingNewTabDelegate new_tab_delegate; - shell()->tab()->SetNewTabDelegate(&new_tab_delegate); - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - ExecuteScriptWithUserGesture( - shell()->tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str())); - new_tab_delegate.WaitForOnNewTab(); - EXPECT_TRUE(new_tab_delegate.was_on_new_tab_called()); - EXPECT_EQ(1u, shell()->tab()->GetBrowser()->GetTabs().size()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc b/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc deleted file mode 100644 index 81f91b7..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc +++ /dev/null
@@ -1,256 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> - -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/threading/platform_thread.h" -#include "build/build_config.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "components/no_state_prefetch/browser/prerender_histograms.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/url_loader_monitor.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" -#include "services/network/public/cpp/resource_request.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/prerender_controller.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/ukm/test_ukm_recorder.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "weblayer/browser/android/metrics/metrics_test_helper.h" -#endif - -namespace weblayer { - -class NoStatePrefetchBrowserTest : public WebLayerBrowserTest { - public: -#if BUILDFLAG(IS_ANDROID) - void SetUp() override { - InstallTestGmsBridge(ConsentType::kConsent); - - WebLayerBrowserTest::SetUp(); - } - - void TearDown() override { - RemoveTestGmsBridge(); - WebLayerBrowserTest::TearDown(); - } -#endif - - void SetUpOnMainThread() override { - prerendered_page_fetched_ = std::make_unique<base::RunLoop>(); - script_resource_fetched_ = std::make_unique<base::RunLoop>(); - - https_server_ = std::make_unique<net::EmbeddedTestServer>( - net::EmbeddedTestServer::TYPE_HTTPS); - https_server_->RegisterRequestHandler(base::BindRepeating( - &NoStatePrefetchBrowserTest::HandleRequest, base::Unretained(this))); - https_server_->AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - ASSERT_TRUE(https_server_->Start()); - -#if BUILDFLAG(IS_ANDROID) - ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>(); -#endif - } - - // Helper methods. - std::unique_ptr<net::test_server::HttpResponse> HandleRequest( - const net::test_server::HttpRequest& request) { - if (request.GetURL().path().find("prerendered_page") != std::string::npos) { - prerendered_page_fetched_->Quit(); - prerendered_page_was_fetched_ = true; - } - if (request.GetURL().path().find("prefetch.js") != std::string::npos) { - script_fetched_ = true; - auto iter = request.headers.find("Purpose"); - purpose_header_value_ = iter->second; - script_resource_fetched_->Quit(); - } - if (request.GetURL().path().find("prefetch_meta.js") != std::string::npos) { - script_executed_ = true; - } - - // The default handlers will take care of this request. - return nullptr; - } - - void NavigateToPageAndWaitForTitleChange(const GURL& navigate_to, - std::u16string expected_title) { - content::TitleWatcher title_watcher( - static_cast<TabImpl*>(shell()->tab())->web_contents(), expected_title); - NavigateAndWaitForCompletion(navigate_to, shell()); - ASSERT_TRUE(expected_title == title_watcher.WaitAndGetTitle()); - } - - protected: - content::BrowserContext* GetBrowserContext() { - Tab* tab = shell()->tab(); - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - return tab_impl->web_contents()->GetBrowserContext(); - } - - std::unique_ptr<base::RunLoop> prerendered_page_fetched_; - std::unique_ptr<base::RunLoop> script_resource_fetched_; - bool prerendered_page_was_fetched_ = false; - bool script_fetched_ = false; - bool script_executed_ = false; - std::string purpose_header_value_; - std::unique_ptr<net::EmbeddedTestServer> https_server_; -#if BUILDFLAG(IS_ANDROID) - std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_; -#endif -}; - -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, - CreateNoStatePrefetchManager) { - auto* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext(GetBrowserContext()); - EXPECT_TRUE(no_state_prefetch_manager); -} - -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, - CreateNoStatePrefetchLinkManager) { - auto* no_state_prefetch_link_manager = - NoStatePrefetchLinkManagerFactory::GetForBrowserContext( - GetBrowserContext()); - EXPECT_TRUE(no_state_prefetch_link_manager); -} - -// Test that adding a link-rel prerender tag causes a fetch. -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, - LinkRelPrerenderPageFetched) { - NavigateAndWaitForCompletion(GURL(https_server_->GetURL("/parent_page.html")), - shell()); - prerendered_page_fetched_->Run(); -} - -// Test that only render blocking resources are loaded during NoStatePrefetch. -// TODO(https://crbug.com/1144282): Fix failures on Asan. -#if defined(ADDRESS_SANITIZER) -#define MAYBE_NSPLoadsRenderBlockingResource \ - DISABLED_NSPLoadsRenderBlockingResource -#else -#define MAYBE_NSPLoadsRenderBlockingResource NSPLoadsRenderBlockingResource -#endif -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, - MAYBE_NSPLoadsRenderBlockingResource) { - NavigateAndWaitForCompletion(GURL(https_server_->GetURL("/parent_page.html")), - shell()); - script_resource_fetched_->Run(); - EXPECT_EQ("prefetch", purpose_header_value_); - EXPECT_FALSE(script_executed_); -} - -// Test that navigating to a no-state-prefetched page executes JS and reuses -// prerendered resources. -// TODO(https://crbug.com/1144282): Fix failures on Asan. -#if defined(ADDRESS_SANITIZER) -#define MAYBE_NavigateToPrerenderedPage DISABLED_NavigateToPrerenderedPage -#else -#define MAYBE_NavigateToPrerenderedPage NavigateToPrerenderedPage -#endif -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, - MAYBE_NavigateToPrerenderedPage) { - NavigateAndWaitForCompletion(GURL(https_server_->GetURL("/parent_page.html")), - shell()); - script_resource_fetched_->Run(); - - // Navigate to the prerendered page and wait for its title to change. - script_fetched_ = false; - NavigateToPageAndWaitForTitleChange( - GURL(https_server_->GetURL("/prerendered_page.html")), u"Prefetch Page"); - - EXPECT_FALSE(script_fetched_); - EXPECT_TRUE(script_executed_); -} - -#if BUILDFLAG(IS_ANDROID) -// Test that no-state-prefetch results in UKM getting recorded. -// TODO(https://crbug.com/1292252): Flaky failures. -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, DISABLED_UKMRecorded) { - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); - NavigateAndWaitForCompletion(GURL(https_server_->GetURL("/parent_page.html")), - shell()); - script_resource_fetched_->Run(); - - NavigateToPageAndWaitForTitleChange( - GURL(https_server_->GetURL("/prerendered_page.html")), u"Prefetch Page"); - - auto entries = ukm_recorder_->GetEntriesByName( - ukm::builders::NoStatePrefetch::kEntryName); - ASSERT_EQ(entries.size(), 1u); - const auto* entry = entries[0]; - // FinalStatus must be set to FINAL_STATUS_NOSTATE_PREFETCH_FINISHED. - ukm_recorder_->ExpectEntryMetric( - entry, - ukm::builders::NoStatePrefetch::kPrefetchedRecently_FinalStatusName, 56); - // Origin must be set to ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN. - ukm_recorder_->ExpectEntryMetric( - entry, ukm::builders::NoStatePrefetch::kPrefetchedRecently_OriginName, 7); -} -#endif - -// link-rel="prerender" happens even when NoStatePrefetch has been disabled. -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, - LinkRelPrerenderWithNSPDisabled) { - GetProfile()->SetBooleanSetting(SettingType::NETWORK_PREDICTION_ENABLED, - false); - NavigateAndWaitForCompletion(GURL(https_server_->GetURL("/parent_page.html")), - shell()); - prerendered_page_fetched_->Run(); -} - -// link-rel="next" URLs should not be prefetched. -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, LinkRelNextWithNSPDisabled) { - NavigateAndWaitForCompletion( - GURL(https_server_->GetURL("/link_rel_next_parent.html")), shell()); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(prerendered_page_was_fetched_); -} - -// Non-web initiated prerender succeeds and subsequent navigations reuse -// previously downloaded resources. -// TODO(https://crbug.com/1144282): Fix failures on Asan. -#if defined(ADDRESS_SANITIZER) -#define MAYBE_ExternalPrerender DISABLED_ExternalPrerender -#else -#define MAYBE_ExternalPrerender ExternalPrerender -#endif -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, MAYBE_ExternalPrerender) { - GetProfile()->GetPrerenderController()->Prerender( - GURL(https_server_->GetURL("/prerendered_page.html"))); - - script_resource_fetched_->Run(); - - // Navigate to the prerendered page and wait for its title to change. - script_fetched_ = false; - NavigateToPageAndWaitForTitleChange( - GURL(https_server_->GetURL("/prerendered_page.html")), u"Prefetch Page"); - EXPECT_FALSE(script_fetched_); -} - -// Non-web initiated prerender fails when the user has opted out. -IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, - ExternalPrerenderWhenOptedOut) { - GetProfile()->SetBooleanSetting(SettingType::NETWORK_PREDICTION_ENABLED, - false); - GetProfile()->GetPrerenderController()->Prerender( - GURL(https_server_->GetURL("/prerendered_page.html"))); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(prerendered_page_was_fetched_); -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.cc b/weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.cc deleted file mode 100644 index 9827786..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h" - -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_link_manager.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" - -namespace weblayer { - -// static -prerender::NoStatePrefetchLinkManager* -NoStatePrefetchLinkManagerFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<prerender::NoStatePrefetchLinkManager*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -NoStatePrefetchLinkManagerFactory* -NoStatePrefetchLinkManagerFactory::GetInstance() { - return base::Singleton<NoStatePrefetchLinkManagerFactory>::get(); -} - -NoStatePrefetchLinkManagerFactory::NoStatePrefetchLinkManagerFactory() - : BrowserContextKeyedServiceFactory( - "NoStatePrefetchLinkManager", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(weblayer::NoStatePrefetchManagerFactory::GetInstance()); -} - -std::unique_ptr<KeyedService> -NoStatePrefetchLinkManagerFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser_context) const { - DCHECK(browser_context); - - prerender::NoStatePrefetchManager* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext(browser_context); - if (!no_state_prefetch_manager) - return nullptr; - - return std::make_unique<prerender::NoStatePrefetchLinkManager>( - no_state_prefetch_manager); -} - -content::BrowserContext* -NoStatePrefetchLinkManagerFactory::GetBrowserContextToUse( - content::BrowserContext* browser_context) const { - return browser_context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h b/weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h deleted file mode 100644 index ad8abda..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_LINK_MANAGER_FACTORY_H_ -#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_LINK_MANAGER_FACTORY_H_ - -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_link_manager.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -class NoStatePrefetchLinkManagerFactory - : public BrowserContextKeyedServiceFactory { - public: - // Returns the prerender::NoStatePrefetchLinkManager for |context|. - static prerender::NoStatePrefetchLinkManager* GetForBrowserContext( - content::BrowserContext* context); - - static NoStatePrefetchLinkManagerFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<NoStatePrefetchLinkManagerFactory>; - - NoStatePrefetchLinkManagerFactory(); - ~NoStatePrefetchLinkManagerFactory() override = default; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_LINK_MANAGER_FACTORY_H_
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.cc b/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.cc deleted file mode 100644 index 8462f87..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.cc +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.h" - -#include "components/no_state_prefetch/browser/no_state_prefetch_contents_delegate.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/cookie_settings_factory.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/public/profile.h" - -namespace weblayer { - -NoStatePrefetchManagerDelegateImpl::NoStatePrefetchManagerDelegateImpl( - content::BrowserContext* browser_context) - : browser_context_(browser_context) {} - -scoped_refptr<content_settings::CookieSettings> -NoStatePrefetchManagerDelegateImpl::GetCookieSettings() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - return CookieSettingsFactory::GetForBrowserContext(browser_context_); -} - -std::unique_ptr<prerender::NoStatePrefetchContentsDelegate> -NoStatePrefetchManagerDelegateImpl::GetNoStatePrefetchContentsDelegate() { - return std::make_unique<prerender::NoStatePrefetchContentsDelegate>(); -} - -bool NoStatePrefetchManagerDelegateImpl:: - IsNetworkPredictionPreferenceEnabled() { - auto* profile = ProfileImpl::FromBrowserContext(browser_context_); - DCHECK(profile); - - return profile->GetBooleanSetting(SettingType::NETWORK_PREDICTION_ENABLED); -} - -std::string -NoStatePrefetchManagerDelegateImpl::GetReasonForDisablingPrediction() { - return IsNetworkPredictionPreferenceEnabled() ? "" - : "Disabled by user setting"; -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.h b/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.h deleted file mode 100644 index 503b4cd..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_MANAGER_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_MANAGER_DELEGATE_IMPL_H_ - -#include "base/memory/raw_ptr.h" -#include "components/content_settings/core/browser/cookie_settings.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager_delegate.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -class NoStatePrefetchManagerDelegateImpl - : public prerender::NoStatePrefetchManagerDelegate { - public: - explicit NoStatePrefetchManagerDelegateImpl( - content::BrowserContext* browser_context); - ~NoStatePrefetchManagerDelegateImpl() override = default; - - // NoStatePrefetchManagerDelegate overrides. - scoped_refptr<content_settings::CookieSettings> GetCookieSettings() override; - std::unique_ptr<prerender::NoStatePrefetchContentsDelegate> - GetNoStatePrefetchContentsDelegate() override; - bool IsNetworkPredictionPreferenceEnabled() override; - std::string GetReasonForDisablingPrediction() override; - - private: - raw_ptr<content::BrowserContext> browser_context_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_MANAGER_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.cc b/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.cc deleted file mode 100644 index 3e3893f..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" - -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_delegate_impl.h" - -namespace weblayer { - -// static -prerender::NoStatePrefetchManager* -NoStatePrefetchManagerFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<prerender::NoStatePrefetchManager*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -NoStatePrefetchManagerFactory* NoStatePrefetchManagerFactory::GetInstance() { - return base::Singleton<NoStatePrefetchManagerFactory>::get(); -} - -NoStatePrefetchManagerFactory::NoStatePrefetchManagerFactory() - : BrowserContextKeyedServiceFactory( - "NoStatePrefetchManager", - BrowserContextDependencyManager::GetInstance()) {} - -std::unique_ptr<KeyedService> -NoStatePrefetchManagerFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser_context) const { - return std::make_unique<prerender::NoStatePrefetchManager>( - browser_context, - std::make_unique<NoStatePrefetchManagerDelegateImpl>(browser_context)); -} - -content::BrowserContext* NoStatePrefetchManagerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h b/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h deleted file mode 100644 index 322d92cf..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_MANAGER_FACTORY_H_ -#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_MANAGER_FACTORY_H_ - -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace content { -class BrowserContext; -} - -namespace prerender { -class NoStatePrefetchManager; -} - -namespace weblayer { - -// Singleton that owns all NoStatePrefetchManagers and associates them with -// BrowserContexts. Listens for the BrowserContext's destruction notification -// and cleans up the associated NoStatePrefetchManager. -class NoStatePrefetchManagerFactory : public BrowserContextKeyedServiceFactory { - public: - // Returns the NoStatePrefetchManager for |context|. - static prerender::NoStatePrefetchManager* GetForBrowserContext( - content::BrowserContext* context); - - static NoStatePrefetchManagerFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<NoStatePrefetchManagerFactory>; - - NoStatePrefetchManagerFactory(); - ~NoStatePrefetchManagerFactory() override = default; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_MANAGER_FACTORY_H_
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.cc b/weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.cc deleted file mode 100644 index ca11200b..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.cc +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.h" - -#include "components/no_state_prefetch/browser/no_state_prefetch_link_manager.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_link_manager_factory.h" - -namespace weblayer { - -prerender::NoStatePrefetchLinkManager* -NoStatePrefetchProcessorImplDelegateImpl::GetNoStatePrefetchLinkManager( - content::BrowserContext* browser_context) { - return NoStatePrefetchLinkManagerFactory::GetForBrowserContext( - browser_context); -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.h b/weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.h deleted file mode 100644 index 4c321680..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_PROCESSOR_IMPL_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_PROCESSOR_IMPL_DELEGATE_IMPL_H_ - -#include "components/no_state_prefetch/browser/no_state_prefetch_processor_impl_delegate.h" - -namespace content { -class BrowserContext; -} - -namespace prerender { -class NoStatePrefetchLinkManager; -} - -namespace weblayer { - -class NoStatePrefetchProcessorImplDelegateImpl - : public prerender::NoStatePrefetchProcessorImplDelegate { - public: - NoStatePrefetchProcessorImplDelegateImpl() = default; - ~NoStatePrefetchProcessorImplDelegateImpl() override = default; - - // prerender::NoStatePrefetchProcessorImplDelegate overrides, - prerender::NoStatePrefetchLinkManager* GetNoStatePrefetchLinkManager( - content::BrowserContext* browser_context) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_PROCESSOR_IMPL_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_utils.cc b/weblayer/browser/no_state_prefetch/no_state_prefetch_utils.cc deleted file mode 100644 index fb42dac..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_utils.cc +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h" - -#include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" - -namespace weblayer { -prerender::NoStatePrefetchContents* NoStatePrefetchContentsFromWebContents( - content::WebContents* web_contents) { - if (!web_contents) - return nullptr; - - prerender::NoStatePrefetchManager* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext( - web_contents->GetBrowserContext()); - if (!no_state_prefetch_manager) - return nullptr; - - return no_state_prefetch_manager->GetNoStatePrefetchContents(web_contents); -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h b/weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h deleted file mode 100644 index 1ec49d4..0000000 --- a/weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_UTILS_H_ -#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_UTILS_H_ - -namespace content { -class WebContents; -} - -namespace prerender { -class NoStatePrefetchContents; -} - -namespace weblayer { - -prerender::NoStatePrefetchContents* NoStatePrefetchContentsFromWebContents( - content::WebContents* web_contents); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_NO_STATE_PREFETCH_UTILS_H_
diff --git a/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc b/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc deleted file mode 100644 index 8fb526b0..0000000 --- a/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/no_state_prefetch/prerender_controller_impl.h" - -#include "build/build_config.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_handle.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "content/public/browser/browser_context.h" -#include "ui/gfx/geometry/rect.h" -#include "url/gurl.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/jni_string.h" -#include "weblayer/browser/java/jni/PrerenderControllerImpl_jni.h" -#endif - -namespace weblayer { - -PrerenderControllerImpl::PrerenderControllerImpl( - content::BrowserContext* browser_context) - : browser_context_(browser_context) { - DCHECK(browser_context_); -} - -PrerenderControllerImpl::~PrerenderControllerImpl() = default; - -#if BUILDFLAG(IS_ANDROID) -void PrerenderControllerImpl::Prerender( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& url) { - Prerender(GURL(ConvertJavaStringToUTF8(url))); -} -#endif - -void PrerenderControllerImpl::Prerender(const GURL& url) { - auto* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext(browser_context_); - DCHECK(no_state_prefetch_manager); - - // The referrer parameter results in a header being set that lets the server - // serving the URL being prefetched see where the request originated. It's an - // optional header, it's okay to skip setting it here. SessionStorageNamespace - // isn't necessary for NoStatePrefetch, so it's okay to pass in a nullptr. - // NoStatePrefetchManager uses default bounds if the one provided is empty. - no_state_prefetch_manager->StartPrefetchingFromExternalRequest( - url, content::Referrer(), /* session_storage_namespace= */ nullptr, - /* bounds= */ gfx::Rect()); -} - -void PrerenderControllerImpl::DestroyAllContents() { - auto* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext(browser_context_); - DCHECK(no_state_prefetch_manager); - - no_state_prefetch_manager->DestroyAllContents( - prerender::FINAL_STATUS_APP_TERMINATING); -} - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/prerender_controller_impl.h b/weblayer/browser/no_state_prefetch/prerender_controller_impl.h deleted file mode 100644 index d1ac0b65..0000000 --- a/weblayer/browser/no_state_prefetch/prerender_controller_impl.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_CONTROLLER_IMPL_H_ -#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_CONTROLLER_IMPL_H_ - -#include "base/memory/raw_ptr.h" -#include "build/build_config.h" -#include "weblayer/public/prerender_controller.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/scoped_java_ref.h" -#endif - -class GURL; - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -// Enables creation of a non-web initiated prerender request. -class PrerenderControllerImpl : public PrerenderController { - public: - explicit PrerenderControllerImpl(content::BrowserContext* browser_context); - ~PrerenderControllerImpl() override; - PrerenderControllerImpl(const PrerenderControllerImpl&) = delete; - PrerenderControllerImpl& operator=(const PrerenderControllerImpl&) = delete; - -#if BUILDFLAG(IS_ANDROID) - void Prerender(JNIEnv* env, const base::android::JavaParamRef<jstring>& url); -#endif - - // PrerenderController - void Prerender(const GURL& url) override; - void DestroyAllContents() override; - - private: - raw_ptr<content::BrowserContext> browser_context_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_CONTROLLER_IMPL_H_
diff --git a/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc b/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc deleted file mode 100644 index a13e583..0000000 --- a/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/no_state_prefetch/prerender_tab_helper.h" - -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" - -namespace weblayer { - -PrerenderTabHelper::PrerenderTabHelper(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents), - content::WebContentsUserData<PrerenderTabHelper>(*web_contents) {} - -PrerenderTabHelper::~PrerenderTabHelper() = default; - -void PrerenderTabHelper::PrimaryPageChanged(content::Page& page) { - if (page.GetMainDocument().IsErrorDocument()) - return; - - prerender::NoStatePrefetchManager* no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); - - if (no_state_prefetch_manager && - !no_state_prefetch_manager->IsWebContentsPrefetching(web_contents())) - no_state_prefetch_manager->RecordNavigation( - page.GetMainDocument().GetLastCommittedURL()); -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(PrerenderTabHelper); - -} // namespace weblayer
diff --git a/weblayer/browser/no_state_prefetch/prerender_tab_helper.h b/weblayer/browser/no_state_prefetch/prerender_tab_helper.h deleted file mode 100644 index f64a8f3..0000000 --- a/weblayer/browser/no_state_prefetch/prerender_tab_helper.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_TAB_HELPER_H_ -#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_TAB_HELPER_H_ - -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace content { -class WebContents; -} - -namespace prerender { -class NoStatePrefetchManager; -} - -namespace weblayer { - -// Notifies the prerender::NoStatePrefetchManager with the events happening in -// the prerendered WebContents. -class PrerenderTabHelper - : public content::WebContentsObserver, - public content::WebContentsUserData<PrerenderTabHelper> { - public: - ~PrerenderTabHelper() override; - PrerenderTabHelper(const PrerenderTabHelper&) = delete; - PrerenderTabHelper& operator=(const PrerenderTabHelper&) = delete; - - // content::WebContentsObserver implementation. - void PrimaryPageChanged(content::Page& page) override; - - private: - explicit PrerenderTabHelper(content::WebContents* web_contents); - friend class content::WebContentsUserData<PrerenderTabHelper>; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_TAB_HELPER_H_ \ No newline at end of file
diff --git a/weblayer/browser/origin_trials_browsertest.cc b/weblayer/browser/origin_trials_browsertest.cc deleted file mode 100644 index 992ba95..0000000 --- a/weblayer/browser/origin_trials_browsertest.cc +++ /dev/null
@@ -1,170 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -#include "base/containers/flat_set.h" -#include "base/functional/bind.h" -#include "base/strings/strcat.h" -#include "base/test/scoped_feature_list.h" -#include "components/browsing_data/content/browsing_data_helper.h" -#include "components/origin_trials/browser/origin_trials.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/origin_trials_controller_delegate.h" -#include "content/public/common/content_features.h" -#include "content/public/test/url_loader_interceptor.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" -#include "url/origin.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -// See -// https://chromium.googlesource.com/chromium/src/+/main/docs/origin_trials_integration.md -const char kTestTokenPublicKey[] = - "dRCs+TocuKkocNKa0AtZ4awrt9XKH2SQCI6o4FY6BNA="; - -const char kTrialEnabledDomain[] = "example.com"; -const char kTrialEnabledPath[] = "/origin-trial"; -const char kFrobulatePersistentTrialName[] = "FrobulatePersistent"; -// Generated with -// tools/origin_trials/generate_token.py https://example.com \ -// FrobulatePersistent --expire-timestamp=2000000000 -const char kFrobulatePersistentToken[] = - "AzZfd1vKZ0SSGRGk/" - "8nIszQSlHYjbuYVE3jwaNZG3X4t11zRhzPWWJwTZ+JJDS3JJsyEZcpz+y20pAP6/" - "6upOQ4AAABdeyJvcmlnaW4iOiAiaHR0cHM6Ly9leGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI" - "6ICJGcm9idWxhdGVQZXJzaXN0ZW50IiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9"; - -} // namespace - -class OriginTrialsBrowserTest : public WebLayerBrowserTest { - public: - OriginTrialsBrowserTest() { - scoped_feature_list_.InitAndEnableFeature( - ::features::kPersistentOriginTrials); - } - - ~OriginTrialsBrowserTest() override = default; - - void SetUpOnMainThread() override { - WebLayerBrowserTest::SetUpOnMainThread(); - url_loader_interceptor_ = std::make_unique<content::URLLoaderInterceptor>( - base::BindRepeating(&OriginTrialsBrowserTest::InterceptRequest)); - } - - void TearDownOnMainThread() override { - // Clean up any saved settings after test run - GetBrowserContext() - ->GetOriginTrialsControllerDelegate() - ->ClearPersistedTokens(); - - url_loader_interceptor_.reset(); - - WebLayerBrowserTest::TearDownOnMainThread(); - } - - base::flat_set<std::string> GetPersistedTrials() { - url::Origin origin = url::Origin::CreateFromNormalizedTuple( - "https", kTrialEnabledDomain, 443); - return GetBrowserContext() - ->GetOriginTrialsControllerDelegate() - ->GetPersistedTrialsForOrigin(origin, /*partition_origin*/ origin, - base::Time::Now()); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII("origin-trial-public-key", - kTestTokenPublicKey); - } - - // Navigate to an insecure domain - void RequestToHttpDomain() { - NavigateAndWaitForCompletion(GURL("http://127.0.0.1/"), shell()); - } - - // Navigate to our enabled origin without any Origin-Trial response headers - void RequestWithoutHeaders() { - GURL url(base::StrCat({"https://", kTrialEnabledDomain, "/"})); - NavigateAndWaitForCompletion(url, shell()); - } - - // Navigate to our enabled origin with a response containing |token| - // in the Origin-Trial header - void RequestForOriginTrial() { - GURL url( - base::StrCat({"https://", kTrialEnabledDomain, kTrialEnabledPath})); - NavigateAndWaitForCompletion(url, shell()); - } - - static bool InterceptRequest( - content::URLLoaderInterceptor::RequestParams* params) { - std::string headers = - "HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\n"; - // Find the appropriate origin trial token. - if (params->url_request.url.DomainIs(kTrialEnabledDomain) && - params->url_request.url.path() == kTrialEnabledPath) { - // Construct and send the response. - - base::StrAppend(&headers, - {"Origin-Trial: ", kFrobulatePersistentToken, "\n"}); - } - headers += '\n'; - std::string body = "<!DOCTYPE html><body>Hello world!</body>"; - content::URLLoaderInterceptor::WriteResponse(headers, body, - params->client.get()); - return true; - } - - protected: - base::test::ScopedFeatureList scoped_feature_list_; - std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_; -}; - -IN_PROC_BROWSER_TEST_F(OriginTrialsBrowserTest, NoHeaderDoesNotEnableResponse) { - RequestWithoutHeaders(); - base::flat_set<std::string> trials = GetPersistedTrials(); - EXPECT_TRUE(trials.empty()); -} - -IN_PROC_BROWSER_TEST_F(OriginTrialsBrowserTest, ResponseEnablesOriginTrial) { - RequestForOriginTrial(); - base::flat_set<std::string> trials = GetPersistedTrials(); - ASSERT_FALSE(trials.empty()); - EXPECT_EQ(kFrobulatePersistentTrialName, *(trials.begin())); -} - -IN_PROC_BROWSER_TEST_F(OriginTrialsBrowserTest, - TrialEnabledAfterNavigationToOtherDomain) { - // Navigate to a page that enables a persistent origin trial - RequestForOriginTrial(); - EXPECT_FALSE(GetPersistedTrials().empty()); - // Navigate to a different domain - RequestToHttpDomain(); - - // The trial should still be enabled - base::flat_set<std::string> trials = GetPersistedTrials(); - ASSERT_FALSE(trials.empty()); - EXPECT_EQ(kFrobulatePersistentTrialName, *(trials.begin())); -} - -IN_PROC_BROWSER_TEST_F(OriginTrialsBrowserTest, - TrialDisabledAfterNavigationToSameDomain) { - // Navigate to a page that enables a persistent origin trial - RequestForOriginTrial(); - EXPECT_FALSE(GetPersistedTrials().empty()); - // Navigate to same domain without the Origin-Trial header set - RequestWithoutHeaders(); - - // The trial should no longer be enabled - EXPECT_TRUE(GetPersistedTrials().empty()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/origin_trials_factory.cc b/weblayer/browser/origin_trials_factory.cc deleted file mode 100644 index c4bf632..0000000 --- a/weblayer/browser/origin_trials_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/origin_trials_factory.h" - -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/origin_trials/browser/leveldb_persistence_provider.h" -#include "components/origin_trials/browser/origin_trials.h" -#include "components/origin_trials/common/features.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/storage_partition.h" -#include "third_party/blink/public/common/origin_trials/trial_token_validator.h" - -namespace weblayer { - -// static -origin_trials::OriginTrials* OriginTrialsFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - if (origin_trials::features::IsPersistentOriginTrialsEnabled()) { - return static_cast<origin_trials::OriginTrials*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); - } - return nullptr; -} - -// static -OriginTrialsFactory* OriginTrialsFactory::GetInstance() { - static base::NoDestructor<OriginTrialsFactory> factory; - return factory.get(); -} - -OriginTrialsFactory::OriginTrialsFactory() - : BrowserContextKeyedServiceFactory( - "OriginTrials", - BrowserContextDependencyManager::GetInstance()) {} - -OriginTrialsFactory::~OriginTrialsFactory() noexcept = default; - -std::unique_ptr<KeyedService> -OriginTrialsFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<origin_trials::OriginTrials>( - std::make_unique<origin_trials::LevelDbPersistenceProvider>( - context->GetPath(), - context->GetDefaultStoragePartition()->GetProtoDatabaseProvider()), - std::make_unique<blink::TrialTokenValidator>()); -} - -content::BrowserContext* OriginTrialsFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/origin_trials_factory.h b/weblayer/browser/origin_trials_factory.h deleted file mode 100644 index 5249c67..0000000 --- a/weblayer/browser/origin_trials_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_ORIGIN_TRIALS_FACTORY_H_ -#define WEBLAYER_BROWSER_ORIGIN_TRIALS_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace origin_trials { -class OriginTrials; -} // namespace origin_trials - -namespace weblayer { - -class OriginTrialsFactory : public BrowserContextKeyedServiceFactory { - public: - OriginTrialsFactory(const OriginTrialsFactory&) = delete; - OriginTrialsFactory& operator=(const OriginTrialsFactory&) = delete; - - static origin_trials::OriginTrials* GetForBrowserContext( - content::BrowserContext* browser_context); - static OriginTrialsFactory* GetInstance(); - - private: - friend class base::NoDestructor<OriginTrialsFactory>; - - OriginTrialsFactory(); - ~OriginTrialsFactory() override; - - // BrowserContextKeyedServiceFactory methods: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_ORIGIN_TRIALS_FACTORY_H_
diff --git a/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc b/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc deleted file mode 100644 index bba884b..0000000 --- a/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc +++ /dev/null
@@ -1,177 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> - -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/page_load_metrics/browser/observers/ad_metrics/ad_intervention_browser_test_utils.h" -#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" -#include "components/subresource_filter/core/browser/subresource_filter_features.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "components/subresource_filter/core/common/test_ruleset_utils.h" -#include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" -#include "components/ukm/test_ukm_recorder.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_navigation_observer.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/features.h" -#include "url/gurl.h" -#include "weblayer/test/subresource_filter_browser_test_harness.h" - -namespace weblayer { - -namespace { - -const char kAdsInterventionRecordedHistogram[] = - "SubresourceFilter.PageLoad.AdsInterventionTriggered"; - -} // namespace - -class WebLayerOverlayPopupAdViolationBrowserTest - : public SubresourceFilterBrowserTest { - public: - WebLayerOverlayPopupAdViolationBrowserTest() = default; - - void SetUp() override { - std::vector<base::test::FeatureRef> enabled = { - subresource_filter::kAdTagging, - subresource_filter::kAdsInterventionsEnforced}; - std::vector<base::test::FeatureRef> disabled = { - blink::features::kFrequencyCappingForOverlayPopupDetection}; - - feature_list_.InitWithFeatures(enabled, disabled); - SubresourceFilterBrowserTest::SetUp(); - } - - void SetUpOnMainThread() override { - SubresourceFilterBrowserTest::SetUpOnMainThread(); - SetRulesetWithRules( - {subresource_filter::testing::CreateSuffixRule("ad_iframe_writer.js")}); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -// TODO(https://crbug.com/1199860): Fails on Linux MSan. -#if BUILDFLAG(IS_LINUX) && defined(MEMORY_SANITIZER) -#define MAYBE_NoOverlayPopupAd_AdInterventionNotTriggered_WL \ - DISABLED_NoOverlayPopupAd_AdInterventionNotTriggered_WL -#else -#define MAYBE_NoOverlayPopupAd_AdInterventionNotTriggered_WL \ - NoOverlayPopupAd_AdInterventionNotTriggered_WL -#endif -IN_PROC_BROWSER_TEST_F(WebLayerOverlayPopupAdViolationBrowserTest, - MAYBE_NoOverlayPopupAd_AdInterventionNotTriggered_WL) { - base::HistogramTester histogram_tester; - - GURL url = embedded_test_server()->GetURL( - "a.com", "/ads_observer/large_scrollable_page_with_adiframe_writer.html"); - - page_load_metrics::NavigateAndWaitForFirstMeaningfulPaint(web_contents(), - url); - - // Reload the page. Since we haven't seen any ad violations, expect that the - // ad script is loaded and that the subresource filter UI doesn't show up. - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kOverlayPopupAd, 0); -} - -// TODO(https://crbug.com/1287783): Fails on linux, android and chromeos. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) -#define MAYBE_OverlayPopupAd_AdInterventionTriggered_WL \ - DISABLED_OverlayPopupAd_AdInterventionTriggered_WL -#else -#define MAYBE_OverlayPopupAd_AdInterventionTriggered_WL \ - OverlayPopupAd_AdInterventionTriggered_WL -#endif -IN_PROC_BROWSER_TEST_F(WebLayerOverlayPopupAdViolationBrowserTest, - MAYBE_OverlayPopupAd_AdInterventionTriggered_WL) { - base::HistogramTester histogram_tester; - - GURL url = embedded_test_server()->GetURL( - "a.com", "/ads_observer/large_scrollable_page_with_adiframe_writer.html"); - - page_load_metrics::NavigateAndWaitForFirstMeaningfulPaint(web_contents(), - url); - - page_load_metrics::TriggerAndDetectOverlayPopupAd(web_contents()); - - // Reload the page. Since we are enforcing ad blocking on ads violations, - // expect that the ad script is not loaded and that the subresource filter UI - // shows up. - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 1); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kOverlayPopupAd, 1); -} - -class WebLayerOverlayPopupAdViolationBrowserTestWithoutEnforcement - : public WebLayerOverlayPopupAdViolationBrowserTest { - public: - WebLayerOverlayPopupAdViolationBrowserTestWithoutEnforcement() = default; - - void SetUp() override { - std::vector<base::test::FeatureRef> enabled = { - subresource_filter::kAdTagging}; - std::vector<base::test::FeatureRef> disabled = { - subresource_filter::kAdsInterventionsEnforced, - blink::features::kFrequencyCappingForOverlayPopupDetection}; - - feature_list_.InitWithFeatures(enabled, disabled); - SubresourceFilterBrowserTest::SetUp(); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -// TODO(https://crbug.com/1344280): Test is flaky. -IN_PROC_BROWSER_TEST_F( - WebLayerOverlayPopupAdViolationBrowserTestWithoutEnforcement, - DISABLED_OverlayPopupAd_NoAdInterventionTriggered_WL) { - base::HistogramTester histogram_tester; - - GURL url = embedded_test_server()->GetURL( - "a.com", "/ads_observer/large_scrollable_page_with_adiframe_writer.html"); - - page_load_metrics::NavigateAndWaitForFirstMeaningfulPaint(web_contents(), - url); - - page_load_metrics::TriggerAndDetectOverlayPopupAd(web_contents()); - - // Reload the page. Since we are not enforcing ad blocking on ads violations, - // expect that the ad script is loaded and that the subresource filter UI - // doesn't show up. Expect a histogram recording as the intervention is - // running in dry run mode. - EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - "SubresourceFilter.Actions2", - subresource_filter::SubresourceFilterAction::kUIShown, 0); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - subresource_filter::mojom::AdsViolation::kOverlayPopupAd, 1); -} - -} // namespace weblayer
diff --git a/weblayer/browser/page_impl.cc b/weblayer/browser/page_impl.cc deleted file mode 100644 index b37e1d34..0000000 --- a/weblayer/browser/page_impl.cc +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/page_impl.h" - -#include "build/build_config.h" -#include "content/public/browser/page.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/navigation_controller_impl.h" -#include "weblayer/browser/tab_impl.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/java/jni/PageImpl_jni.h" -#endif - -#if BUILDFLAG(IS_ANDROID) -using base::android::AttachCurrentThread; -using base::android::ScopedJavaLocalRef; -#endif - -namespace weblayer { -PAGE_USER_DATA_KEY_IMPL(PageImpl); - -PageImpl::PageImpl(content::Page& page) - : content::PageUserData<PageImpl>(page) {} - -PageImpl::~PageImpl() { - auto* rfh = &(page().GetMainDocument()); - auto* web_contents = content::WebContents::FromRenderFrameHost(rfh); - auto* tab = TabImpl::FromWebContents(web_contents); - if (tab) { - auto* navigation_controller = - static_cast<NavigationControllerImpl*>(tab->GetNavigationController()); - navigation_controller->OnPageDestroyed(this); - } - -#if BUILDFLAG(IS_ANDROID) - if (java_page_) { - Java_PageImpl_onNativeDestroyed(AttachCurrentThread(), java_page_); - } -#endif -} - -#if BUILDFLAG(IS_ANDROID) -void PageImpl::SetJavaPage( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& java_page) { - java_page_ = java_page; -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/page_impl.h b/weblayer/browser/page_impl.h deleted file mode 100644 index 22bc465..0000000 --- a/weblayer/browser/page_impl.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PAGE_IMPL_H_ -#define WEBLAYER_BROWSER_PAGE_IMPL_H_ - -#include "build/build_config.h" -#include "content/public/browser/page_user_data.h" -#include "weblayer/public/page.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/scoped_java_ref.h" -#endif - -namespace weblayer { - -class PageImpl : public Page, public content::PageUserData<PageImpl> { - public: - PageImpl(const PageImpl&) = delete; - PageImpl& operator=(const PageImpl&) = delete; - - ~PageImpl() override; - -#if BUILDFLAG(IS_ANDROID) - void SetJavaPage(JNIEnv* env, - const base::android::JavaParamRef<jobject>& java_page); - - base::android::ScopedJavaGlobalRef<jobject> java_page() { return java_page_; } -#endif - - private: - explicit PageImpl(content::Page& page); - friend class content::PageUserData<PageImpl>; - PAGE_USER_DATA_KEY_DECL(); - -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> java_page_; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PAGE_IMPL_H_
diff --git a/weblayer/browser/page_load_metrics_browsertest.cc b/weblayer/browser/page_load_metrics_browsertest.cc deleted file mode 100644 index 1c3c0be..0000000 --- a/weblayer/browser/page_load_metrics_browsertest.cc +++ /dev/null
@@ -1,120 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/test/bind.h" -#include "base/test/metrics/histogram_tester.h" -#include "build/build_config.h" -#include "components/page_load_metrics/browser/page_load_metrics_observer.h" -#include "components/page_load_metrics/browser/page_load_tracker.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/page_load_metrics_initialize.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -using PageLoadMetricsBrowserTest = WebLayerBrowserTest; - -class PageLoadMetricsObserver - : public page_load_metrics::PageLoadMetricsObserver { - public: - explicit PageLoadMetricsObserver(base::RepeatingClosure quit_closure) - : quit_closure_(quit_closure) {} - ~PageLoadMetricsObserver() override = default; - - // page_load_metrics::PageLoadMetricsObserver implementation: - - ObservePolicy OnFencedFramesStart( - content::NavigationHandle* navigation_handle, - const GURL& currently_committed_url) override { - // This class is only interested in events for outer-most frame that are - // forwarded by PageLoadTracker. So, this class doesn't need observer-level - // forwarding. - return STOP_OBSERVING; - } - - PageLoadMetricsObserver::ObservePolicy OnPrerenderStart( - content::NavigationHandle* navigation_handle, - const GURL& currently_committed_url) override { - // Currently, prerendering is not enabled for WebLayer. - // - // TODO(https://crbug.com/1267224): If support prerendering, add callbacks - // and tests. - return STOP_OBSERVING; - } - - void OnFirstPaintInPage( - const page_load_metrics::mojom::PageLoadTiming& timing) override { - on_first_paint_seen_ = true; - QuitRunLoopIfReady(); - } - - void OnFirstContentfulPaintInPage( - const page_load_metrics::mojom::PageLoadTiming& timing) override { - on_first_contentful_paint_seen_ = true; - QuitRunLoopIfReady(); - } - - private: - void QuitRunLoopIfReady() { - if (on_first_paint_seen_ && on_first_contentful_paint_seen_) - quit_closure_.Run(); - } - - bool on_first_paint_seen_ = false; - bool on_first_contentful_paint_seen_ = false; - base::RepeatingClosure quit_closure_; -}; - -IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, Heartbeat) { - base::HistogramTester histogram_tester; - ASSERT_TRUE(embedded_test_server()->Start()); - - base::RunLoop run_loop; - - auto callback = base::BindLambdaForTesting( - [&](page_load_metrics::PageLoadTracker* tracker) { - tracker->AddObserver( - std::make_unique<PageLoadMetricsObserver>(run_loop.QuitClosure())); - - // Don't need this anymore - SetRegisterEmbedderObserversForTesting(nullptr); - }); - SetRegisterEmbedderObserversForTesting(&callback); - - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL("/simple_page.html"), shell()); - - run_loop.Run(); - - // Look for prefix because on Android the name would be different if the tab - // is not in foreground initially. This seems to happen on a slow test bot. - EXPECT_GE(histogram_tester - .GetTotalCountsForPrefix( - "PageLoad.PaintTiming.NavigationToFirstPaint") - .size(), - 1u); - EXPECT_GE(histogram_tester - .GetTotalCountsForPrefix( - "PageLoad.PaintTiming.NavigationToFirstContentfulPaint") - .size(), - 1u); -} - -IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, UserCounter) { - base::HistogramTester histogram_tester; - ASSERT_TRUE(embedded_test_server()->Start()); - - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/form.html"), - shell()); - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); // Flush. - - histogram_tester.ExpectBucketCount("Blink.UseCounter.MainFrame.Features", - blink::mojom::WebFeature::kPageVisits, 1); - histogram_tester.ExpectBucketCount("Blink.UseCounter.Features", - blink::mojom::WebFeature::kFormElement, 1); -} - -} // namespace weblayer
diff --git a/weblayer/browser/page_load_metrics_initialize.cc b/weblayer/browser/page_load_metrics_initialize.cc deleted file mode 100644 index 7fa928a..0000000 --- a/weblayer/browser/page_load_metrics_initialize.cc +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/page_load_metrics_initialize.h" - -#include <memory> -#include <utility> - -#include "base/functional/bind.h" -#include "components/page_load_metrics/browser/metrics_web_contents_observer.h" -#include "components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h" -#include "components/page_load_metrics/browser/page_load_metrics_embedder_base.h" -#include "components/page_load_metrics/browser/page_load_metrics_memory_tracker.h" -#include "components/page_load_metrics/browser/page_load_metrics_observer.h" -#include "components/page_load_metrics/browser/page_load_tracker.h" -#include "weblayer/browser/heavy_ad_service_factory.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h" -#include "weblayer/browser/page_load_metrics_observer_impl.h" -#include "weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.h" - -namespace content { -class BrowserContext; -} // namespace content - -namespace page_load_metrics { -class PageLoadMetricsMemoryTracker; -} // namespace page_load_metrics - -namespace weblayer { - -namespace { - -base::RepeatingCallback<void(page_load_metrics::PageLoadTracker*)>* - g_callback_for_testing; - -class PageLoadMetricsEmbedder - : public page_load_metrics::PageLoadMetricsEmbedderBase { - public: - PageLoadMetricsEmbedder(const PageLoadMetricsEmbedder&) = delete; - PageLoadMetricsEmbedder& operator=(const PageLoadMetricsEmbedder&) = delete; - explicit PageLoadMetricsEmbedder(content::WebContents* web_contents) - : PageLoadMetricsEmbedderBase(web_contents) {} - ~PageLoadMetricsEmbedder() override = default; - - // page_load_metrics::PageLoadMetricsEmbedderBase: - bool IsNewTabPageUrl(const GURL& url) override { return false; } - bool IsNoStatePrefetch(content::WebContents* web_contents) override { - return NoStatePrefetchContentsFromWebContents(web_contents); - } - bool IsExtensionUrl(const GURL& url) override { return false; } - bool IsSidePanel(content::WebContents* web_contents) override { - // The side panel is not supported in WebLayer so this always returns false. - return false; - } - page_load_metrics::PageLoadMetricsMemoryTracker* - GetMemoryTrackerForBrowserContext( - content::BrowserContext* browser_context) override { - if (!base::FeatureList::IsEnabled(features::kV8PerFrameMemoryMonitoring)) - return nullptr; - - return WeblayerPageLoadMetricsMemoryTrackerFactory::GetForBrowserContext( - browser_context); - } - - protected: - // page_load_metrics::PageLoadMetricsEmbedderBase: - void RegisterEmbedderObservers( - page_load_metrics::PageLoadTracker* tracker) override { - tracker->AddObserver(std::make_unique<PageLoadMetricsObserverImpl>()); - - if (!IsNoStatePrefetch(web_contents())) { - std::unique_ptr<page_load_metrics::AdsPageLoadMetricsObserver> - ads_observer = - page_load_metrics::AdsPageLoadMetricsObserver::CreateIfNeeded( - tracker->GetWebContents(), - HeavyAdServiceFactory::GetForBrowserContext( - tracker->GetWebContents()->GetBrowserContext()), - base::BindRepeating(&i18n::GetApplicationLocale)); - if (ads_observer) - tracker->AddObserver(std::move(ads_observer)); - } - - if (g_callback_for_testing) - (*g_callback_for_testing).Run(tracker); - } -}; - -} // namespace - -void InitializePageLoadMetricsForWebContents( - content::WebContents* web_contents) { - // Change this method? consider to modify the peer in - // android_webview/browser/page_load_metrics/page_load_metrics_initialize.cc - // chrome/browser/page_load_metrics/page_load_metrics_initialize.cc - // as well. - page_load_metrics::MetricsWebContentsObserver::CreateForWebContents( - web_contents, std::make_unique<PageLoadMetricsEmbedder>(web_contents)); -} - -void SetRegisterEmbedderObserversForTesting( - base::RepeatingCallback<void(page_load_metrics::PageLoadTracker*)>* - callback) { - g_callback_for_testing = callback; -} - -} // namespace weblayer
diff --git a/weblayer/browser/page_load_metrics_initialize.h b/weblayer/browser/page_load_metrics_initialize.h deleted file mode 100644 index 882d59b8..0000000 --- a/weblayer/browser/page_load_metrics_initialize.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PAGE_LOAD_METRICS_INITIALIZE_H_ -#define WEBLAYER_BROWSER_PAGE_LOAD_METRICS_INITIALIZE_H_ - -#include "base/functional/callback_forward.h" - -namespace content { -class WebContents; -} - -namespace page_load_metrics { -class PageLoadTracker; -} - -namespace weblayer { - -void InitializePageLoadMetricsForWebContents( - content::WebContents* web_contents); - -// Sets a callback which is called by -// page_load_metrics::PageLoadMetricsEmbedderBase::RegisterEmbedderObservers. -void SetRegisterEmbedderObserversForTesting( - base::RepeatingCallback<void(page_load_metrics::PageLoadTracker*)>* - callback); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PAGE_LOAD_METRICS_INITIALIZE_H_
diff --git a/weblayer/browser/page_load_metrics_observer_impl.cc b/weblayer/browser/page_load_metrics_observer_impl.cc deleted file mode 100644 index f22e754..0000000 --- a/weblayer/browser/page_load_metrics_observer_impl.cc +++ /dev/null
@@ -1,132 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/page_load_metrics_observer_impl.h" - -#include "base/time/time.h" -#include "build/build_config.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_utils.h" -#include "components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/web_contents.h" -#include "services/metrics/public/cpp/ukm_recorder.h" -#include "weblayer/browser/navigation_controller_impl.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" -#include "weblayer/browser/tab_impl.h" - -namespace weblayer { - -page_load_metrics::PageLoadMetricsObserver::ObservePolicy -PageLoadMetricsObserverImpl::OnFencedFramesStart( - content::NavigationHandle* navigation_handle, - const GURL& currently_committed_url) { - // This class is only interested in events for outer-most frame that are - // forwarded by PageLoadTracker. So, this class doesn't need observer-level - // forwarding. - return STOP_OBSERVING; -} - -page_load_metrics::PageLoadMetricsObserver::ObservePolicy -PageLoadMetricsObserverImpl::OnPrerenderStart( - content::NavigationHandle* navigation_handle, - const GURL& currently_committed_url) { - // Currently, prerendering is not enabled for WebLayer. - // - // TODO(https://crbug.com/1267224): If support prerendering, add callbacks, - // e.g. notification of activation_start. - return STOP_OBSERVING; -} - -PageLoadMetricsObserverImpl::ObservePolicy -PageLoadMetricsObserverImpl::OnCommit( - content::NavigationHandle* navigation_handle) { -#if BUILDFLAG(IS_ANDROID) - if (!ukm::UkmRecorder::Get()) - return CONTINUE_OBSERVING; - - // If URL-Keyed-Metrics (UKM) is enabled in the system, this is used to - // populate it with top-level page-load metrics. - prerender::NoStatePrefetchManager* const no_state_prefetch_manager = - NoStatePrefetchManagerFactory::GetForBrowserContext( - navigation_handle->GetWebContents()->GetBrowserContext()); - if (!no_state_prefetch_manager) - return CONTINUE_OBSERVING; - prerender::RecordNoStatePrefetchMetrics(navigation_handle, - GetDelegate().GetPageUkmSourceId(), - no_state_prefetch_manager); -#endif - return CONTINUE_OBSERVING; -} - -page_load_metrics::PageLoadMetricsObserver::ObservePolicy -PageLoadMetricsObserverImpl::FlushMetricsOnAppEnterBackground( - const page_load_metrics::mojom::PageLoadTiming& timing) { - // FlushMetricsOnAppEnterBackground is invoked on Android in cases where the - // app is about to be backgrounded, as part of the Activity.onPause() - // flow. After this method is invoked, WebLayer may be killed without further - // notification, so we record final metrics collected up to this point. - ReportBufferedMetrics(timing); - - // We continue observing after being backgrounded, in case we are foregrounded - // again without being killed. In those cases we may still report non-buffered - // metrics such as FCP after being re-foregrounded. - return CONTINUE_OBSERVING; -} - -PageLoadMetricsObserverImpl::ObservePolicy -PageLoadMetricsObserverImpl::OnHidden( - const page_load_metrics::mojom::PageLoadTiming& timing) { - ReportBufferedMetrics(timing); - return CONTINUE_OBSERVING; -} - -void PageLoadMetricsObserverImpl::OnComplete( - const page_load_metrics::mojom::PageLoadTiming& timing) { - ReportBufferedMetrics(timing); -} - -void PageLoadMetricsObserverImpl::OnFirstContentfulPaintInPage( - const page_load_metrics::mojom::PageLoadTiming& timing) { - auto* tab = TabImpl::FromWebContents(GetDelegate().GetWebContents()); - if (!tab) - return; - - auto* nav_controller = - static_cast<NavigationControllerImpl*>(tab->GetNavigationController()); - nav_controller->OnFirstContentfulPaint( - GetDelegate().GetNavigationStart(), - *timing.paint_timing->first_contentful_paint); -} - -void PageLoadMetricsObserverImpl::ReportBufferedMetrics( - const page_load_metrics::mojom::PageLoadTiming& timing) { - // This method may be invoked multiple times. Make sure that if we already - // reported, we do not report again. - if (reported_buffered_metrics_) - return; - reported_buffered_metrics_ = true; - - // Buffered metrics aren't available until after the navigation commits. - if (!GetDelegate().DidCommit()) - return; - - auto* tab = TabImpl::FromWebContents(GetDelegate().GetWebContents()); - if (!tab) - return; - - const page_load_metrics::ContentfulPaintTimingInfo& largest_contentful_paint = - GetDelegate() - .GetLargestContentfulPaintHandler() - .MergeMainFrameAndSubframes(); - if (!largest_contentful_paint.ContainsValidTime()) - return; - - auto* nav_controller = - static_cast<NavigationControllerImpl*>(tab->GetNavigationController()); - nav_controller->OnLargestContentfulPaint(GetDelegate().GetNavigationStart(), - *largest_contentful_paint.Time()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/page_load_metrics_observer_impl.h b/weblayer/browser/page_load_metrics_observer_impl.h deleted file mode 100644 index d2d1572..0000000 --- a/weblayer/browser/page_load_metrics_observer_impl.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PAGE_LOAD_METRICS_OBSERVER_IMPL_H_ -#define WEBLAYER_BROWSER_PAGE_LOAD_METRICS_OBSERVER_IMPL_H_ - -#include "components/page_load_metrics/browser/page_load_metrics_observer.h" - -namespace weblayer { - -class PageLoadMetricsObserverImpl - : public page_load_metrics::PageLoadMetricsObserver { - public: - PageLoadMetricsObserverImpl() = default; - ~PageLoadMetricsObserverImpl() override = default; - - // page_load_metrics::PageLoadMetricsObserver implementation: - ObservePolicy OnFencedFramesStart( - content::NavigationHandle* navigation_handle, - const GURL& currently_committed_url) override; - ObservePolicy OnPrerenderStart(content::NavigationHandle* navigation_handle, - const GURL& currently_committed_url) override; - ObservePolicy FlushMetricsOnAppEnterBackground( - const page_load_metrics::mojom::PageLoadTiming& timing) override; - ObservePolicy OnHidden( - const page_load_metrics::mojom::PageLoadTiming& timing) override; - void OnComplete( - const page_load_metrics::mojom::PageLoadTiming& timing) override; - ObservePolicy OnCommit(content::NavigationHandle* navigation_handle) override; - void OnFirstContentfulPaintInPage( - const page_load_metrics::mojom::PageLoadTiming& timing) override; - - void ReportBufferedMetrics( - const page_load_metrics::mojom::PageLoadTiming& timing); - - private: - bool reported_buffered_metrics_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PAGE_LOAD_METRICS_OBSERVER_IMPL_H_
diff --git a/weblayer/browser/page_specific_content_settings_delegate.cc b/weblayer/browser/page_specific_content_settings_delegate.cc deleted file mode 100644 index d8e6106..0000000 --- a/weblayer/browser/page_specific_content_settings_delegate.cc +++ /dev/null
@@ -1,99 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/page_specific_content_settings_delegate.h" - -#include "base/feature_list.h" -#include "base/functional/callback_helpers.h" -#include "components/content_settings/core/common/content_settings.h" -#include "components/permissions/permission_decision_auto_blocker.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/content_features.h" -#include "ipc/ipc_channel_proxy.h" -#include "mojo/public/cpp/bindings/associated_remote.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/content_settings_manager_delegate.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/permissions/permission_decision_auto_blocker_factory.h" -#include "weblayer/common/renderer_configuration.mojom.h" - -namespace weblayer { - -PageSpecificContentSettingsDelegate::PageSpecificContentSettingsDelegate( - content::WebContents* web_contents) - : web_contents_(web_contents) {} - -PageSpecificContentSettingsDelegate::~PageSpecificContentSettingsDelegate() = - default; - -// static -void PageSpecificContentSettingsDelegate::InitializeRenderer( - content::RenderProcessHost* process) { - mojo::AssociatedRemote<mojom::RendererConfiguration> rc_interface; - process->GetChannel()->GetRemoteAssociatedInterface(&rc_interface); - mojo::PendingRemote<content_settings::mojom::ContentSettingsManager> - content_settings_manager; - content_settings::ContentSettingsManagerImpl::Create( - process, content_settings_manager.InitWithNewPipeAndPassReceiver(), - std::make_unique<ContentSettingsManagerDelegate>()); - rc_interface->SetInitialConfiguration(std::move(content_settings_manager)); -} - -void PageSpecificContentSettingsDelegate::UpdateLocationBar() {} - -PrefService* PageSpecificContentSettingsDelegate::GetPrefs() { - return static_cast<BrowserContextImpl*>(web_contents_->GetBrowserContext()) - ->pref_service(); -} - -HostContentSettingsMap* PageSpecificContentSettingsDelegate::GetSettingsMap() { - return HostContentSettingsMapFactory::GetForBrowserContext( - web_contents_->GetBrowserContext()); -} - -std::unique_ptr<BrowsingDataModel::Delegate> -PageSpecificContentSettingsDelegate::CreateBrowsingDataModelDelegate() { - return nullptr; -} - -void PageSpecificContentSettingsDelegate::SetDefaultRendererContentSettingRules( - content::RenderFrameHost* rfh, - RendererContentSettingRules* rules) {} - -std::vector<storage::FileSystemType> -PageSpecificContentSettingsDelegate::GetAdditionalFileSystemTypes() { - return {}; -} - -browsing_data::CookieHelper::IsDeletionDisabledCallback -PageSpecificContentSettingsDelegate::GetIsDeletionDisabledCallback() { - return base::NullCallback(); -} - -bool PageSpecificContentSettingsDelegate::IsMicrophoneCameraStateChanged( - content_settings::PageSpecificContentSettings::MicrophoneCameraState - microphone_camera_state, - const std::string& media_stream_selected_audio_device, - const std::string& media_stream_selected_video_device) { - return false; -} - -content_settings::PageSpecificContentSettings::MicrophoneCameraState -PageSpecificContentSettingsDelegate::GetMicrophoneCameraState() { - return {}; -} - -content::WebContents* PageSpecificContentSettingsDelegate:: - MaybeGetSyncedWebContentsForPictureInPicture( - content::WebContents* web_contents) { - return nullptr; -} - -void PageSpecificContentSettingsDelegate::OnContentAllowed( - ContentSettingsType type) {} - -void PageSpecificContentSettingsDelegate::OnContentBlocked( - ContentSettingsType type) {} - -} // namespace weblayer
diff --git a/weblayer/browser/page_specific_content_settings_delegate.h b/weblayer/browser/page_specific_content_settings_delegate.h deleted file mode 100644 index 91af0f8..0000000 --- a/weblayer/browser/page_specific_content_settings_delegate.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PAGE_SPECIFIC_CONTENT_SETTINGS_DELEGATE_H_ -#define WEBLAYER_BROWSER_PAGE_SPECIFIC_CONTENT_SETTINGS_DELEGATE_H_ - -#include "base/memory/raw_ptr.h" -#include "components/content_settings/browser/page_specific_content_settings.h" - -namespace weblayer { - -// Called by PageSpecificContentSettings to handle WebLayer specific logic. -class PageSpecificContentSettingsDelegate - : public content_settings::PageSpecificContentSettings::Delegate { - public: - explicit PageSpecificContentSettingsDelegate( - content::WebContents* web_contents); - ~PageSpecificContentSettingsDelegate() override; - PageSpecificContentSettingsDelegate( - const PageSpecificContentSettingsDelegate&) = delete; - PageSpecificContentSettingsDelegate& operator=( - const PageSpecificContentSettingsDelegate&) = delete; - - static void InitializeRenderer(content::RenderProcessHost* process); - - private: - // PageSpecificContentSettings::Delegate: - void UpdateLocationBar() override; - PrefService* GetPrefs() override; - HostContentSettingsMap* GetSettingsMap() override; - std::unique_ptr<BrowsingDataModel::Delegate> CreateBrowsingDataModelDelegate() - override; - void SetDefaultRendererContentSettingRules( - content::RenderFrameHost* rfh, - RendererContentSettingRules* rules) override; - std::vector<storage::FileSystemType> GetAdditionalFileSystemTypes() override; - browsing_data::CookieHelper::IsDeletionDisabledCallback - GetIsDeletionDisabledCallback() override; - bool IsMicrophoneCameraStateChanged( - content_settings::PageSpecificContentSettings::MicrophoneCameraState - microphone_camera_state, - const std::string& media_stream_selected_audio_device, - const std::string& media_stream_selected_video_device) override; - content_settings::PageSpecificContentSettings::MicrophoneCameraState - GetMicrophoneCameraState() override; - content::WebContents* MaybeGetSyncedWebContentsForPictureInPicture( - content::WebContents* web_contents) override; - void OnContentAllowed(ContentSettingsType type) override; - void OnContentBlocked(ContentSettingsType type) override; - - raw_ptr<content::WebContents> web_contents_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PAGE_SPECIFIC_CONTENT_SETTINGS_DELEGATE_H_
diff --git a/weblayer/browser/password_manager_driver_factory.cc b/weblayer/browser/password_manager_driver_factory.cc deleted file mode 100644 index ed367316..0000000 --- a/weblayer/browser/password_manager_driver_factory.cc +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/password_manager_driver_factory.h" - -#include "base/memory/raw_ptr.h" -#include "components/password_manager/content/browser/bad_message.h" -#include "components/password_manager/content/browser/form_meta_data.h" -#include "components/site_isolation/site_isolation_policy.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "mojo/public/cpp/bindings/associated_receiver.h" - -namespace weblayer { - -// A minimal implementation of autofill::mojom::PasswordManagerDriver which just -// listens for the user to type into a password field. -class PasswordManagerDriverFactory::PasswordManagerDriver - : public autofill::mojom::PasswordManagerDriver { - public: - explicit PasswordManagerDriver(content::RenderFrameHost* render_frame_host) - : render_frame_host_(render_frame_host) {} - - void BindPendingReceiver( - mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver> - pending_receiver) { - password_manager_receiver_.Bind(std::move(pending_receiver)); - } - - private: - // autofill::mojom::PasswordManagerDriver: - // Note that these messages received from a potentially compromised renderer. - // For that reason, any access to form data should be validated via - // bad_message::CheckChildProcessSecurityPolicy. - void PasswordFormsParsed( - const std::vector<autofill::FormData>& raw_forms_data) override {} - void PasswordFormsRendered( - const std::vector<autofill::FormData>& raw_visible_forms_data) override {} - void PasswordFormSubmitted(const autofill::FormData& raw_form_data) override { - } - void InformAboutUserInput(const autofill::FormData& raw_form_data) override { - autofill::FormData form_data = - password_manager::GetFormWithFrameAndFormMetaData(render_frame_host_, - raw_form_data); - if (FormHasNonEmptyPasswordField(form_data) && - site_isolation::SiteIsolationPolicy:: - IsIsolationForPasswordSitesEnabled()) { - // This function signals that a password field has been filled (whether by - // the user, JS, autofill, or some other means) or a password form has - // been submitted. Use this as a heuristic to start site-isolating the - // form's site. This is intended to be used primarily when full site - // isolation is not used, such as on Android. - content::SiteInstance::StartIsolatingSite( - render_frame_host_->GetSiteInstance()->GetBrowserContext(), - form_data.url, - content::ChildProcessSecurityPolicy::IsolatedOriginSource:: - USER_TRIGGERED); - } - } - void DynamicFormSubmission(autofill::mojom::SubmissionIndicatorEvent - submission_indication_event) override {} - void PasswordFormCleared(const autofill::FormData& raw_form_data) override {} - void RecordSavePasswordProgress(const std::string& log) override {} - void UserModifiedPasswordField() override {} - void UserModifiedNonPasswordField(autofill::FieldRendererId renderer_id, - const std::u16string& value, - bool autocomplete_attribute_has_username, - bool is_likely_otp) override {} - void ShowPasswordSuggestions(autofill::FieldRendererId element_id, - const autofill::FormData& form, - uint64_t username_field_index, - uint64_t password_field_index, - base::i18n::TextDirection text_direction, - const std::u16string& typed_username, - int options, - const gfx::RectF& bounds) override {} - -#if BUILDFLAG(IS_ANDROID) - void ShowKeyboardReplacingSurface( - autofill::mojom::SubmissionReadinessState submission_readiness, - bool is_webauthn_form) override {} -#endif - - void CheckSafeBrowsingReputation(const GURL& form_action, - const GURL& frame_url) override {} - void FocusedInputChanged( - autofill::FieldRendererId focused_field_id, - autofill::mojom::FocusedFieldType focused_field_type) override {} - void LogFirstFillingResult(autofill::FormRendererId form_renderer_id, - int32_t result) override {} - - mojo::AssociatedReceiver<autofill::mojom::PasswordManagerDriver> - password_manager_receiver_{this}; - raw_ptr<content::RenderFrameHost> render_frame_host_; -}; - -PasswordManagerDriverFactory::PasswordManagerDriverFactory( - content::WebContents* web_contents) - : content::WebContentsObserver(web_contents), - content::WebContentsUserData<PasswordManagerDriverFactory>( - *web_contents) {} - -PasswordManagerDriverFactory::~PasswordManagerDriverFactory() = default; - -// static -void PasswordManagerDriverFactory::BindPasswordManagerDriver( - mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver> - pending_receiver, - content::RenderFrameHost* render_frame_host) { - // TODO(https://crbug.com/1233858): Similarly to the - // ContentPasswordManagerDriver implementation. Do not bind the interface when - // the RenderFrameHost is in an anonymous iframe. - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(render_frame_host); - if (!web_contents) - return; - - PasswordManagerDriverFactory* factory = - PasswordManagerDriverFactory::FromWebContents(web_contents); - if (!factory) - return; - - factory->GetDriverForFrame(render_frame_host) - ->BindPendingReceiver(std::move(pending_receiver)); -} - -PasswordManagerDriverFactory::PasswordManagerDriver* -PasswordManagerDriverFactory::GetDriverForFrame( - content::RenderFrameHost* render_frame_host) { - DCHECK_EQ(web_contents(), - content::WebContents::FromRenderFrameHost(render_frame_host)); - DCHECK(render_frame_host->IsRenderFrameLive()); - - auto [it, inserted] = - frame_driver_map_.try_emplace(render_frame_host, render_frame_host); - return &it->second; -} - -void PasswordManagerDriverFactory::RenderFrameDeleted( - content::RenderFrameHost* render_frame_host) { - frame_driver_map_.erase(render_frame_host); -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(PasswordManagerDriverFactory); - -} // namespace weblayer
diff --git a/weblayer/browser/password_manager_driver_factory.h b/weblayer/browser/password_manager_driver_factory.h deleted file mode 100644 index cfc4494e..0000000 --- a/weblayer/browser/password_manager_driver_factory.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PASSWORD_MANAGER_DRIVER_FACTORY_H_ -#define WEBLAYER_BROWSER_PASSWORD_MANAGER_DRIVER_FACTORY_H_ - -#include <map> - -#include "components/autofill/content/common/mojom/autofill_driver.mojom.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "mojo/public/cpp/bindings/pending_associated_receiver.h" - -namespace content { -class WebContents; -} - -namespace weblayer { - -// WebLayer uses the system autofill and not the autofill used by Chrome. This -// factory and the corresponding driver are only used to listen for the -// notification that a password was typed into a form, since this is used as a -// signal to start isolating that site. -// TODO(crbug.com/1088446): Find a way to easily share this with Chrome. -class PasswordManagerDriverFactory - : public content::WebContentsObserver, - public content::WebContentsUserData<PasswordManagerDriverFactory> { - public: - ~PasswordManagerDriverFactory() override; - - PasswordManagerDriverFactory(const PasswordManagerDriverFactory&) = delete; - PasswordManagerDriverFactory& operator=(const PasswordManagerDriverFactory&) = - delete; - - static void BindPasswordManagerDriver( - mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver> - pending_receiver, - content::RenderFrameHost* render_frame_host); - - private: - class PasswordManagerDriver; - friend class content::WebContentsUserData<PasswordManagerDriverFactory>; - - explicit PasswordManagerDriverFactory(content::WebContents* web_contents); - - // content::WebContentsObserver: - void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; - - PasswordManagerDriver* GetDriverForFrame( - content::RenderFrameHost* render_frame_host); - - std::map<content::RenderFrameHost*, PasswordManagerDriver> frame_driver_map_; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PASSWORD_MANAGER_DRIVER_FACTORY_H_
diff --git a/weblayer/browser/permissions/geolocation_permission_context_delegate.cc b/weblayer/browser/permissions/geolocation_permission_context_delegate.cc deleted file mode 100644 index a44299da..0000000 --- a/weblayer/browser/permissions/geolocation_permission_context_delegate.cc +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/permissions/geolocation_permission_context_delegate.h" - -#include "build/build_config.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/android/permission_request_utils.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/tab_impl.h" -#endif - -namespace weblayer { - -bool GeolocationPermissionContextDelegate::DecidePermission( - const permissions::PermissionRequestID& id, - const GURL& requesting_origin, - bool user_gesture, - permissions::BrowserPermissionCallback* callback, - permissions::GeolocationPermissionContext* context) { - return false; -} - -#if BUILDFLAG(IS_ANDROID) -bool GeolocationPermissionContextDelegate::IsInteractable( - content::WebContents* web_contents) { - auto* tab = TabImpl::FromWebContents(web_contents); - return tab && tab->IsActive(); -} - -PrefService* GeolocationPermissionContextDelegate::GetPrefs( - content::BrowserContext* browser_context) { - return static_cast<BrowserContextImpl*>(browser_context)->pref_service(); -} - -bool GeolocationPermissionContextDelegate::IsRequestingOriginDSE( - content::BrowserContext* browser_context, - const GURL& requesting_origin) { - return false; -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/geolocation_permission_context_delegate.h b/weblayer/browser/permissions/geolocation_permission_context_delegate.h deleted file mode 100644 index 0aa94b10..0000000 --- a/weblayer/browser/permissions/geolocation_permission_context_delegate.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERMISSIONS_GEOLOCATION_PERMISSION_CONTEXT_DELEGATE_H_ -#define WEBLAYER_BROWSER_PERMISSIONS_GEOLOCATION_PERMISSION_CONTEXT_DELEGATE_H_ - -#include "build/build_config.h" -#include "components/permissions/contexts/geolocation_permission_context.h" - -namespace weblayer { - -class GeolocationPermissionContextDelegate - : public permissions::GeolocationPermissionContext::Delegate { - public: - GeolocationPermissionContextDelegate() = default; - - GeolocationPermissionContextDelegate( - const GeolocationPermissionContextDelegate&) = delete; - GeolocationPermissionContextDelegate& operator=( - const GeolocationPermissionContextDelegate&) = delete; - - // GeolocationPermissionContext::Delegate: - bool DecidePermission( - const permissions::PermissionRequestID& id, - const GURL& requesting_origin, - bool user_gesture, - permissions::BrowserPermissionCallback* callback, - permissions::GeolocationPermissionContext* context) override; -#if BUILDFLAG(IS_ANDROID) - bool IsInteractable(content::WebContents* web_contents) override; - PrefService* GetPrefs(content::BrowserContext* browser_context) override; - bool IsRequestingOriginDSE(content::BrowserContext* browser_context, - const GURL& requesting_origin) override; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERMISSIONS_GEOLOCATION_PERMISSION_CONTEXT_DELEGATE_H_
diff --git a/weblayer/browser/permissions/origin_keyed_permission_action_service_factory.cc b/weblayer/browser/permissions/origin_keyed_permission_action_service_factory.cc deleted file mode 100644 index 6071ae7..0000000 --- a/weblayer/browser/permissions/origin_keyed_permission_action_service_factory.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/permissions/origin_keyed_permission_action_service_factory.h" - -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/permissions/origin_keyed_permission_action_service.h" - -namespace weblayer { - -// static -permissions::OriginKeyedPermissionActionService* -OriginKeyedPermissionActionServiceFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<permissions::OriginKeyedPermissionActionService*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -OriginKeyedPermissionActionServiceFactory* -OriginKeyedPermissionActionServiceFactory::GetInstance() { - static base::NoDestructor<OriginKeyedPermissionActionServiceFactory> factory; - return factory.get(); -} - -OriginKeyedPermissionActionServiceFactory:: - OriginKeyedPermissionActionServiceFactory() - : BrowserContextKeyedServiceFactory( - "OriginKeyedPermissionActionService", - BrowserContextDependencyManager::GetInstance()) {} - -OriginKeyedPermissionActionServiceFactory:: - ~OriginKeyedPermissionActionServiceFactory() = default; - -KeyedService* -OriginKeyedPermissionActionServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return new permissions::OriginKeyedPermissionActionService(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/origin_keyed_permission_action_service_factory.h b/weblayer/browser/permissions/origin_keyed_permission_action_service_factory.h deleted file mode 100644 index 53f39d9e..0000000 --- a/weblayer/browser/permissions/origin_keyed_permission_action_service_factory.h +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERMISSIONS_ORIGIN_KEYED_PERMISSION_ACTION_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_PERMISSIONS_ORIGIN_KEYED_PERMISSION_ACTION_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace permissions { -class OriginKeyedPermissionActionService; -} // namespace permissions - -namespace weblayer { - -// Factory to create a service to keep track of permission actions of the -// current browser session for metrics evaluation. -class OriginKeyedPermissionActionServiceFactory - : public BrowserContextKeyedServiceFactory { - public: - OriginKeyedPermissionActionServiceFactory( - const OriginKeyedPermissionActionServiceFactory&) = delete; - OriginKeyedPermissionActionServiceFactory& operator=( - const OriginKeyedPermissionActionServiceFactory&) = delete; - - static permissions::OriginKeyedPermissionActionService* GetForBrowserContext( - content::BrowserContext* browser_context); - - static OriginKeyedPermissionActionServiceFactory* GetInstance(); - - private: - friend class base::NoDestructor<OriginKeyedPermissionActionServiceFactory>; - - OriginKeyedPermissionActionServiceFactory(); - ~OriginKeyedPermissionActionServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERMISSIONS_ORIGIN_KEYED_PERMISSION_ACTION_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/permissions/permission_decision_auto_blocker_factory.cc b/weblayer/browser/permissions/permission_decision_auto_blocker_factory.cc deleted file mode 100644 index 7e39994..0000000 --- a/weblayer/browser/permissions/permission_decision_auto_blocker_factory.cc +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/permissions/permission_decision_auto_blocker_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/permissions/permission_decision_auto_blocker.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -permissions::PermissionDecisionAutoBlocker* -PermissionDecisionAutoBlockerFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<permissions::PermissionDecisionAutoBlocker*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -PermissionDecisionAutoBlockerFactory* -PermissionDecisionAutoBlockerFactory::GetInstance() { - static base::NoDestructor<PermissionDecisionAutoBlockerFactory> factory; - return factory.get(); -} - -PermissionDecisionAutoBlockerFactory::PermissionDecisionAutoBlockerFactory() - : BrowserContextKeyedServiceFactory( - "PermissionDecisionAutoBlocker", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -PermissionDecisionAutoBlockerFactory::~PermissionDecisionAutoBlockerFactory() = - default; - -std::unique_ptr<KeyedService> -PermissionDecisionAutoBlockerFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<permissions::PermissionDecisionAutoBlocker>( - HostContentSettingsMapFactory::GetForBrowserContext(context)); -} - -content::BrowserContext* -PermissionDecisionAutoBlockerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/permission_decision_auto_blocker_factory.h b/weblayer/browser/permissions/permission_decision_auto_blocker_factory.h deleted file mode 100644 index dfcc87b..0000000 --- a/weblayer/browser/permissions/permission_decision_auto_blocker_factory.h +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERMISSIONS_PERMISSION_DECISION_AUTO_BLOCKER_FACTORY_H_ -#define WEBLAYER_BROWSER_PERMISSIONS_PERMISSION_DECISION_AUTO_BLOCKER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace permissions { -class PermissionDecisionAutoBlocker; -} - -namespace weblayer { - -class PermissionDecisionAutoBlockerFactory - : public BrowserContextKeyedServiceFactory { - public: - PermissionDecisionAutoBlockerFactory( - const PermissionDecisionAutoBlockerFactory&) = delete; - PermissionDecisionAutoBlockerFactory& operator=( - const PermissionDecisionAutoBlockerFactory&) = delete; - - static permissions::PermissionDecisionAutoBlocker* GetForBrowserContext( - content::BrowserContext* browser_context); - static PermissionDecisionAutoBlockerFactory* GetInstance(); - - private: - friend class base::NoDestructor<PermissionDecisionAutoBlockerFactory>; - - PermissionDecisionAutoBlockerFactory(); - ~PermissionDecisionAutoBlockerFactory() override; - - // BrowserContextKeyedServiceFactory - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERMISSIONS_PERMISSION_DECISION_AUTO_BLOCKER_FACTORY_H_
diff --git a/weblayer/browser/permissions/permission_manager_factory.cc b/weblayer/browser/permissions/permission_manager_factory.cc deleted file mode 100644 index 5059205..0000000 --- a/weblayer/browser/permissions/permission_manager_factory.cc +++ /dev/null
@@ -1,174 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/permissions/permission_manager_factory.h" - -#include "base/no_destructor.h" -#include "build/build_config.h" -#include "components/background_sync/background_sync_permission_context.h" -#include "components/content_settings/core/common/content_settings_types.h" -#include "components/embedder_support/permission_context_utils.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/permissions/permission_context_base.h" -#include "components/permissions/permission_manager.h" -#include "components/permissions/permission_util.h" -#include "components/webrtc/media_stream_device_enumerator_impl.h" -#include "third_party/blink/public/common/permissions/permission_utils.h" -#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h" -#include "weblayer/browser/background_fetch/background_fetch_permission_context.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/permissions/geolocation_permission_context_delegate.h" -#include "weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.h" -#include "weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.h" - -namespace weblayer { -namespace { - -// Permission context which denies all requests. -class DeniedPermissionContext : public permissions::PermissionContextBase { - public: - using PermissionContextBase::PermissionContextBase; - - protected: - ContentSetting GetPermissionStatusInternal( - content::RenderFrameHost* render_frame_host, - const GURL& requesting_origin, - const GURL& embedding_origin) const override { - return CONTENT_SETTING_BLOCK; - } -}; - -// A permission context with default behavior, which is restricted to secure -// origins. -class SafePermissionContext : public permissions::PermissionContextBase { - public: - using PermissionContextBase::PermissionContextBase; - SafePermissionContext(const SafePermissionContext&) = delete; - SafePermissionContext& operator=(const SafePermissionContext&) = delete; -}; - -// Used by the CameraPanTiltZoomPermissionContext to query which devices support -// that API. -// TODO(crbug.com/1219486): Move this elsewhere once we're using a custom -// implementation of MediaStreamDeviceEnumerator to expose this information to -// WebLayer embedders via an API. -webrtc::MediaStreamDeviceEnumerator* GetMediaStreamDeviceEnumerator() { - static base::NoDestructor<webrtc::MediaStreamDeviceEnumeratorImpl> instance; - return instance.get(); -} - -permissions::PermissionManager::PermissionContextMap CreatePermissionContexts( - content::BrowserContext* browser_context) { - embedder_support::PermissionContextDelegates delegates; - - delegates.camera_pan_tilt_zoom_permission_context_delegate = - std::make_unique<WebLayerCameraPanTiltZoomPermissionContextDelegate>(); - delegates.geolocation_permission_context_delegate = - std::make_unique<GeolocationPermissionContextDelegate>(); -#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS) - // TODO(crbug.com/1200933): macOS and ChromeOS uses - // GeolocationPermissionContextSystem which requires a GeolocationManager for - // construction. In Chrome this object is owned by the BrowserProcess. An - // equivalent object will need to be created in WebLayer and passed into the - // PermissionContextDelegates here before it supports macOS. - NOTREACHED(); -#endif // BUILDFLAG(IS_MAC) - delegates.media_stream_device_enumerator = GetMediaStreamDeviceEnumerator(); - delegates.nfc_permission_context_delegate = - std::make_unique<WebLayerNfcPermissionContextDelegate>(); - - // Create default permission contexts initially. - permissions::PermissionManager::PermissionContextMap permission_contexts = - embedder_support::CreateDefaultPermissionContexts( - browser_context, - /*is_regular_profile=*/false, std::move(delegates)); - - // Add additional WebLayer specific permission contexts. Please add a comment - // when adding new contexts here explaining why it can't be shared with other - // Content embedders by adding it to CreateDefaultPermissionContexts(). - - // Similar to the Chrome implementation except we don't have access to the - // DownloadRequestLimiter in WebLayer. - permission_contexts[ContentSettingsType::BACKGROUND_FETCH] = - std::make_unique<BackgroundFetchPermissionContext>(browser_context); - - // The Chrome implementation only checks for policies which we don't have in - // WebLayer. - permission_contexts[ContentSettingsType::MEDIASTREAM_CAMERA] = - std::make_unique<SafePermissionContext>( - browser_context, ContentSettingsType::MEDIASTREAM_CAMERA, - blink::mojom::PermissionsPolicyFeature::kCamera); - permission_contexts[ContentSettingsType::MEDIASTREAM_MIC] = - std::make_unique<SafePermissionContext>( - browser_context, ContentSettingsType::MEDIASTREAM_MIC, - blink::mojom::PermissionsPolicyFeature::kMicrophone); - -#if BUILDFLAG(IS_ANDROID) - // The Chrome implementation has special cases for Chrome OS and Windows which - // we don't support yet. On Android this will match Chrome's behaviour. - permission_contexts[ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER] = - std::make_unique<SafePermissionContext>( - browser_context, ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER, - blink::mojom::PermissionsPolicyFeature::kEncryptedMedia); -#endif - - // For now, all requests are denied. As features are added, their permission - // contexts can be added here instead of DeniedPermissionContext. - for (blink::PermissionType type : blink::GetAllPermissionTypes()) { -#if !BUILDFLAG(IS_ANDROID) - // PROTECTED_MEDIA_IDENTIFIER is only supported on Android. - if (type == blink::PermissionType::PROTECTED_MEDIA_IDENTIFIER) - continue; -#endif - ContentSettingsType content_settings_type = - permissions::PermissionUtil::PermissionTypeToContentSettingType(type); - if (permission_contexts.find(content_settings_type) == - permission_contexts.end()) { - permission_contexts[content_settings_type] = - std::make_unique<DeniedPermissionContext>( - browser_context, content_settings_type, - blink::mojom::PermissionsPolicyFeature::kNotFound); - } - } - - return permission_contexts; -} - -} // namespace - -// static -permissions::PermissionManager* PermissionManagerFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<permissions::PermissionManager*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -PermissionManagerFactory* PermissionManagerFactory::GetInstance() { - static base::NoDestructor<PermissionManagerFactory> factory; - return factory.get(); -} - -PermissionManagerFactory::PermissionManagerFactory() - : BrowserContextKeyedServiceFactory( - "PermissionManagerFactory", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -PermissionManagerFactory::~PermissionManagerFactory() = default; - -std::unique_ptr<KeyedService> -PermissionManagerFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<permissions::PermissionManager>( - context, CreatePermissionContexts(context)); -} - -content::BrowserContext* PermissionManagerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/permission_manager_factory.h b/weblayer/browser/permissions/permission_manager_factory.h deleted file mode 100644 index d2c44cccf..0000000 --- a/weblayer/browser/permissions/permission_manager_factory.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERMISSIONS_PERMISSION_MANAGER_FACTORY_H_ -#define WEBLAYER_BROWSER_PERMISSIONS_PERMISSION_MANAGER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace permissions { -class PermissionManager; -} - -namespace weblayer { - -class PermissionManagerFactory : public BrowserContextKeyedServiceFactory { - public: - PermissionManagerFactory(const PermissionManagerFactory&) = delete; - PermissionManagerFactory& operator=(const PermissionManagerFactory&) = delete; - - static permissions::PermissionManager* GetForBrowserContext( - content::BrowserContext* browser_context); - static PermissionManagerFactory* GetInstance(); - - private: - friend class base::NoDestructor<PermissionManagerFactory>; - - PermissionManagerFactory(); - ~PermissionManagerFactory() override; - - // BrowserContextKeyedServiceFactory methods: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERMISSIONS_PERMISSION_MANAGER_FACTORY_H_
diff --git a/weblayer/browser/permissions/permissions_browsertest.cc b/weblayer/browser/permissions/permissions_browsertest.cc deleted file mode 100644 index 4d2f2d87..0000000 --- a/weblayer/browser/permissions/permissions_browsertest.cc +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/permissions/permissions_client.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -class PermissionsBrowserTest : public WebLayerBrowserTest { - public: - void SetUpOnMainThread() override { - ASSERT_TRUE(embedded_test_server()->Start()); - } - - protected: - content::WebContents* GetWebContents() { - Tab* tab = shell()->tab(); - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - return tab_impl->web_contents(); - } - - GURL GetCurrentDisplayURL() { - auto* navigation_controller = shell()->tab()->GetNavigationController(); - return navigation_controller->GetNavigationEntryDisplayURL( - navigation_controller->GetNavigationListCurrentIndex()); - } -}; - -IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest, SubresourceFilterActivation) { - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - EXPECT_FALSE( - permissions::PermissionsClient::Get()->IsSubresourceFilterActivated( - GetWebContents()->GetBrowserContext(), GetCurrentDisplayURL())); - - GURL test_url(embedded_test_server()->GetURL("/simple_page.html")); - ActivateSubresourceFilterInWebContentsForURL(GetWebContents(), test_url); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE( - permissions::PermissionsClient::Get()->IsSubresourceFilterActivated( - GetWebContents()->GetBrowserContext(), GetCurrentDisplayURL())); -} - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.cc b/weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.cc deleted file mode 100644 index bd5a510..0000000 --- a/weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.h" - -#include "build/build_config.h" - -namespace weblayer { - -WebLayerCameraPanTiltZoomPermissionContextDelegate:: - WebLayerCameraPanTiltZoomPermissionContextDelegate() = default; - -WebLayerCameraPanTiltZoomPermissionContextDelegate:: - ~WebLayerCameraPanTiltZoomPermissionContextDelegate() = default; - -bool WebLayerCameraPanTiltZoomPermissionContextDelegate:: - GetPermissionStatusInternal(const GURL& requesting_origin, - const GURL& embedding_origin, - ContentSetting* content_setting_result) { -#if BUILDFLAG(IS_ANDROID) - // The PTZ permission is automatically granted on Android. It is safe to do so - // because pan and tilt are not supported on Android. - *content_setting_result = CONTENT_SETTING_ALLOW; - return true; -#else - return false; -#endif -} - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.h b/weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.h deleted file mode 100644 index 0820644..0000000 --- a/weblayer/browser/permissions/weblayer_camera_pan_tilt_zoom_permission_context_delegate.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_CAMERA_PAN_TILT_ZOOM_PERMISSION_CONTEXT_DELEGATE_H_ -#define WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_CAMERA_PAN_TILT_ZOOM_PERMISSION_CONTEXT_DELEGATE_H_ - -#include "components/permissions/contexts/camera_pan_tilt_zoom_permission_context.h" - -namespace weblayer { - -class WebLayerCameraPanTiltZoomPermissionContextDelegate - : public permissions::CameraPanTiltZoomPermissionContext::Delegate { - public: - WebLayerCameraPanTiltZoomPermissionContextDelegate(); - - WebLayerCameraPanTiltZoomPermissionContextDelegate( - const WebLayerCameraPanTiltZoomPermissionContextDelegate&) = delete; - WebLayerCameraPanTiltZoomPermissionContextDelegate& operator=( - const WebLayerCameraPanTiltZoomPermissionContextDelegate&) = delete; - - ~WebLayerCameraPanTiltZoomPermissionContextDelegate() override; - - // CameraPanTiltZoomPermissionContext::Delegate: - bool GetPermissionStatusInternal( - const GURL& requesting_origin, - const GURL& embedding_origin, - ContentSetting* content_setting_result) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_CAMERA_PAN_TILT_ZOOM_PERMISSION_CONTEXT_DELEGATE_H_ \ No newline at end of file
diff --git a/weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.cc b/weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.cc deleted file mode 100644 index e689fb8..0000000 --- a/weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.cc +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.h" - -#include "build/build_config.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/tab_impl.h" -#endif - -namespace weblayer { - -WebLayerNfcPermissionContextDelegate::WebLayerNfcPermissionContextDelegate() = - default; - -WebLayerNfcPermissionContextDelegate::~WebLayerNfcPermissionContextDelegate() = - default; - -#if BUILDFLAG(IS_ANDROID) -bool WebLayerNfcPermissionContextDelegate::IsInteractable( - content::WebContents* web_contents) { - auto* tab = TabImpl::FromWebContents(web_contents); - return tab && tab->IsActive(); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.h b/weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.h deleted file mode 100644 index 5c36a7c..0000000 --- a/weblayer/browser/permissions/weblayer_nfc_permission_context_delegate.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_NFC_PERMISSION_CONTEXT_DELEGATE_H_ -#define WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_NFC_PERMISSION_CONTEXT_DELEGATE_H_ - -#include "build/build_config.h" -#include "components/permissions/contexts/nfc_permission_context.h" - -namespace weblayer { - -class WebLayerNfcPermissionContextDelegate - : public permissions::NfcPermissionContext::Delegate { - public: - WebLayerNfcPermissionContextDelegate(); - - WebLayerNfcPermissionContextDelegate( - const WebLayerNfcPermissionContextDelegate&) = delete; - WebLayerNfcPermissionContextDelegate& operator=( - const WebLayerNfcPermissionContextDelegate&) = delete; - - ~WebLayerNfcPermissionContextDelegate() override; - - // NfcPermissionContext::Delegate: -#if BUILDFLAG(IS_ANDROID) - bool IsInteractable(content::WebContents* web_contents) override; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_NFC_PERMISSION_CONTEXT_DELEGATE_H_ \ No newline at end of file
diff --git a/weblayer/browser/permissions/weblayer_permissions_client.cc b/weblayer/browser/permissions/weblayer_permissions_client.cc deleted file mode 100644 index ea03e62..0000000 --- a/weblayer/browser/permissions/weblayer_permissions_client.cc +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/permissions/weblayer_permissions_client.h" - -#include "base/no_destructor.h" -#include "build/build_config.h" -#include "components/content_settings/core/browser/cookie_settings.h" -#include "components/subresource_filter/content/browser/subresource_filter_content_settings_manager.h" -#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h" -#include "weblayer/browser/cookie_settings_factory.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/permissions/origin_keyed_permission_action_service_factory.h" -#include "weblayer/browser/permissions/permission_decision_auto_blocker_factory.h" -#include "weblayer/browser/subresource_filter_profile_context_factory.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/browser/android/permission_request_utils.h" -#include "weblayer/browser/android/resource_mapper.h" -#endif - -namespace weblayer { - -// static -WebLayerPermissionsClient* WebLayerPermissionsClient::GetInstance() { - static base::NoDestructor<WebLayerPermissionsClient> instance; - return instance.get(); -} - -HostContentSettingsMap* WebLayerPermissionsClient::GetSettingsMap( - content::BrowserContext* browser_context) { - return HostContentSettingsMapFactory::GetForBrowserContext(browser_context); -} - -scoped_refptr<content_settings::CookieSettings> -WebLayerPermissionsClient::GetCookieSettings( - content::BrowserContext* browser_context) { - return CookieSettingsFactory::GetForBrowserContext(browser_context); -} - -bool WebLayerPermissionsClient::IsSubresourceFilterActivated( - content::BrowserContext* browser_context, - const GURL& url) { - return SubresourceFilterProfileContextFactory::GetForBrowserContext( - browser_context) - ->settings_manager() - ->GetSiteActivationFromMetadata(url); -} - -permissions::OriginKeyedPermissionActionService* -WebLayerPermissionsClient::GetOriginKeyedPermissionActionService( - content::BrowserContext* browser_context) { - return OriginKeyedPermissionActionServiceFactory::GetForBrowserContext( - browser_context); -} - -permissions::PermissionDecisionAutoBlocker* -WebLayerPermissionsClient::GetPermissionDecisionAutoBlocker( - content::BrowserContext* browser_context) { - return PermissionDecisionAutoBlockerFactory::GetForBrowserContext( - browser_context); -} - -// PermissionActionsHistory would never be read in WebLayer, so it seems logical -// not to have the service at all. -permissions::PermissionActionsHistory* -WebLayerPermissionsClient::GetPermissionActionsHistory( - content::BrowserContext* browser_context) { - return nullptr; -} - -permissions::ObjectPermissionContextBase* -WebLayerPermissionsClient::GetChooserContext( - content::BrowserContext* browser_context, - ContentSettingsType type) { - return nullptr; -} - -#if BUILDFLAG(IS_ANDROID) -void WebLayerPermissionsClient::RepromptForAndroidPermissions( - content::WebContents* web_contents, - const std::vector<ContentSettingsType>& content_settings_types, - const std::vector<ContentSettingsType>& filtered_content_settings_types, - const std::vector<std::string>& required_permissions, - const std::vector<std::string>& optional_permissions, - PermissionsUpdatedCallback callback) { - RequestAndroidPermissions(web_contents, content_settings_types, - std::move(callback)); -} - -int WebLayerPermissionsClient::MapToJavaDrawableId(int resource_id) { - return weblayer::MapToJavaDrawableId(resource_id); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/permissions/weblayer_permissions_client.h b/weblayer/browser/permissions/weblayer_permissions_client.h deleted file mode 100644 index e5d7cab9..0000000 --- a/weblayer/browser/permissions/weblayer_permissions_client.h +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_PERMISSIONS_CLIENT_H_ -#define WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_PERMISSIONS_CLIENT_H_ - -#include "base/no_destructor.h" -#include "build/build_config.h" -#include "components/permissions/permissions_client.h" - -namespace weblayer { - -class WebLayerPermissionsClient : public permissions::PermissionsClient { - public: - WebLayerPermissionsClient(const WebLayerPermissionsClient&) = delete; - WebLayerPermissionsClient& operator=(const WebLayerPermissionsClient&) = - delete; - - static WebLayerPermissionsClient* GetInstance(); - - // PermissionsClient: - HostContentSettingsMap* GetSettingsMap( - content::BrowserContext* browser_context) override; - scoped_refptr<content_settings::CookieSettings> GetCookieSettings( - content::BrowserContext* browser_context) override; - bool IsSubresourceFilterActivated(content::BrowserContext* browser_context, - const GURL& url) override; - permissions::OriginKeyedPermissionActionService* - GetOriginKeyedPermissionActionService( - content::BrowserContext* browser_context) override; - permissions::PermissionActionsHistory* GetPermissionActionsHistory( - content::BrowserContext* browser_context) override; - permissions::PermissionDecisionAutoBlocker* GetPermissionDecisionAutoBlocker( - content::BrowserContext* browser_context) override; - permissions::ObjectPermissionContextBase* GetChooserContext( - content::BrowserContext* browser_context, - ContentSettingsType type) override; -#if BUILDFLAG(IS_ANDROID) - void RepromptForAndroidPermissions( - content::WebContents* web_contents, - const std::vector<ContentSettingsType>& content_settings_types, - const std::vector<ContentSettingsType>& filtered_content_settings_types, - const std::vector<std::string>& required_permissions, - const std::vector<std::string>& optional_permissions, - PermissionsUpdatedCallback callback) override; - int MapToJavaDrawableId(int resource_id) override; -#endif - - private: - friend base::NoDestructor<WebLayerPermissionsClient>; - - WebLayerPermissionsClient() = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERMISSIONS_WEBLAYER_PERMISSIONS_CLIENT_H_
diff --git a/weblayer/browser/persistence/browser_persistence_common.cc b/weblayer/browser/persistence/browser_persistence_common.cc deleted file mode 100644 index 7a19315..0000000 --- a/weblayer/browser/persistence/browser_persistence_common.cc +++ /dev/null
@@ -1,157 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/persistence/browser_persistence_common.h" - -#include "components/sessions/content/content_serialized_navigation_builder.h" -#include "components/sessions/content/session_tab_helper.h" -#include "components/sessions/core/session_command.h" -#include "components/sessions/core/session_service_commands.h" -#include "components/sessions/core/session_types.h" -#include "content/public/browser/browser_url_handler.h" -#include "content/public/browser/dom_storage_context.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/storage_partition.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" - -namespace weblayer { -namespace { - -void ProcessRestoreCommands( - BrowserImpl* browser, - const std::vector<std::unique_ptr<sessions::SessionWindow>>& windows) { - if (windows.empty() || windows[0]->tabs.empty()) - return; - - const bool had_tabs = !browser->GetTabs().empty(); - content::BrowserContext* browser_context = - browser->profile()->GetBrowserContext(); - for (int i = 0; i < static_cast<int>(windows[0]->tabs.size()); ++i) { - const sessions::SessionTab& session_tab = *(windows[0]->tabs[i]); - if (session_tab.navigations.empty()) - continue; - - // Associate sessionStorage (if any) to the restored tab. - scoped_refptr<content::SessionStorageNamespace> session_storage_namespace; - if (!session_tab.session_storage_persistent_id.empty()) { - session_storage_namespace = - browser_context->GetDefaultStoragePartition() - ->GetDOMStorageContext() - ->RecreateSessionStorage( - session_tab.session_storage_persistent_id); - } - - const int selected_navigation_index = - session_tab.normalized_navigation_index(); - - GURL restore_url = - session_tab.navigations[selected_navigation_index].virtual_url(); - content::SessionStorageNamespaceMap session_storage_namespace_map = - content::CreateMapWithDefaultSessionStorageNamespace( - browser_context, session_storage_namespace); - content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary( - &restore_url, browser_context); - content::WebContents::CreateParams create_params( - browser_context, - content::SiteInstance::ShouldAssignSiteForURL(restore_url) - ? content::SiteInstance::CreateForURL(browser_context, restore_url) - : nullptr); - create_params.initially_hidden = true; - create_params.desired_renderer_state = - content::WebContents::CreateParams::kNoRendererProcess; - create_params.last_active_time = session_tab.last_active_time; - std::unique_ptr<content::WebContents> web_contents = - content::WebContents::CreateWithSessionStorage( - create_params, session_storage_namespace_map); - std::vector<std::unique_ptr<content::NavigationEntry>> entries = - sessions::ContentSerializedNavigationBuilder::ToNavigationEntries( - session_tab.navigations, browser_context); - - blink::UserAgentOverride ua_override; - ua_override.ua_string_override = - session_tab.user_agent_override.ua_string_override; - ua_override.ua_metadata_override = blink::UserAgentMetadata::Demarshal( - session_tab.user_agent_override.opaque_ua_metadata_override); - web_contents->SetUserAgentOverride(ua_override, false); - web_contents->GetController().Restore( - selected_navigation_index, content::RestoreType::kRestored, &entries); - DCHECK(entries.empty()); - TabImpl* tab = browser->CreateTabForSessionRestore(std::move(web_contents), - session_tab.guid); - tab->SetData(session_tab.data); - - if (!had_tabs && i == (windows[0])->selected_tab_index) - browser->SetActiveTab(tab); - } - if (!had_tabs && !browser->GetTabs().empty() && !browser->GetActiveTab()) - browser->SetActiveTab(browser->GetTabs().back()); -} - -} // namespace - -void RestoreBrowserState( - BrowserImpl* browser, - std::vector<std::unique_ptr<sessions::SessionCommand>> commands) { - std::vector<std::unique_ptr<sessions::SessionWindow>> windows; - SessionID active_window_id = SessionID::InvalidValue(); - sessions::RestoreSessionFromCommands(commands, &windows, &active_window_id); - ProcessRestoreCommands(browser, windows); - - if (browser->GetTabs().empty()) { - // Nothing to restore, or restore failed. Create a default tab. - browser->SetActiveTab( - browser->CreateTabForSessionRestore(nullptr, std::string())); - } -} - -std::vector<std::unique_ptr<sessions::SessionCommand>> -BuildCommandsForTabConfiguration(SessionID browser_session_id, - TabImpl* tab, - int index_in_browser) { - DCHECK(tab); - std::vector<std::unique_ptr<sessions::SessionCommand>> result; - const SessionID tab_id = GetSessionIDForTab(tab); - result.push_back( - sessions::CreateSetTabWindowCommand(browser_session_id, tab_id)); - - result.push_back(sessions::CreateLastActiveTimeCommand( - tab_id, tab->web_contents()->GetLastActiveTime())); - - const blink::UserAgentOverride& ua_override = - tab->web_contents()->GetUserAgentOverride(); - if (!ua_override.ua_string_override.empty()) { - sessions::SerializedUserAgentOverride serialized_override; - serialized_override.ua_string_override = ua_override.ua_string_override; - serialized_override.opaque_ua_metadata_override = - blink::UserAgentMetadata::Marshal(ua_override.ua_metadata_override); - result.push_back(sessions::CreateSetTabUserAgentOverrideCommand( - tab_id, serialized_override)); - } - if (index_in_browser != -1) { - result.push_back( - sessions::CreateSetTabIndexInWindowCommand(tab_id, index_in_browser)); - } - - result.push_back(sessions::CreateSetSelectedNavigationIndexCommand( - tab_id, tab->web_contents()->GetController().GetCurrentEntryIndex())); - - result.push_back(sessions::CreateSetTabGuidCommand(tab_id, tab->GetGuid())); - - result.push_back(sessions::CreateSetTabDataCommand(tab_id, tab->GetData())); - - return result; -} - -SessionID GetSessionIDForTab(Tab* tab) { - sessions::SessionTabHelper* session_tab_helper = - sessions::SessionTabHelper::FromWebContents( - static_cast<TabImpl*>(tab)->web_contents()); - DCHECK(session_tab_helper); - return session_tab_helper->session_id(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/persistence/browser_persistence_common.h b/weblayer/browser/persistence/browser_persistence_common.h deleted file mode 100644 index 7f7978da6..0000000 --- a/weblayer/browser/persistence/browser_persistence_common.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTENCE_COMMON_H_ -#define WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTENCE_COMMON_H_ - -#include <memory> -#include <vector> - -class SessionID; - -namespace sessions { -class SessionCommand; -} - -// Common functions used in persisting/restoring the state (tabs, navigations) -// of a Browser. -namespace weblayer { - -class BrowserImpl; -class Tab; -class TabImpl; - -// Restores browser state from |commands|. This ensures |browser| contains at -// least one tab when done. -void RestoreBrowserState( - BrowserImpl* browser, - std::vector<std::unique_ptr<sessions::SessionCommand>> commands); - -// Creates and returns the minimal set of SessionCommands to configure a tab. -// This does not include any navigations. -std::vector<std::unique_ptr<sessions::SessionCommand>> -BuildCommandsForTabConfiguration(SessionID browser_session_id, - TabImpl* tab, - int index_in_browser); - -// Convenience to return the SessionID for a Tab. -SessionID GetSessionIDForTab(Tab* tab); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTENCE_COMMON_H_
diff --git a/weblayer/browser/persistence/browser_persister.cc b/weblayer/browser/persistence/browser_persister.cc deleted file mode 100644 index dcdd8a0..0000000 --- a/weblayer/browser/persistence/browser_persister.cc +++ /dev/null
@@ -1,360 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/persistence/browser_persister.h" - -#include <stddef.h> - -#include <utility> -#include <vector> - -#include "base/functional/bind.h" -#include "base/ranges/algorithm.h" -#include "components/sessions/content/content_serialized_navigation_builder.h" -#include "components/sessions/content/session_tab_helper.h" -#include "components/sessions/core/command_storage_manager.h" -#include "components/sessions/core/session_command.h" -#include "components/sessions/core/session_constants.h" -#include "components/sessions/core/session_id.h" -#include "components/sessions/core/session_types.h" -#include "content/public/browser/navigation_details.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/restore_type.h" -#include "content/public/browser/session_storage_namespace.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/persistence/browser_persistence_common.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" - -using sessions::ContentSerializedNavigationBuilder; -using sessions::SerializedNavigationEntry; - -namespace weblayer { -namespace { - -int GetIndexOfTab(BrowserImpl* browser, Tab* tab) { - const std::vector<Tab*>& tabs = browser->GetTabs(); - auto iter = base::ranges::find(tabs, tab); - DCHECK(iter != tabs.end()); - return static_cast<int>(iter - tabs.begin()); -} - -} // namespace - -// Every kWritesPerReset commands triggers recreating the file. -constexpr int kWritesPerReset = 250; - -// BrowserPersister -// ------------------------------------------------------------- - -BrowserPersister::BrowserPersister(const base::FilePath& path, - BrowserImpl* browser) - : browser_(browser), - browser_session_id_(SessionID::NewUnique()), - command_storage_manager_( - std::make_unique<sessions::CommandStorageManager>( - sessions::CommandStorageManager::kOther, - path, - this, - browser->profile()->GetBrowserContext()->IsOffTheRecord(), - std::vector<uint8_t>(0))), - rebuild_on_next_save_(false) { - browser_->AddObserver(this); - command_storage_manager_->GetLastSessionCommands(base::BindOnce( - &BrowserPersister::OnGotLastSessionCommands, weak_factory_.GetWeakPtr())); -} - -BrowserPersister::~BrowserPersister() { - SaveIfNecessary(); - browser_->RemoveObserver(this); -} - -void BrowserPersister::SaveIfNecessary() { - if (command_storage_manager_->HasPendingSave()) - command_storage_manager_->Save(); -} - -bool BrowserPersister::ShouldUseDelayedSave() { - return true; -} - -void BrowserPersister::OnWillSaveCommands() { - if (!rebuild_on_next_save_) - return; - - rebuild_on_next_save_ = false; - command_storage_manager_->set_pending_reset(true); - command_storage_manager_->ClearPendingCommands(); - tab_to_available_range_.clear(); - BuildCommandsForBrowser(); -} - -void BrowserPersister::OnErrorWritingSessionCommands() { - rebuild_on_next_save_ = true; - command_storage_manager_->StartSaveTimer(); -} - -void BrowserPersister::OnTabAdded(Tab* tab) { - auto* tab_impl = static_cast<TabImpl*>(tab); - data_observations_.AddObservation(tab_impl); - content::WebContents* web_contents = tab_impl->web_contents(); - auto* tab_helper = sessions::SessionTabHelper::FromWebContents(web_contents); - DCHECK(tab_helper); - tab_helper->SetWindowID(browser_session_id_); - - // Record the association between the SessionStorageNamespace and the - // tab. - content::SessionStorageNamespace* session_storage_namespace = - web_contents->GetController().GetDefaultSessionStorageNamespace(); - session_storage_namespace->SetShouldPersist(true); - - if (rebuild_on_next_save_) - return; - - int index = GetIndexOfTab(browser_, tab); - BuildCommandsForTab(static_cast<TabImpl*>(tab), index); - const std::vector<Tab*>& tabs = browser_->GetTabs(); - for (int i = index + 1; i < static_cast<int>(tabs.size()); ++i) { - ScheduleCommand(sessions::CreateSetTabIndexInWindowCommand( - GetSessionIDForTab(tabs[i]), i)); - } -} - -void BrowserPersister::OnTabRemoved(Tab* tab, bool active_tab_changed) { - auto* tab_impl = static_cast<TabImpl*>(tab); - data_observations_.RemoveObservation(tab_impl); - // Allow the associated sessionStorage to get deleted; it won't be needed - // in the session restore. - content::WebContents* web_contents = tab_impl->web_contents(); - content::SessionStorageNamespace* session_storage_namespace = - web_contents->GetController().GetDefaultSessionStorageNamespace(); - session_storage_namespace->SetShouldPersist(false); - - if (rebuild_on_next_save_) - return; - - ScheduleCommand(sessions::CreateTabClosedCommand(GetSessionIDForTab(tab))); - const std::vector<Tab*>& tabs = browser_->GetTabs(); - for (size_t i = 0; i < tabs.size(); ++i) { - ScheduleCommand(sessions::CreateSetTabIndexInWindowCommand( - GetSessionIDForTab(tabs[i]), i)); - } - auto i = tab_to_available_range_.find(GetSessionIDForTab(tab)); - if (i != tab_to_available_range_.end()) - tab_to_available_range_.erase(i); -} - -void BrowserPersister::OnActiveTabChanged(Tab* tab) { - if (rebuild_on_next_save_) - return; - - const int index = tab == nullptr ? -1 : GetIndexOfTab(browser_, tab); - ScheduleCommand(sessions::CreateSetSelectedTabInWindowCommand( - browser_session_id_, index)); -} - -void BrowserPersister::OnDataChanged( - TabImpl* tab, - const std::map<std::string, std::string>& data) { - if (rebuild_on_next_save_) - return; - - ScheduleCommand( - sessions::CreateSetTabDataCommand(GetSessionIDForTab(tab), data)); -} - -void BrowserPersister::SetTabUserAgentOverride( - SessionID window_id, - SessionID tab_id, - const sessions::SerializedUserAgentOverride& user_agent_override) { - if (rebuild_on_next_save_) - return; - - ScheduleCommand(sessions::CreateSetTabUserAgentOverrideCommand( - tab_id, user_agent_override)); -} - -void BrowserPersister::SetSelectedNavigationIndex(SessionID window_id, - SessionID tab_id, - int index) { - if (rebuild_on_next_save_) - return; - - if (tab_to_available_range_.find(tab_id) != tab_to_available_range_.end()) { - if (index < tab_to_available_range_[tab_id].first || - index > tab_to_available_range_[tab_id].second) { - // The new index is outside the range of what we've archived, schedule - // a reset. - ScheduleRebuildOnNextSave(); - return; - } - } - ScheduleCommand( - sessions::CreateSetSelectedNavigationIndexCommand(tab_id, index)); -} - -void BrowserPersister::UpdateTabNavigation( - SessionID window_id, - SessionID tab_id, - const SerializedNavigationEntry& navigation) { - if (rebuild_on_next_save_) - return; - - if (tab_to_available_range_.find(tab_id) != tab_to_available_range_.end()) { - std::pair<int, int>& range = tab_to_available_range_[tab_id]; - range.first = std::min(navigation.index(), range.first); - range.second = std::max(navigation.index(), range.second); - } - ScheduleCommand(CreateUpdateTabNavigationCommand(tab_id, navigation)); -} - -void BrowserPersister::TabNavigationPathPruned(SessionID window_id, - SessionID tab_id, - int index, - int count) { - if (rebuild_on_next_save_) - return; - - DCHECK_GE(index, 0); - DCHECK_GT(count, 0); - - // Update the range of available indices. - if (tab_to_available_range_.find(tab_id) != tab_to_available_range_.end()) { - std::pair<int, int>& range = tab_to_available_range_[tab_id]; - - // if both range.first and range.second are also deleted. - if (range.second >= index && range.second < index + count && - range.first >= index && range.first < index + count) { - range.first = range.second = 0; - } else { - // Update range.first - if (range.first >= index + count) - range.first = range.first - count; - else if (range.first >= index && range.first < index + count) - range.first = index; - - // Update range.second - if (range.second >= index + count) - range.second = std::max(range.first, range.second - count); - else if (range.second >= index && range.second < index + count) - range.second = std::max(range.first, index - 1); - } - } - - return ScheduleCommand( - sessions::CreateTabNavigationPathPrunedCommand(tab_id, index, count)); -} - -void BrowserPersister::TabNavigationPathEntriesDeleted(SessionID window_id, - SessionID tab_id) { - if (rebuild_on_next_save_) - return; - - // Multiple tabs might be affected by this deletion, so the rebuild is - // delayed until next save. - rebuild_on_next_save_ = true; - command_storage_manager_->StartSaveTimer(); -} - -void BrowserPersister::ScheduleRebuildOnNextSave() { - rebuild_on_next_save_ = true; - command_storage_manager_->StartSaveTimer(); -} - -void BrowserPersister::OnGotLastSessionCommands( - std::vector<std::unique_ptr<sessions::SessionCommand>> commands, - bool read_error) { - ScheduleRebuildOnNextSave(); - - RestoreBrowserState(browser_, std::move(commands)); - - is_restore_in_progress_ = false; - browser_->OnRestoreCompleted(); -} - -void BrowserPersister::BuildCommandsForTab(TabImpl* tab, int index_in_browser) { - command_storage_manager_->AppendRebuildCommands( - BuildCommandsForTabConfiguration(browser_session_id_, tab, - index_in_browser)); - - const SessionID session_id = GetSessionIDForTab(tab); - content::NavigationController& controller = - tab->web_contents()->GetController(); - // Ensure that we don't try to persist initial NavigationEntry, as it is - // not actually associated with any navigation and will just result in - // about:blank on session restore. - bool is_on_initial_entry = (tab->web_contents() - ->GetController() - .GetLastCommittedEntry() - ->IsInitialEntry()); - const int current_index = - is_on_initial_entry ? -1 : controller.GetCurrentEntryIndex(); - const int min_index = - std::max(current_index - sessions::gMaxPersistNavigationCount, 0); - const int max_index = - std::min(current_index + sessions::gMaxPersistNavigationCount, - controller.GetEntryCount()); - const int pending_index = controller.GetPendingEntryIndex(); - tab_to_available_range_[session_id] = - std::pair<int, int>(min_index, max_index); - - for (int i = min_index; i < max_index; ++i) { - content::NavigationEntry* entry = (i == pending_index) - ? controller.GetPendingEntry() - : controller.GetEntryAtIndex(i); - DCHECK(entry); - if (entry->IsInitialEntry()) - continue; - const SerializedNavigationEntry navigation = - ContentSerializedNavigationBuilder::FromNavigationEntry(i, entry); - command_storage_manager_->AppendRebuildCommand( - CreateUpdateTabNavigationCommand(session_id, navigation)); - } - command_storage_manager_->AppendRebuildCommand( - sessions::CreateSetSelectedNavigationIndexCommand(session_id, - current_index)); - - // Record the association between the sessionStorage namespace and the tab. - content::SessionStorageNamespace* session_storage_namespace = - controller.GetDefaultSessionStorageNamespace(); - ScheduleCommand(sessions::CreateSessionStorageAssociatedCommand( - session_id, session_storage_namespace->id())); -} - -void BrowserPersister::BuildCommandsForBrowser() { - // This is necessary for BrowserPersister to restore the browser. The type is - // effectively ignored. - command_storage_manager_->AppendRebuildCommand( - sessions::CreateSetWindowTypeCommand( - browser_session_id_, - sessions::SessionWindow::WindowType::TYPE_NORMAL)); - - int active_index = -1; - int tab_index = 0; - for (Tab* tab : browser_->GetTabs()) { - BuildCommandsForTab(static_cast<TabImpl*>(tab), tab_index); - if (tab == browser_->GetActiveTab()) - active_index = tab_index; - ++tab_index; - } - - command_storage_manager_->AppendRebuildCommand( - sessions::CreateSetSelectedTabInWindowCommand(browser_session_id_, - active_index)); -} - -void BrowserPersister::ScheduleCommand( - std::unique_ptr<sessions::SessionCommand> command) { - DCHECK(command); - if (ReplacePendingCommand(command_storage_manager_.get(), &command)) - return; - command_storage_manager_->ScheduleCommand(std::move(command)); - if (command_storage_manager_->commands_since_reset() >= kWritesPerReset) - ScheduleRebuildOnNextSave(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/persistence/browser_persister.h b/weblayer/browser/persistence/browser_persister.h deleted file mode 100644 index 38c072b..0000000 --- a/weblayer/browser/persistence/browser_persister.h +++ /dev/null
@@ -1,142 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_H_ -#define WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_H_ - -#include <stddef.h> - -#include <map> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/scoped_multi_source_observation.h" -#include "components/sessions/content/session_tab_helper_delegate.h" -#include "components/sessions/core/command_storage_manager_delegate.h" -#include "components/sessions/core/session_service_commands.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/browser_observer.h" - -class SessionID; - -namespace sessions { -class SessionCommand; -} - -namespace weblayer { - -class BrowserImpl; - -// BrowserPersister is responsible for maintaining the state of tabs in a -// single Browser so that they can be restored at a later date. The state is -// written to a file. To avoid having to write the complete state anytime -// something changes interesting events (represented as SessionCommands) are -// written to disk. To restore, the events are read back and the state -// recreated. At certain times the file is truncated and rebuilt from the -// current state. -class BrowserPersister : public sessions::CommandStorageManagerDelegate, - public sessions::SessionTabHelperDelegate, - public BrowserObserver, - public TabImpl::DataObserver { - public: - BrowserPersister(const base::FilePath& path, BrowserImpl* browser); - - BrowserPersister(const BrowserPersister&) = delete; - BrowserPersister& operator=(const BrowserPersister&) = delete; - - ~BrowserPersister() override; - - bool is_restore_in_progress() const { return is_restore_in_progress_; } - - void SaveIfNecessary(); - - private: - friend class BrowserPersisterTestHelper; - - using IdToRange = std::map<SessionID, std::pair<int, int>>; - - // CommandStorageManagerDelegate: - bool ShouldUseDelayedSave() override; - void OnWillSaveCommands() override; - void OnErrorWritingSessionCommands() override; - - // BrowserObserver; - void OnTabAdded(Tab* tab) override; - void OnTabRemoved(Tab* tab, bool active_tab_changed) override; - void OnActiveTabChanged(Tab* tab) override; - - // TabImpl::DataObserver: - void OnDataChanged(TabImpl* tab, - const std::map<std::string, std::string>& data) override; - - // sessions::SessionTabHelperDelegate: - void SetTabUserAgentOverride(SessionID window_id, - SessionID tab_id, - const sessions::SerializedUserAgentOverride& - user_agent_override) override; - void SetSelectedNavigationIndex(SessionID window_id, - SessionID tab_id, - int index) override; - void UpdateTabNavigation( - SessionID window_id, - SessionID tab_id, - const sessions::SerializedNavigationEntry& navigation) override; - void TabNavigationPathPruned(SessionID window_id, - SessionID tab_id, - int index, - int count) override; - void TabNavigationPathEntriesDeleted(SessionID window_id, - SessionID tab_id) override; - - // Schedules recreating the file on the next save. - void ScheduleRebuildOnNextSave(); - - // Called with the contents of the previous session. - void OnGotLastSessionCommands( - std::vector<std::unique_ptr<sessions::SessionCommand>> commands, - bool read_error); - - // Schedules commands to recreate the state of the specified tab. - void BuildCommandsForTab(TabImpl* tab, int index_in_window); - - // Schedules commands to recreate the state of |browser_|. - void BuildCommandsForBrowser(); - - // Schedules the specified command. - void ScheduleCommand(std::unique_ptr<sessions::SessionCommand> command); - - void ProcessRestoreCommands( - const std::vector<std::unique_ptr<sessions::SessionWindow>>& windows); - - raw_ptr<BrowserImpl> browser_; - - // ID used for the browser. The sessions code requires each tab to be - // associated with a browser. - const SessionID browser_session_id_; - - std::unique_ptr<sessions::CommandStorageManager> command_storage_manager_; - - // Maps from session tab id to the range of navigation entries that has - // been written to disk. - IdToRange tab_to_available_range_; - - // Force session commands to be rebuild before next save event. - bool rebuild_on_next_save_; - - base::ScopedMultiSourceObservation<TabImpl, TabImpl::DataObserver> - data_observations_{this}; - - // True while asynchronously reading the state to restore. - bool is_restore_in_progress_ = true; - - base::WeakPtrFactory<BrowserPersister> weak_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_H_
diff --git a/weblayer/browser/persistence/browser_persister_browsertest.cc b/weblayer/browser/persistence/browser_persister_browsertest.cc deleted file mode 100644 index c7a1028..0000000 --- a/weblayer/browser/persistence/browser_persister_browsertest.cc +++ /dev/null
@@ -1,454 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/persistence/browser_persister.h" - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/functional/callback_helpers.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/raw_ref.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/test/bind.h" -#include "base/threading/thread_restrictions.h" -#include "base/uuid.h" -#include "build/build_config.h" -#include "components/sessions/core/command_storage_backend.h" -#include "components/sessions/core/command_storage_manager_test_helper.h" -#include "components/sessions/core/session_constants.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/url_loader_interceptor.h" -#include "net/base/filename_util.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/persistence/browser_persister_file_utils.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/common/weblayer_paths.h" -#include "weblayer/public/browser_restore_observer.h" -#include "weblayer/public/navigation.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/navigation_observer.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/interstitial_utils.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -class BrowserPersisterTestHelper { - public: - static sessions::CommandStorageManager* GetCommandStorageManager( - BrowserPersister* persister) { - return persister->command_storage_manager_.get(); - } -}; - -namespace { -using testing::UnorderedElementsAre; - -class BrowserNavigationObserverImpl : public BrowserRestoreObserver, - public NavigationObserver { - public: - static void WaitForNewTabToCompleteNavigation(Browser* browser, - const GURL& url, - size_t tab_to_wait_for = 0) { - BrowserNavigationObserverImpl observer(browser, url, tab_to_wait_for); - observer.Wait(); - } - - private: - BrowserNavigationObserverImpl(Browser* browser, - const GURL& url, - size_t tab_to_wait_for) - : browser_(browser), url_(url), tab_to_wait_for_(tab_to_wait_for) { - browser_->AddBrowserRestoreObserver(this); - } - ~BrowserNavigationObserverImpl() override { - tab_->GetNavigationController()->RemoveObserver(this); - } - - void Wait() { run_loop_.Run(); } - - // NavigationObserver; - void NavigationCompleted(Navigation* navigation) override { - if (navigation->GetURL() == *url_) - run_loop_.Quit(); - } - - // BrowserRestoreObserver: - void OnRestoreCompleted() override { - browser_->RemoveBrowserRestoreObserver(this); - ASSERT_LT(tab_to_wait_for_, browser_->GetTabs().size()); - ASSERT_EQ(nullptr, tab_.get()); - tab_ = browser_->GetTabs()[tab_to_wait_for_]; - tab_->GetNavigationController()->AddObserver(this); - } - - raw_ptr<Browser> browser_; - const raw_ref<const GURL> url_; - raw_ptr<Tab> tab_ = nullptr; - const size_t tab_to_wait_for_; - std::unique_ptr<TestNavigationObserver> navigation_observer_; - base::RunLoop run_loop_; -}; - -void ShutdownBrowserPersisterAndWait(BrowserImpl* browser) { - auto task_runner = sessions::CommandStorageManagerTestHelper( - BrowserPersisterTestHelper::GetCommandStorageManager( - browser->browser_persister())) - .GetBackendTaskRunner(); - browser->PrepareForShutdown(); - base::RunLoop run_loop; - task_runner->PostTaskAndReply(FROM_HERE, base::DoNothing(), - run_loop.QuitClosure()); - run_loop.Run(); -} - -std::unique_ptr<BrowserImpl> CreateBrowser(ProfileImpl* profile, - const std::string& persistence_id) { - Browser::PersistenceInfo info; - info.id = persistence_id; - auto browser = Browser::Create(profile, &info); - return std::unique_ptr<BrowserImpl>( - static_cast<BrowserImpl*>(browser.release())); -} - -} // namespace - -using BrowserPersisterTest = WebLayerBrowserTest; - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, SingleTab) { - ASSERT_TRUE(embedded_test_server()->Start()); - - std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x"); - Tab* tab = browser->CreateTab(); - EXPECT_TRUE(browser->IsRestoringPreviousState()); - const GURL url = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url, tab); - ShutdownBrowserPersisterAndWait(browser.get()); - tab = nullptr; - browser.reset(); - - browser = CreateBrowser(GetProfile(), "x"); - // Should be no tabs while waiting for restore. - EXPECT_TRUE(browser->GetTabs().empty()); - EXPECT_TRUE(browser->IsRestoringPreviousState()); - // Wait for the restore and navigation to complete. - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser.get(), url); - - ASSERT_EQ(1u, browser->GetTabs().size()); - EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab()); - EXPECT_EQ(1, browser->GetTabs()[0] - ->GetNavigationController() - ->GetNavigationListSize()); - EXPECT_FALSE(browser->IsRestoringPreviousState()); -} - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, RestoresGuid) { - ASSERT_TRUE(embedded_test_server()->Start()); - - std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x"); - Tab* tab = browser->CreateTab(); - const std::string original_guid = tab->GetGuid(); - EXPECT_FALSE(original_guid.empty()); - EXPECT_TRUE(base::Uuid::ParseCaseInsensitive(original_guid).is_valid()); - const GURL url = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url, tab); - ShutdownBrowserPersisterAndWait(browser.get()); - tab = nullptr; - browser.reset(); - - browser = CreateBrowser(GetProfile(), "x"); - // Should be no tabs while waiting for restore. - EXPECT_TRUE(browser->GetTabs().empty()); - // Wait for the restore and navigation to complete. - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser.get(), url); - - ASSERT_EQ(1u, browser->GetTabs().size()); - EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab()); - EXPECT_EQ(original_guid, browser->GetTabs()[0]->GetGuid()); -} - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, RestoresData) { - ASSERT_TRUE(embedded_test_server()->Start()); - - std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x"); - Tab* tab = browser->CreateTab(); - tab->SetData({{"abc", "efg"}}); - const GURL url = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url, tab); - ShutdownBrowserPersisterAndWait(browser.get()); - tab = nullptr; - browser.reset(); - - browser = CreateBrowser(GetProfile(), "x"); - // Should be no tabs while waiting for restore. - EXPECT_TRUE(browser->GetTabs().empty()); - // Wait for the restore and navigation to complete. - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser.get(), url); - - ASSERT_EQ(1u, browser->GetTabs().size()); - EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab()); - EXPECT_THAT(browser->GetTabs()[0]->GetData(), - UnorderedElementsAre(std::make_pair("abc", "efg"))); -} - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, RestoresMostRecentData) { - ASSERT_TRUE(embedded_test_server()->Start()); - - std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x"); - Tab* tab = browser->CreateTab(); - tab->SetData({{"xxx", "xxx"}}); - const GURL url = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url, tab); - - // Make sure the data has been saved, then set different data on the tab. - BrowserPersisterTestHelper::GetCommandStorageManager( - browser->browser_persister()) - ->Save(); - tab->SetData({{"abc", "efg"}}); - - ShutdownBrowserPersisterAndWait(browser.get()); - tab = nullptr; - browser.reset(); - - browser = CreateBrowser(GetProfile(), "x"); - // Should be no tabs while waiting for restore. - EXPECT_TRUE(browser->GetTabs().empty()); - // Wait for the restore and navigation to complete. - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser.get(), url); - - ASSERT_EQ(1u, browser->GetTabs().size()); - EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab()); - EXPECT_THAT(browser->GetTabs()[0]->GetData(), - UnorderedElementsAre(std::make_pair("abc", "efg"))); -} - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, TwoTabs) { - ASSERT_TRUE(embedded_test_server()->Start()); - - std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x"); - Tab* tab1 = browser->CreateTab(); - const GURL url1 = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url1, tab1); - - Tab* tab2 = browser->CreateTab(); - const GURL url2 = embedded_test_server()->GetURL("/simple_page2.html"); - NavigateAndWaitForCompletion(url2, tab2); - browser->SetActiveTab(tab2); - - // Shut down the service. - ShutdownBrowserPersisterAndWait(browser.get()); - tab1 = tab2 = nullptr; - browser.reset(); - - // Recreate the browser and run the assertions twice to ensure we handle - // correctly storing state of tabs that need to be reloaded. - for (int i = 0; i < 2; ++i) { - browser = CreateBrowser(GetProfile(), "x"); - // Should be no tabs while waiting for restore. - EXPECT_TRUE(browser->GetTabs().empty()) << "iteration " << i; - // Wait for the restore and navigation to complete. This waits for the - // second tab as that was the active one. - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser.get(), url2, 1); - - ASSERT_EQ(2u, browser->GetTabs().size()) << "iteration " << i; - // The first tab shouldn't have loaded yet, as it's not active. - EXPECT_TRUE(static_cast<TabImpl*>(browser->GetTabs()[0]) - ->web_contents() - ->GetController() - .NeedsReload()) - << "iteration " << i; - EXPECT_EQ(browser->GetTabs()[1], browser->GetActiveTab()) - << "iteration " << i; - EXPECT_EQ(1, browser->GetTabs()[1] - ->GetNavigationController() - ->GetNavigationListSize()) - << "iteration " << i; - - ShutdownBrowserPersisterAndWait(browser.get()); - } -} - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, MoveBetweenBrowsers) { - ASSERT_TRUE(embedded_test_server()->Start()); - - // Create a browser with two tabs. - std::unique_ptr<BrowserImpl> browser1 = CreateBrowser(GetProfile(), "x"); - Tab* tab1 = browser1->CreateTab(); - const GURL url1 = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url1, tab1); - - Tab* tab2 = browser1->CreateTab(); - const GURL url2 = embedded_test_server()->GetURL("/simple_page2.html"); - NavigateAndWaitForCompletion(url2, tab2); - browser1->SetActiveTab(tab2); - - // Create another browser with a single tab. - std::unique_ptr<BrowserImpl> browser2 = CreateBrowser(GetProfile(), "y"); - Tab* tab3 = browser2->CreateTab(); - const GURL url3 = embedded_test_server()->GetURL("/simple_page3.html"); - NavigateAndWaitForCompletion(url3, tab3); - - // Move |tab2| to |browser2|. - browser2->AddTab(tab2); - browser2->SetActiveTab(tab2); - - ShutdownBrowserPersisterAndWait(browser1.get()); - ShutdownBrowserPersisterAndWait(browser2.get()); - tab1 = nullptr; - browser1.reset(); - - tab2 = tab3 = nullptr; - browser2.reset(); - - // Restore the browsers. - browser1 = CreateBrowser(GetProfile(), "x"); - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser1.get(), url1); - ASSERT_EQ(1u, browser1->GetTabs().size()); - EXPECT_EQ(1, browser1->GetTabs()[0] - ->GetNavigationController() - ->GetNavigationListSize()); - - browser2 = CreateBrowser(GetProfile(), "y"); - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser2.get(), url2, 1); - ASSERT_EQ(2u, browser2->GetTabs().size()); - EXPECT_EQ(1, browser2->GetTabs()[1] - ->GetNavigationController() - ->GetNavigationListSize()); - - // As |tab3| isn't active it needs to be loaded. Force that now. - TabImpl* restored_tab_3 = static_cast<TabImpl*>(browser2->GetTabs()[0]); - EXPECT_TRUE(restored_tab_3->web_contents()->GetController().NeedsReload()); - restored_tab_3->web_contents()->GetController().LoadIfNecessary(); - EXPECT_TRUE(content::WaitForLoadStop(restored_tab_3->web_contents())); -} - -class BrowserPersisterTestWithTwoPersistedIds : public WebLayerBrowserTest { - public: - // WebLayerBrowserTest: - void SetUpOnMainThread() override { - WebLayerBrowserTest::SetUpOnMainThread(); - // Configure two browsers with ids 'x' and 'y'. - ASSERT_TRUE(embedded_test_server()->Start()); - std::unique_ptr<BrowserImpl> browser1 = CreateBrowser(GetProfile(), "x"); - const GURL url1 = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url1, browser1->CreateTab()); - - std::unique_ptr<BrowserImpl> browser2 = CreateBrowser(GetProfile(), "y"); - const GURL url2 = embedded_test_server()->GetURL("/simple_page3.html"); - NavigateAndWaitForCompletion(url2, browser2->CreateTab()); - - // Shut down the browsers. - ShutdownBrowserPersisterAndWait(browser1.get()); - browser1.reset(); - ShutdownBrowserPersisterAndWait(browser2.get()); - browser2.reset(); - } -}; - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTestWithTwoPersistedIds, - GetBrowserPersistenceIds) { - { - // Create a file that has the name of a valid persistence file, but has - // invalid contents. - base::ScopedAllowBlockingForTesting allow_blocking; - base::WriteFile(BuildBasePathForBrowserPersister( - GetProfile()->GetBrowserPersisterDataBaseDir(), "z"), - "a bogus persistence file"); - } - - base::RunLoop run_loop; - base::flat_set<std::string> persistence_ids; - GetProfile()->GetBrowserPersistenceIds( - base::BindLambdaForTesting([&](base::flat_set<std::string> ids) { - persistence_ids = std::move(ids); - run_loop.Quit(); - })); - run_loop.Run(); - ASSERT_EQ(2u, persistence_ids.size()); - EXPECT_TRUE(persistence_ids.contains("x")); - EXPECT_TRUE(persistence_ids.contains("y")); -} - -bool HasSessionFileStartingWith(const base::FilePath& path) { - auto paths = sessions::CommandStorageBackend::GetSessionFilePaths( - path, sessions::CommandStorageManager::kOther); - return paths.size() == 1; -} - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTestWithTwoPersistedIds, - RemoveBrowserPersistenceStorage) { - base::FilePath file_path1 = BuildBasePathForBrowserPersister( - GetProfile()->GetBrowserPersisterDataBaseDir(), "x"); - base::FilePath file_path2 = BuildBasePathForBrowserPersister( - GetProfile()->GetBrowserPersisterDataBaseDir(), "y"); - - { - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(HasSessionFileStartingWith(file_path1)); - ASSERT_TRUE(HasSessionFileStartingWith(file_path2)); - } - base::RunLoop run_loop; - base::flat_set<std::string> persistence_ids; - persistence_ids.insert("x"); - persistence_ids.insert("y"); - GetProfile()->RemoveBrowserPersistenceStorage( - base::BindLambdaForTesting([&](bool result) { - EXPECT_TRUE(result); - run_loop.Quit(); - }), - std::move(persistence_ids)); - run_loop.Run(); - { - base::ScopedAllowBlockingForTesting allow_blocking; - EXPECT_FALSE(base::PathExists(file_path1)); - EXPECT_FALSE(base::PathExists(file_path2)); - } -} - -IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, OnErrorWritingSessionCommands) { - ASSERT_TRUE(embedded_test_server()->Start()); - - std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x"); - Tab* tab = browser->CreateTab(); - EXPECT_TRUE(browser->IsRestoringPreviousState()); - const GURL url = embedded_test_server()->GetURL("/simple_page.html"); - NavigateAndWaitForCompletion(url, tab); - static_cast<sessions::CommandStorageManagerDelegate*>( - browser->browser_persister()) - ->OnErrorWritingSessionCommands(); - ShutdownBrowserPersisterAndWait(browser.get()); - tab = nullptr; - browser.reset(); - - browser = CreateBrowser(GetProfile(), "x"); - // Should be no tabs while waiting for restore. - EXPECT_TRUE(browser->GetTabs().empty()); - EXPECT_TRUE(browser->IsRestoringPreviousState()); - // Wait for the restore and navigation to complete. - BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation( - browser.get(), url); - - ASSERT_EQ(1u, browser->GetTabs().size()); - EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab()); - EXPECT_EQ(1, browser->GetTabs()[0] - ->GetNavigationController() - ->GetNavigationListSize()); - EXPECT_FALSE(browser->IsRestoringPreviousState()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/persistence/browser_persister_file_utils.cc b/weblayer/browser/persistence/browser_persister_file_utils.cc deleted file mode 100644 index 348f2b12..0000000 --- a/weblayer/browser/persistence/browser_persister_file_utils.cc +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/persistence/browser_persister_file_utils.h" - -#include "base/files/file_enumerator.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" -#include "components/base32/base32.h" -#include "components/sessions/core/command_storage_backend.h" -#include "components/sessions/core/session_constants.h" -#include "content/public/browser/browser_thread.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/browser_list.h" -#include "weblayer/browser/profile_impl.h" - -namespace weblayer { -namespace { - -bool RemoveBrowserPersistenceStorageOnBackgroundThread( - const base::FilePath& database_dir, - base::flat_set<std::string> ids) { - DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - bool all_succeeded = true; - for (const std::string& id : ids) { - DCHECK(!id.empty()); - // Original persistence path. - const base::FilePath persistence_path = - BuildBasePathForBrowserPersister(database_dir, id); - if (!base::DeleteFile(persistence_path)) - all_succeeded = false; - - // Remove persistence paths with timestamps. - auto paths = sessions::CommandStorageBackend::GetSessionFilePaths( - persistence_path, sessions::CommandStorageManager::kOther); - for (const auto& path : paths) { - if (!base::DeleteFile(path)) - all_succeeded = false; - } - } - return all_succeeded; -} - -} // namespace - -base::flat_set<std::string> GetBrowserPersistenceIdsOnBackgroundThread( - const base::FilePath& path) { - DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - base::flat_set<std::string> ids; - base::FilePath matching_path = base::FilePath().AppendASCII( - std::string(BrowserImpl::kPersistenceFilePrefix) + std::string("*")); - base::FileEnumerator iter(path, /* recursive */ false, - base::FileEnumerator::FILES, matching_path.value()); - for (base::FilePath name = iter.Next(); !name.empty(); name = iter.Next()) { - // The name is base32 encoded, which is ascii. - const std::string base_name = iter.GetInfo().GetName().MaybeAsASCII(); - if (base_name.size() <= std::size(BrowserImpl::kPersistenceFilePrefix)) - continue; - - const std::string encoded_id_and_timestamp = - base_name.substr(std::size(BrowserImpl::kPersistenceFilePrefix) - 1); - const size_t separator_index = encoded_id_and_timestamp.find( - base::FilePath(sessions::kTimestampSeparator).MaybeAsASCII()); - const std::string encoded_id = - separator_index == std::string::npos - ? encoded_id_and_timestamp - : encoded_id_and_timestamp.substr(0, separator_index); - const std::string decoded_id = base32::Base32Decode(encoded_id); - if (!decoded_id.empty() && ids.count(decoded_id) == 0 && - sessions::CommandStorageBackend::IsValidFile(name)) { - ids.insert(decoded_id); - } - } - return ids; -} - -base::FilePath BuildBasePathForBrowserPersister( - const base::FilePath& profile_path, - const std::string& browser_id) { - DCHECK(!browser_id.empty()); - const std::string encoded_name = base32::Base32Encode(browser_id); - return profile_path.AppendASCII(BrowserImpl::kPersistenceFilePrefix + - encoded_name); -} - -void RemoveBrowserPersistenceStorageImpl( - ProfileImpl* profile, - base::OnceCallback<void(bool)> done_callback, - base::flat_set<std::string> ids) { - // Remove any ids that are actively in use. - for (BrowserImpl* browser : BrowserList::GetInstance()->browsers()) { - if (browser->profile() == profile) - ids.erase(browser->GetPersistenceId()); - } - - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&RemoveBrowserPersistenceStorageOnBackgroundThread, - profile->GetBrowserPersisterDataBaseDir(), std::move(ids)), - std::move(done_callback)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/persistence/browser_persister_file_utils.h b/weblayer/browser/persistence/browser_persister_file_utils.h deleted file mode 100644 index d941e5e..0000000 --- a/weblayer/browser/persistence/browser_persister_file_utils.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_FILE_UTILS_H_ -#define WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_FILE_UTILS_H_ - -#include <string> - -#include "base/containers/flat_set.h" -#include "base/functional/callback_forward.h" - -namespace base { -class FilePath; -} - -namespace weblayer { - -class ProfileImpl; - -// Returns the set of known persistence ids for the profile at |path|. -base::flat_set<std::string> GetBrowserPersistenceIdsOnBackgroundThread( - const base::FilePath& path); - -// Returns the base path to save persistence information. `profile_path` is the -// path of the profile, and `browser_id` the persistence id. -// -// WARNING: persistence code writes more than one file. Historically it wrote -// to the value returned by this. Now it writes to the value returned by this -// with the suffix"_TIMESTAMP", where TIMESTAMP is the time stamp. -base::FilePath BuildBasePathForBrowserPersister( - const base::FilePath& profile_path, - const std::string& browser_id); - -// Implementation of RemoveBrowserPersistenceStorage(). Tries to remove all -// the persistence files for the set of browser persistence ids. -void RemoveBrowserPersistenceStorageImpl( - ProfileImpl* profile, - base::OnceCallback<void(bool)> done_callback, - base::flat_set<std::string> ids); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_FILE_UTILS_H_
diff --git a/weblayer/browser/persistent_download.cc b/weblayer/browser/persistent_download.cc deleted file mode 100644 index bb22ab4..0000000 --- a/weblayer/browser/persistent_download.cc +++ /dev/null
@@ -1,167 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/persistent_download.h" - -#include "base/files/file_path.h" -#include "base/functional/bind.h" -#include "base/memory/ptr_util.h" -#include "base/task/sequenced_task_runner.h" -#include "components/download/public/common/download_item.h" - -namespace weblayer { - -namespace { -const char kPersistentDownloadKeyName[] = "weblayer_download_impl"; -} - -PersistentDownload::~PersistentDownload() = default; - -void PersistentDownload::Create(download::DownloadItem* item) { - item->SetUserData(kPersistentDownloadKeyName, - base::WrapUnique(new PersistentDownload(item))); -} - -PersistentDownload* PersistentDownload::Get(download::DownloadItem* item) { - return static_cast<PersistentDownload*>( - item->GetUserData(kPersistentDownloadKeyName)); -} - -DownloadState PersistentDownload::GetState() { - if (item_->GetState() == download::DownloadItem::COMPLETE) - return DownloadState::kComplete; - - if (cancel_pending_ || item_->GetState() == download::DownloadItem::CANCELLED) - return DownloadState::kCancelled; - - if (pause_pending_ || (item_->IsPaused() && !resume_pending_)) - return DownloadState::kPaused; - - if (resume_pending_ || - item_->GetState() == download::DownloadItem::IN_PROGRESS) { - return DownloadState::kInProgress; - } - - return DownloadState::kFailed; -} - -int64_t PersistentDownload::GetTotalBytes() { - return item_->GetTotalBytes(); -} - -int64_t PersistentDownload::GetReceivedBytes() { - return item_->GetReceivedBytes(); -} - -void PersistentDownload::Pause() { - // The Pause/Resume/Cancel methods need to be called in a PostTask because we - // may be in a callback from the download subsystem and it doesn't handle - // nested calls. - resume_pending_ = false; - pause_pending_ = true; - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(&PersistentDownload::PauseInternal, - weak_ptr_factory_.GetWeakPtr())); -} - -void PersistentDownload::Resume() { - pause_pending_ = false; - resume_pending_ = true; - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(&PersistentDownload::ResumeInternal, - weak_ptr_factory_.GetWeakPtr())); -} - -void PersistentDownload::Cancel() { - cancel_pending_ = true; - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(&PersistentDownload::CancelInternal, - weak_ptr_factory_.GetWeakPtr())); -} - -base::FilePath PersistentDownload::GetLocation() { - return item_->GetTargetFilePath(); -} - -std::u16string PersistentDownload::GetFileNameToReportToUser() { - return item_->GetFileNameToReportUser().LossyDisplayName(); -} - -std::string PersistentDownload::GetMimeType() { - return item_->GetMimeType(); -} - -DownloadError PersistentDownload::GetError() { - auto reason = item_->GetLastReason(); - if (reason == download::DOWNLOAD_INTERRUPT_REASON_NONE) - return DownloadError::kNoError; - - if (reason == download::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM) - return DownloadError::kSSLError; - - if (reason >= download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED && - reason <= - download::DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT) - return DownloadError::kServerError; - - if (reason >= download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED && - reason <= download::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST) - return DownloadError::kConnectivityError; - - if (reason == download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE) - return DownloadError::kNoSpace; - - if (reason >= download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED && - reason <= download::DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE) - return DownloadError::kFileError; - - if (reason == download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED) - return DownloadError::kCancelled; - - return DownloadError::kOtherError; -} - -PersistentDownload::PersistentDownload(download::DownloadItem* item) - : item_(item) {} - -void PersistentDownload::PauseInternal() { - if (pause_pending_) { - pause_pending_ = false; - item_->Pause(); - } -} - -int PersistentDownload::GetNotificationId() { - return item_->GetId(); -} - -bool PersistentDownload::IsTransient() { - return false; -} - -GURL PersistentDownload::GetSourceUrl() { - return {}; -} - -const SkBitmap* PersistentDownload::GetLargeIcon() { - return nullptr; -} - -void PersistentDownload::OnFinished(bool activated) { - // For this type of download, activation is handled purely in Java. -} - -void PersistentDownload::ResumeInternal() { - if (resume_pending_) { - resume_pending_ = false; - item_->Resume(true); - } -} - -void PersistentDownload::CancelInternal() { - cancel_pending_ = false; - item_->Cancel(true); -} - -} // namespace weblayer
diff --git a/weblayer/browser/persistent_download.h b/weblayer/browser/persistent_download.h deleted file mode 100644 index 72b39e0..0000000 --- a/weblayer/browser/persistent_download.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PERSISTENT_DOWNLOAD_H_ -#define WEBLAYER_BROWSER_PERSISTENT_DOWNLOAD_H_ - -#include "base/memory/raw_ptr.h" -#include "weblayer/browser/download_impl.h" - -namespace download { -class DownloadItem; -} - -namespace weblayer { - -// A DownloadImpl that is persisted to disk. It will be backed by a -// download::DownloadItem for which IsTransient returns false. This is used when -// a user downloads a file from the web. -class PersistentDownload : public DownloadImpl { - public: - PersistentDownload(const PersistentDownload& other) = delete; - PersistentDownload& operator=(const PersistentDownload& other) = delete; - ~PersistentDownload() override; - - static void Create(download::DownloadItem* item); - static PersistentDownload* Get(download::DownloadItem* item); - - // Download: - DownloadState GetState() override; - int64_t GetTotalBytes() override; - int64_t GetReceivedBytes() override; - void Pause() override; - void Resume() override; - void Cancel() override; - base::FilePath GetLocation() override; - std::u16string GetFileNameToReportToUser() override; - std::string GetMimeType() override; - DownloadError GetError() override; - - // DownloadImpl: - int GetNotificationId() override; - bool IsTransient() override; - GURL GetSourceUrl() override; - const SkBitmap* GetLargeIcon() override; - void OnFinished(bool activated) override; - - private: - explicit PersistentDownload(download::DownloadItem* item); - - void PauseInternal(); - void ResumeInternal(); - void CancelInternal(); - - raw_ptr<download::DownloadItem> item_; - - bool pause_pending_ = false; - bool resume_pending_ = false; - bool cancel_pending_ = false; - - base::WeakPtrFactory<PersistentDownload> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PERSISTENT_DOWNLOAD_H_
diff --git a/weblayer/browser/popup_blocker_browsertest.cc b/weblayer/browser/popup_blocker_browsertest.cc deleted file mode 100644 index 56db082..0000000 --- a/weblayer/browser/popup_blocker_browsertest.cc +++ /dev/null
@@ -1,271 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/raw_ptr.h" -#include "base/strings/stringprintf.h" -#include "build/build_config.h" -#include "components/blocked_content/popup_blocker_tab_helper.h" -#include "third_party/blink/public/common/switches.h" -#include "ui/base/page_transition_types.h" -#include "ui/base/window_open_disposition.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/browser.h" -#include "weblayer/public/browser_observer.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/new_tab_delegate.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -class PopupBlockerBrowserTest : public WebLayerBrowserTest, - public NewTabDelegate, - public BrowserObserver { - public: - // WebLayerBrowserTest: - void SetUpOnMainThread() override { - ASSERT_TRUE(embedded_test_server()->Start()); - original_tab_ = shell()->tab(); - original_tab_->SetNewTabDelegate(this); - shell()->browser()->AddObserver(this); - - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"), - original_tab_); - } - void TearDownOnMainThread() override { - shell()->browser()->RemoveObserver(this); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - WebLayerBrowserTest::SetUpCommandLine(command_line); - // Some bots are flaky due to slower loading interacting with - // deferred commits. - command_line->AppendSwitch(blink::switches::kAllowPreCommitInput); - } - - // NewTabDelegate: - void OnNewTab(Tab* new_tab, NewTabType type) override {} - - // BrowserObserver: - void OnTabAdded(Tab* tab) override { - new_tab_ = tab; - if (new_tab_run_loop_) - new_tab_run_loop_->Quit(); - } - void OnTabRemoved(Tab* tab, bool active_tab_changed) override { - ASSERT_EQ(tab, new_tab_); - new_tab_ = nullptr; - if (close_tab_run_loop_) - close_tab_run_loop_->Quit(); - } - - size_t GetBlockedPopupCount() { - return blocked_content::PopupBlockerTabHelper::FromWebContents( - GetWebContents(original_tab_)) - ->GetBlockedPopupsCount(); - } - - content::WebContents* GetWebContents(Tab* tab) { - return static_cast<TabImpl*>(tab)->web_contents(); - } - - Tab* WaitForNewTab() { - if (!new_tab_) { - new_tab_run_loop_ = std::make_unique<base::RunLoop>(); - new_tab_run_loop_->Run(); - new_tab_run_loop_ = nullptr; - } - return new_tab_; - } - - void WaitForCloseTab() { - if (new_tab_) { - close_tab_run_loop_ = std::make_unique<base::RunLoop>(); - close_tab_run_loop_->Run(); - close_tab_run_loop_ = nullptr; - } - ASSERT_FALSE(new_tab_); - } - - void ExpectTabURL(Tab* tab, const GURL& url) { - if (tab->GetNavigationController()->GetNavigationListSize() > 0) { - EXPECT_EQ(tab->GetNavigationController()->GetNavigationEntryDisplayURL(0), - url); - } else { - TestNavigationObserver( - url, TestNavigationObserver::NavigationEvent::kCompletion, tab) - .Wait(); - } - } - - Tab* ShowPopup(const GURL& url) { - auto* popup_blocker = - blocked_content::PopupBlockerTabHelper::FromWebContents( - GetWebContents(original_tab_)); - popup_blocker->ShowBlockedPopup( - popup_blocker->GetBlockedPopupRequests().begin()->first, - WindowOpenDisposition::NEW_FOREGROUND_TAB); - Tab* new_tab = WaitForNewTab(); - ExpectTabURL(new_tab, url); - EXPECT_EQ(GetBlockedPopupCount(), 0u); - return new_tab; - } - - Tab* original_tab() { return original_tab_; } - - private: - std::unique_ptr<base::RunLoop> new_tab_run_loop_; - std::unique_ptr<base::RunLoop> close_tab_run_loop_; - - raw_ptr<Tab> original_tab_ = nullptr; - raw_ptr<Tab> new_tab_ = nullptr; -}; - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, BlocksPopup) { - ExecuteScript(original_tab(), "window.open('https://google.com')", true); - EXPECT_EQ(GetBlockedPopupCount(), 1u); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, BlocksMultiplePopups) { - ExecuteScript(original_tab(), "window.open('https://google.com')", true); - ExecuteScript(original_tab(), "window.open('https://google.com')", true); - EXPECT_EQ(GetBlockedPopupCount(), 2u); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, DoesNotBlockUserGesture) { - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - ExecuteScriptWithUserGesture( - original_tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str())); - - Tab* new_tab = WaitForNewTab(); - ExpectTabURL(new_tab, popup_url); - EXPECT_EQ(GetBlockedPopupCount(), 0u); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, OpensBlockedPopup) { - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - ExecuteScript( - original_tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true); - EXPECT_EQ(GetBlockedPopupCount(), 1u); - - Tab* new_tab = ShowPopup(popup_url); - - // Blocked popups should no longer have the opener set to match Chrome - // behavior. - EXPECT_FALSE(GetWebContents(new_tab)->HasOpener()); - // Make sure we can cleanly close the popup, and there's no crash. - ExecuteScriptWithUserGesture(new_tab, "window.close()"); - WaitForCloseTab(); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, - AllowsPopupThroughContentSettingException) { - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - HostContentSettingsMapFactory::GetForBrowserContext( - GetWebContents(original_tab())->GetBrowserContext()) - ->SetContentSettingDefaultScope(popup_url, GURL(), - ContentSettingsType::POPUPS, - CONTENT_SETTING_ALLOW); - ExecuteScript( - original_tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true); - Tab* new_tab = WaitForNewTab(); - ExpectTabURL(new_tab, popup_url); - EXPECT_EQ(GetBlockedPopupCount(), 0u); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, - AllowsPopupThroughContentSettingDefaultValue) { - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - HostContentSettingsMapFactory::GetForBrowserContext( - GetWebContents(original_tab())->GetBrowserContext()) - ->SetDefaultContentSetting(ContentSettingsType::POPUPS, - CONTENT_SETTING_ALLOW); - ExecuteScript( - original_tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true); - Tab* new_tab = WaitForNewTab(); - ExpectTabURL(new_tab, popup_url); - EXPECT_EQ(GetBlockedPopupCount(), 0u); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, - BlockPopupThroughContentSettingException) { - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - HostContentSettingsMapFactory::GetForBrowserContext( - GetWebContents(original_tab())->GetBrowserContext()) - ->SetDefaultContentSetting(ContentSettingsType::POPUPS, - CONTENT_SETTING_ALLOW); - HostContentSettingsMapFactory::GetForBrowserContext( - GetWebContents(original_tab())->GetBrowserContext()) - ->SetContentSettingDefaultScope(popup_url, GURL(), - ContentSettingsType::POPUPS, - CONTENT_SETTING_BLOCK); - ExecuteScript( - original_tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true); - EXPECT_EQ(GetBlockedPopupCount(), 1u); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, - BlocksAndOpensPopupFromOpenURL) { - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - content::OpenURLParams params(popup_url, content::Referrer(), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_LINK, true); - params.initiator_origin = url::Origin::Create(popup_url); - GetWebContents(original_tab())->OpenURL(params); - EXPECT_EQ(GetBlockedPopupCount(), 1u); - - ShowPopup(popup_url); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, - DoesNotOpenPopupWithoutNewTabDelegate) { - NewTabDelegate* old_delegate = - static_cast<TabImpl*>(original_tab())->new_tab_delegate(); - original_tab()->SetNewTabDelegate(nullptr); - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - ExecuteScriptWithUserGesture( - original_tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str())); - EXPECT_EQ(GetBlockedPopupCount(), 0u); - - // Navigate the original tab, then make sure we still only have a single tab. - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"), - original_tab()); - EXPECT_EQ(shell()->browser()->GetTabs().size(), 1u); - - // Restore the old delegate to make sure it is cleaned up on Android. - original_tab()->SetNewTabDelegate(old_delegate); -} - -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, - DoesNotOpenBlockedPopupWithoutNewTabDelegate) { - NewTabDelegate* old_delegate = - static_cast<TabImpl*>(original_tab())->new_tab_delegate(); - original_tab()->SetNewTabDelegate(nullptr); - GURL popup_url = embedded_test_server()->GetURL("/echo?popup"); - ExecuteScript( - original_tab(), - base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true); - EXPECT_EQ(GetBlockedPopupCount(), 0u); - - // Navigate the original tab, then make sure we still only have a single tab. - NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"), - original_tab()); - EXPECT_EQ(shell()->browser()->GetTabs().size(), 1u); - - // Restore the old delegate to make sure it is cleaned up on Android. - original_tab()->SetNewTabDelegate(old_delegate); -} - -} // namespace weblayer
diff --git a/weblayer/browser/popup_navigation_delegate_impl.cc b/weblayer/browser/popup_navigation_delegate_impl.cc deleted file mode 100644 index 6812e86..0000000 --- a/weblayer/browser/popup_navigation_delegate_impl.cc +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/popup_navigation_delegate_impl.h" - -#include "base/functional/callback_helpers.h" -#include "build/build_config.h" -#include "components/infobars/content/content_infobar_manager.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/blocked_content/android/popup_blocked_infobar_delegate.h" -#endif - -namespace weblayer { - -PopupNavigationDelegateImpl::PopupNavigationDelegateImpl( - const content::OpenURLParams& params, - content::WebContents* source_contents, - content::RenderFrameHost* opener) - : params_(params), - source_contents_(source_contents), - opener_(opener), - original_user_gesture_(params_.user_gesture) {} - -content::RenderFrameHost* PopupNavigationDelegateImpl::GetOpener() { - return opener_; -} - -bool PopupNavigationDelegateImpl::GetOriginalUserGesture() { - return original_user_gesture_; -} - -GURL PopupNavigationDelegateImpl::GetURL() { - return params_.url; -} - -blocked_content::PopupNavigationDelegate::NavigateResult -PopupNavigationDelegateImpl::NavigateWithGesture( - const blink::mojom::WindowFeatures& window_features, - absl::optional<WindowOpenDisposition> updated_disposition) { - // It's safe to mutate |params_| here because NavigateWithGesture() will only - // be called once, and the user gesture value has already been saved in - // |original_user_gesture_|. - params_.user_gesture = true; - if (updated_disposition) - params_.disposition = updated_disposition.value(); - content::WebContents* new_contents = source_contents_->OpenURL(params_); - return NavigateResult{ - new_contents, - params_.disposition, - }; -} - -void PopupNavigationDelegateImpl::OnPopupBlocked( - content::WebContents* web_contents, - int total_popups_blocked_on_page) { -#if BUILDFLAG(IS_ANDROID) - blocked_content::PopupBlockedInfoBarDelegate::Create( - infobars::ContentInfoBarManager::FromWebContents(web_contents), - total_popups_blocked_on_page, - HostContentSettingsMapFactory::GetForBrowserContext( - web_contents->GetBrowserContext()), - base::NullCallback()); -#endif -} - -} // namespace weblayer
diff --git a/weblayer/browser/popup_navigation_delegate_impl.h b/weblayer/browser/popup_navigation_delegate_impl.h deleted file mode 100644 index f745a03..0000000 --- a/weblayer/browser/popup_navigation_delegate_impl.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_POPUP_NAVIGATION_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_POPUP_NAVIGATION_DELEGATE_IMPL_H_ - -#include "base/memory/raw_ptr.h" -#include "components/blocked_content/popup_navigation_delegate.h" -#include "content/public/browser/page_navigator.h" -#include "content/public/browser/render_frame_host.h" - -namespace weblayer { - -class PopupNavigationDelegateImpl - : public blocked_content::PopupNavigationDelegate { - public: - PopupNavigationDelegateImpl(const content::OpenURLParams& params, - content::WebContents* source_contents, - content::RenderFrameHost* opener); - - // blocked_content::PopupNavigationDelegate: - content::RenderFrameHost* GetOpener() override; - bool GetOriginalUserGesture() override; - GURL GetURL() override; - NavigateResult NavigateWithGesture( - const blink::mojom::WindowFeatures& window_features, - absl::optional<WindowOpenDisposition> updated_disposition) override; - void OnPopupBlocked(content::WebContents* web_contents, - int total_popups_blocked_on_page) override; - - const content::OpenURLParams& params() const { return params_; } - - private: - content::OpenURLParams params_; - raw_ptr<content::WebContents> source_contents_; - raw_ptr<content::RenderFrameHost> opener_; - const bool original_user_gesture_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_POPUP_NAVIGATION_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/prefetch_browsertest.cc b/weblayer/browser/prefetch_browsertest.cc deleted file mode 100644 index c5aa82f..0000000 --- a/weblayer/browser/prefetch_browsertest.cc +++ /dev/null
@@ -1,141 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/files/file_path.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/synchronization/lock.h" -#include "base/test/bind.h" -#include "base/thread_annotations.h" -#include "build/build_config.h" -#include "components/network_session_configurator/common/network_switches.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/browser_test_utils.h" -#include "net/base/network_change_notifier.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { -namespace { -const char kPrefetchPage[] = "/simple_prefetch.html"; -const char kRedirectPrefetchPage[] = "/redirect_prefetch.html"; -const char kRedirectPrefetchUrl[] = "/redirect"; -const char kRedirectedPrefetchUrl[] = "/redirected"; -const char kPrefetchTarget[] = "/prefetch_target.lnk"; -} // namespace - -class PrefetchBrowserTest : public WebLayerBrowserTest { - public: - void SetUpOnMainThread() override { - // The test makes requests to google.com which we want to redirect to the - // test server. - host_resolver()->AddRule("*", "127.0.0.1"); - - embedded_test_server()->RegisterRequestMonitor(base::BindRepeating( - &PrefetchBrowserTest::MonitorRequest, base::Unretained(this))); - ASSERT_TRUE(embedded_test_server()->Start()); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - // Set a dummy variation ID to send X-Client-Data header to Google hosts - // in RedirectedPrefetch test. - command_line->AppendSwitchASCII("force-variation-ids", "42"); - // Need to ignore cert errors to use a HTTPS server for the test domains. - command_line->AppendSwitch(switches::kIgnoreCertificateErrors); - } - - bool RunPrefetchExperiment(GURL url, const std::u16string expected_title) { - content::TitleWatcher title_watcher( - static_cast<TabImpl*>(shell()->tab())->web_contents(), expected_title); - NavigateAndWaitForCompletion(url, shell()); - return expected_title == title_watcher.WaitAndGetTitle(); - } - - protected: - bool prefetch_target_request_seen_ = false; - base::Lock lock_; - - // |requests_| is accessed on the UI thread by the test body and on the IO - // thread by the test server's request handler, so must be guarded by a lock - // to avoid data races. - std::vector<net::test_server::HttpRequest> requests_ GUARDED_BY(lock_); - - private: - void MonitorRequest(const net::test_server::HttpRequest& request) { - if (request.relative_url == std::string(kPrefetchTarget)) { - prefetch_target_request_seen_ = true; - } - } -}; - -IN_PROC_BROWSER_TEST_F(PrefetchBrowserTest, PrefetchWorks) { - // Set real NetworkChangeNotifier singleton aside. - std::unique_ptr<net::NetworkChangeNotifier::DisableForTest> disable_for_test( - new net::NetworkChangeNotifier::DisableForTest); - ASSERT_FALSE(prefetch_target_request_seen_); - EXPECT_TRUE(RunPrefetchExperiment( - embedded_test_server()->GetURL(kPrefetchPage), u"link onload")); - EXPECT_TRUE(prefetch_target_request_seen_); -} - -// https://crbug.com/922362: When the prefetched request is redirected, DCHECKs -// in PrefetchURLLoader::FollowRedirect() failed due to "X-Client-Data" in -// removed_headers. Verify that it no longer does. -IN_PROC_BROWSER_TEST_F(PrefetchBrowserTest, RedirectedPrefetch) { - net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); - https_server.RegisterRequestHandler(base::BindLambdaForTesting( - [this](const net::test_server::HttpRequest& request) - -> std::unique_ptr<net::test_server::HttpResponse> { - auto response = std::make_unique<net::test_server::BasicHttpResponse>(); - base::AutoLock auto_lock(lock_); - if (request.relative_url == std::string(kRedirectPrefetchPage)) { - requests_.push_back(request); - response->set_content_type("text/html"); - response->set_content( - base::StringPrintf("<link rel=\"prefetch\" href=\"%s\" " - "onload=\"document.title='done'\">", - kRedirectPrefetchUrl)); - return response; - } else if (request.relative_url == std::string(kRedirectPrefetchUrl)) { - requests_.push_back(request); - response->set_code(net::HTTP_MOVED_PERMANENTLY); - response->AddCustomHeader( - "Location", base::StringPrintf("https://example.com:%s%s", - request.GetURL().port().c_str(), - kRedirectedPrefetchUrl)); - return response; - } else if (request.relative_url == - std::string(kRedirectedPrefetchUrl)) { - requests_.push_back(request); - return response; - } - return nullptr; - })); - - https_server.ServeFilesFromSourceDirectory( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - { - base::AutoLock auto_lock(lock_); - requests_.clear(); - } - ASSERT_TRUE(https_server.Start()); - - GURL url = https_server.GetURL("www.google.com", kRedirectPrefetchPage); - EXPECT_TRUE(RunPrefetchExperiment(url, u"done")); - { - base::AutoLock auto_lock(lock_); - ASSERT_EQ(3U, requests_.size()); - EXPECT_EQ(base::StringPrintf("www.google.com:%u", https_server.port()), - requests_[0].headers["Host"]); - EXPECT_EQ(kRedirectPrefetchPage, requests_[0].relative_url); - } -} - -} // namespace weblayer
diff --git a/weblayer/browser/profile_browsertest.cc b/weblayer/browser/profile_browsertest.cc deleted file mode 100644 index 091f53f..0000000 --- a/weblayer/browser/profile_browsertest.cc +++ /dev/null
@@ -1,222 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/test/bind.h" -#include "build/build_config.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "ui/gfx/image/image_unittest_util.h" -#include "weblayer/browser/browser_list.h" -#include "weblayer/browser/browser_list_observer.h" -#include "weblayer/browser/favicon/favicon_fetcher_impl.h" -#include "weblayer/browser/favicon/test_favicon_fetcher_delegate.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/browser.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -using ProfileBrowserTest = WebLayerBrowserTest; - -// TODO(crbug.com/654704): Android does not support PRE_ tests. -#if !BUILDFLAG(IS_ANDROID) - -// UKM enabling via Profile persists across restarts. -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, PRE_PersistUKM) { - GetProfile()->SetBooleanSetting(SettingType::UKM_ENABLED, true); -} - -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, PersistUKM) { - ASSERT_TRUE(GetProfile()->GetBooleanSetting(SettingType::UKM_ENABLED)); -} - -// Enabling Network Prediction via Profile persists across restarts. -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, PRE_PersistNetworkPrediction) { - GetProfile()->SetBooleanSetting(SettingType::NETWORK_PREDICTION_ENABLED, - false); -} - -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, PersistNetworkPrediction) { - ASSERT_FALSE( - GetProfile()->GetBooleanSetting(SettingType::NETWORK_PREDICTION_ENABLED)); -} - -#endif // !BUILDFLAG(IS_ANDROID) - -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, GetCachedFaviconForPageUrl) { - // Navigation to a page with a favicon. - ASSERT_TRUE(embedded_test_server()->Start()); - TestFaviconFetcherDelegate fetcher_delegate; - auto fetcher = shell()->tab()->CreateFaviconFetcher(&fetcher_delegate); - const GURL url = - embedded_test_server()->GetURL("/simple_page_with_favicon.html"); - NavigateAndWaitForCompletion(url, shell()); - fetcher_delegate.WaitForFavicon(); - EXPECT_FALSE(fetcher_delegate.last_image().IsEmpty()); - EXPECT_EQ(1, fetcher_delegate.on_favicon_changed_call_count()); - - // Request the favicon. - base::RunLoop run_loop; - static_cast<TabImpl*>(shell()->tab()) - ->profile() - ->GetCachedFaviconForPageUrl( - url, base::BindLambdaForTesting([&](gfx::Image image) { - // The last parameter is the max difference allowed for each color - // component. As the image is encoded before saving to disk some - // variance is expected. - EXPECT_TRUE(gfx::test::AreImagesClose( - image, fetcher_delegate.last_image(), 10)); - run_loop.Quit(); - })); - run_loop.Run(); -} - -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ClearBrowsingDataDeletesFavicons) { - // Navigate to a page with a favicon. - ASSERT_TRUE(embedded_test_server()->Start()); - TestFaviconFetcherDelegate fetcher_delegate; - auto fetcher = shell()->tab()->CreateFaviconFetcher(&fetcher_delegate); - const GURL url = - embedded_test_server()->GetURL("/simple_page_with_favicon.html"); - NavigateAndWaitForCompletion(url, shell()); - fetcher_delegate.WaitForNonemptyFavicon(); - EXPECT_FALSE(fetcher_delegate.last_image().IsEmpty()); - EXPECT_EQ(1, fetcher_delegate.on_favicon_changed_call_count()); - - // Delete the favicons. - base::RunLoop run_loop; - base::Time now = base::Time::Now(); - ProfileImpl* profile = static_cast<TabImpl*>(shell()->tab())->profile(); - profile->ClearBrowsingData({BrowsingDataType::COOKIES_AND_SITE_DATA}, - now - base::Minutes(5), now, - run_loop.QuitClosure()); - run_loop.Run(); - - // Ask for the cached favicon, there shouldn't be one. - base::RunLoop run_loop2; - profile->GetCachedFaviconForPageUrl( - url, base::BindLambdaForTesting([&](gfx::Image image) { - EXPECT_TRUE(image.IsEmpty()); - run_loop2.Quit(); - })); - run_loop2.Run(); - - // Navigate to another page, and verify favicon is downloaded. - fetcher_delegate.ClearLastImage(); - const GURL url2 = - embedded_test_server()->GetURL("/simple_page_with_favicon2.html"); - NavigateAndWaitForCompletion(url2, shell()); - fetcher_delegate.WaitForNonemptyFavicon(); - EXPECT_FALSE(fetcher_delegate.last_image().IsEmpty()); - EXPECT_EQ(2, fetcher_delegate.on_favicon_changed_call_count()); - - // And fetch the favicon one more time. - base::RunLoop run_loop3; - profile->GetCachedFaviconForPageUrl( - url2, base::BindLambdaForTesting([&](gfx::Image image) { - EXPECT_FALSE(image.IsEmpty()); - // The last parameter is the max difference allowed for each color - // component. As the image is encoded before saving to disk some - // variance is expected. - EXPECT_TRUE(gfx::test::AreImagesClose( - image, fetcher_delegate.last_image(), 10)); - run_loop3.Quit(); - })); - run_loop3.Run(); -} - -// Test default value. -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DefaultNetworkPredictionState) { - ASSERT_TRUE( - GetProfile()->GetBooleanSetting(SettingType::NETWORK_PREDICTION_ENABLED)); -} - -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ClearSiteSettings) { - auto foo_origin = GURL("http://www.foo.com"); - - auto* settings_map = HostContentSettingsMapFactory::GetForBrowserContext( - static_cast<TabImpl*>(shell()->tab()) - ->web_contents() - ->GetBrowserContext()); - EXPECT_EQ(settings_map->GetContentSetting(foo_origin, foo_origin, - ContentSettingsType::GEOLOCATION), - CONTENT_SETTING_ASK); - - settings_map->SetContentSettingDefaultScope(foo_origin, foo_origin, - ContentSettingsType::GEOLOCATION, - CONTENT_SETTING_ALLOW); - - // Ensure clearing things other than site data doesn't change it - base::RunLoop run_loop; - base::Time now = base::Time::Now(); - ProfileImpl* profile = static_cast<TabImpl*>(shell()->tab())->profile(); - profile->ClearBrowsingData( - {BrowsingDataType::COOKIES_AND_SITE_DATA, BrowsingDataType::CACHE}, - base::Time(), now, run_loop.QuitClosure()); - run_loop.Run(); - - EXPECT_EQ(settings_map->GetContentSetting(foo_origin, foo_origin, - ContentSettingsType::GEOLOCATION), - CONTENT_SETTING_ALLOW); - - // Now clear site data. - base::RunLoop run_loop2; - profile->ClearBrowsingData({BrowsingDataType::SITE_SETTINGS}, base::Time(), - now, run_loop2.QuitClosure()); - run_loop2.Run(); - - EXPECT_EQ(settings_map->GetContentSetting(foo_origin, foo_origin, - ContentSettingsType::GEOLOCATION), - CONTENT_SETTING_ASK); -} - -// This test creates a Browser and Tab, which doesn't work well with Java when -// driven from native code. -#if !BUILDFLAG(IS_ANDROID) - -class BrowserListObserverImpl : public BrowserListObserver { - public: - BrowserListObserverImpl(std::unique_ptr<Profile> profile, - base::OnceClosure done_closure) - : profile_(std::move(profile)), done_closure_(std::move(done_closure)) { - BrowserList::GetInstance()->AddObserver(this); - } - ~BrowserListObserverImpl() override { - BrowserList::GetInstance()->RemoveObserver(this); - } - - // BrowserListObserver: - void OnBrowserDestroyed(Browser* browser) override { - Profile::DestroyAndDeleteDataFromDisk(std::move(profile_), - std::move(done_closure_)); - } - - private: - std::unique_ptr<Profile> profile_; - base::OnceClosure done_closure_; -}; - -// This is a crash test to verify no memory related problems calling -// DestroyAndDeleteDataFromDisk() from OnBrowserDestroyed(). -IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DestroyFromOnBrowserRemoved) { - auto profile = Profile::Create("2", true); - auto browser = Browser::Create(profile.get(), nullptr); - - // MarkAsDeleted() may be called multiple times. - static_cast<ProfileImpl*>(profile.get())->MarkAsDeleted(); - static_cast<ProfileImpl*>(profile.get())->MarkAsDeleted(); - - base::RunLoop run_loop; - BrowserListObserverImpl observer(std::move(profile), run_loop.QuitClosure()); - browser.reset(); - run_loop.Run(); - - // No crashes should happen. -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/profile_disk_operations.cc b/weblayer/browser/profile_disk_operations.cc deleted file mode 100644 index 2273ad33..0000000 --- a/weblayer/browser/profile_disk_operations.cc +++ /dev/null
@@ -1,237 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/profile_disk_operations.h" - -#include "base/files/file_enumerator.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "build/build_config.h" -#include "components/base32/base32.h" -#include "weblayer/common/weblayer_paths.h" - -namespace weblayer { - -// Variables named |name| is a string passed in from the embedder to identify a -// profile. It can only contain alphanumeric and underscore. -// -// Variables named |dir_name| generally refers to the directory name of the -// profile. It may be the |name| exactly, or it may be <name>.<number>, if a -// profile is created with a name matching a profile marked for deletion. -// |dir_name| is an implementation detail of this file and should not be exposed -// as a concept out of this file. - -namespace { - -// Cannot be part of a valid name. This prevents the client ever specifying a -// name that collides a different one with a suffix. -constexpr char kSuffixDelimiter = '.'; - -bool IsValidProfileNameChar(char c) { - return base::IsAsciiDigit(c) || base::IsAsciiAlpha(c) || c == '_'; -} - -// Return the data path directory to profiles. -base::FilePath GetProfileRootDataDir() { - base::FilePath path; - CHECK(base::PathService::Get(DIR_USER_DATA, &path)); - return path.AppendASCII("profiles"); -} - -base::FilePath GetProfileMarkerRootDataDir() { - base::FilePath path; - CHECK(base::PathService::Get(DIR_USER_DATA, &path)); - path = path.AppendASCII("profiles_to_delete"); - base::CreateDirectory(path); - return path; -} - -base::FilePath GetDataPathFromDirName(const std::string& dir_name) { - return GetProfileRootDataDir().AppendASCII(dir_name.c_str()); -} - -#if BUILDFLAG(IS_POSIX) -base::FilePath GetCachePathFromDirName(const std::string& dir_name) { - base::FilePath cache_path; - CHECK(base::PathService::Get(base::DIR_CACHE, &cache_path)); - cache_path = cache_path.AppendASCII("profiles").AppendASCII(dir_name.c_str()); - return cache_path; -} -#endif // BUILDFLAG(IS_POSIX) - -} // namespace - -ProfileInfo::ProfileInfo(bool is_incognito, - const std::string& name, - const base::FilePath& data_path, - const base::FilePath& cache_path) - : is_incognito(is_incognito), - name(name), - data_path(data_path), - cache_path(cache_path) {} - -ProfileInfo::ProfileInfo() = default; -ProfileInfo::ProfileInfo(const ProfileInfo&) = default; -ProfileInfo& ProfileInfo::operator=(const ProfileInfo&) = default; -ProfileInfo::~ProfileInfo() = default; - -ProfileInfo CreateProfileInfo(const std::string& name, bool is_incognito) { - if (is_incognito) - return {is_incognito, name, base::FilePath(), base::FilePath()}; - - CHECK(internal::IsValidNameForNonIncognitoProfile(name)); - std::string dir_name = name; - int suffix = 0; - while (internal::IsProfileMarkedForDeletion(dir_name)) { - suffix++; - dir_name = name; - dir_name.append(1, kSuffixDelimiter).append(base::NumberToString(suffix)); - } - - base::FilePath data_path = GetDataPathFromDirName(dir_name); - base::CreateDirectory(data_path); - base::FilePath cache_path = data_path; -#if BUILDFLAG(IS_POSIX) - cache_path = GetCachePathFromDirName(dir_name); - base::CreateDirectory(cache_path); -#endif - return {is_incognito, name, data_path, cache_path}; -} - -base::FilePath ComputeBrowserPersisterDataBaseDir(const ProfileInfo& info) { - base::FilePath base_path; - if (info.is_incognito) { - CHECK(base::PathService::Get(DIR_USER_DATA, &base_path)); - if (info.name.empty()) { - // Originally the Android side of WebLayer only supported a single - // incognito file with an empty name. - std::string file_name = "Incognito Restore Data"; - base_path = base_path.AppendASCII(file_name); - } else { - std::string file_name = "Named Profile Incognito Restore Data"; - base_path = base_path.AppendASCII(file_name).AppendASCII( - base32::Base32Encode(info.name)); - } - } else { - base_path = info.data_path.AppendASCII("Restore Data"); - } - return base_path; -} - -void MarkProfileAsDeleted(const ProfileInfo& info) { - if (info.is_incognito) - return; - - base::FilePath data_root_path = GetProfileRootDataDir(); - base::FilePath marker_path = GetProfileMarkerRootDataDir(); - CHECK(data_root_path.AppendRelativePath(info.data_path, &marker_path)); - base::File file(marker_path, - base::File::FLAG_CREATE | base::File::FLAG_WRITE); - if (!base::PathExists(marker_path)) { - LOG(WARNING) << "Failure in deleting profile data. Profile:" << info.name - << " error:" << static_cast<int>(file.error_details()); - } -} - -void TryNukeProfileFromDisk(const ProfileInfo& info) { - if (info.is_incognito) { - // Incognito. Just delete session data. - base::DeletePathRecursively(ComputeBrowserPersisterDataBaseDir(info)); - return; - } - - // This may fail, but that is ok since the marker is not deleted. - base::DeletePathRecursively(info.data_path); -#if BUILDFLAG(IS_POSIX) - base::DeletePathRecursively(info.cache_path); -#endif -} - -std::vector<std::string> ListProfileNames() { - base::FilePath root_dir = GetProfileRootDataDir(); - std::vector<std::string> profile_names; - base::FileEnumerator enumerator(root_dir, /*recursive=*/false, - base::FileEnumerator::DIRECTORIES); - for (base::FilePath path = enumerator.Next(); !path.empty(); - path = enumerator.Next()) { - std::string dir_name = enumerator.GetInfo().GetName().MaybeAsASCII(); - std::string name = internal::CheckDirNameAndExtractName(dir_name); - if (!name.empty() && !internal::IsProfileMarkedForDeletion(dir_name)) - profile_names.push_back(name); - } - return profile_names; -} - -void NukeProfilesMarkedForDeletion() { - base::FilePath marker_root_dir = GetProfileMarkerRootDataDir(); - base::FileEnumerator enumerator(marker_root_dir, /*recursive=*/false, - base::FileEnumerator::FILES); - for (base::FilePath marker_path = enumerator.Next(); !marker_path.empty(); - marker_path = enumerator.Next()) { - std::string dir_name = enumerator.GetInfo().GetName().MaybeAsASCII(); - if (!internal::CheckDirNameAndExtractName(dir_name).empty()) { - // Delete cache and data directory first before deleting marker. - bool delete_success = true; -#if BUILDFLAG(IS_POSIX) - delete_success |= - base::DeletePathRecursively(GetCachePathFromDirName(dir_name)); -#endif // BUILDFLAG(IS_POSIX) - delete_success |= - base::DeletePathRecursively(GetDataPathFromDirName(dir_name)); - // Only delete the marker if deletion is successful. - if (delete_success) { - base::DeleteFile(marker_path); - } - } - } -} - -namespace internal { - -bool IsValidNameForNonIncognitoProfile(const std::string& name) { - for (char c : name) { - if (!IsValidProfileNameChar(c)) - return false; - } - return !name.empty(); -} - -// If |dir_name| is valid, then return the |name|. Otherwise return the empty -// string. -std::string CheckDirNameAndExtractName(const std::string& dir_name) { - std::vector<std::string> parts = - base::SplitString(dir_name, std::string(1, kSuffixDelimiter), - base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); - if (parts.size() == 0 || parts.size() > 2) - return std::string(); - - if (!IsValidNameForNonIncognitoProfile(parts[0])) - return std::string(); - - if (parts.size() > 1) { - if (parts[1].empty()) - return std::string(); - - for (char c : parts[1]) { - if (!base::IsAsciiDigit(c)) - return std::string(); - } - } - - return parts[0]; -} - -bool IsProfileMarkedForDeletion(const std::string& dir_name) { - base::FilePath marker = - GetProfileMarkerRootDataDir().AppendASCII(dir_name.c_str()); - return base::PathExists(marker); -} - -} // namespace internal - -} // namespace weblayer
diff --git a/weblayer/browser/profile_disk_operations.h b/weblayer/browser/profile_disk_operations.h deleted file mode 100644 index 9cfd01d..0000000 --- a/weblayer/browser/profile_disk_operations.h +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PROFILE_DISK_OPERATIONS_H_ -#define WEBLAYER_BROWSER_PROFILE_DISK_OPERATIONS_H_ - -#include <string> -#include <vector> - -#include "base/files/file_path.h" - -namespace weblayer { - -struct ProfileInfo { - ProfileInfo(bool is_incognito, - const std::string& name, - const base::FilePath& data_path, - const base::FilePath& cache_path); - ProfileInfo(); - ProfileInfo(const ProfileInfo&); - ProfileInfo& operator=(const ProfileInfo&); - ~ProfileInfo(); - - bool is_incognito = false; - // The profile name supplied by client code. For non-incognito profiles name - // can only contain alphanumeric and underscore to be valid. - std::string name; - // Path where persistent profile data is stored. This will be empty if - // icognito. - base::FilePath data_path; - // Path where cache profile data is stored. Depending on the OS, this may - // be the same as |data_path|; the OS may delete data in this directory. - base::FilePath cache_path; -}; - -// |name| must be a valid profile name. Ensures that both data and cache path -// directories are created. The paths returned may be different from the name -// to avoid reusing directories that are marked as deleted. -ProfileInfo CreateProfileInfo(const std::string& name, bool is_incognito); - -base::FilePath ComputeBrowserPersisterDataBaseDir(const ProfileInfo& info); -void MarkProfileAsDeleted(const ProfileInfo& info); -void TryNukeProfileFromDisk(const ProfileInfo& info); - -// Return names of profiles on disk. Invalid profile names are ignored. -// Profiles marked as deleted are ignored. -std::vector<std::string> ListProfileNames(); - -// This should be called before any |MarkProfileAsDeleted| for a single process -// to avoid races. -void NukeProfilesMarkedForDeletion(); - -// Functions exposed for testing. -namespace internal { - -bool IsValidNameForNonIncognitoProfile(const std::string& name); -std::string CheckDirNameAndExtractName(const std::string& dir_name); -bool IsProfileMarkedForDeletion(const std::string& dir_name); - -} // namespace internal - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PROFILE_DISK_OPERATIONS_H_
diff --git a/weblayer/browser/profile_disk_operations_unittests.cc b/weblayer/browser/profile_disk_operations_unittests.cc deleted file mode 100644 index 2011799..0000000 --- a/weblayer/browser/profile_disk_operations_unittests.cc +++ /dev/null
@@ -1,153 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> -#include <vector> - -#include "base/base_paths.h" -#include "base/check.h" -#include "base/containers/contains.h" -#include "base/files/file_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/test/scoped_path_override.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "weblayer/browser/profile_disk_operations.h" -#include "weblayer/common/weblayer_paths.h" - -namespace weblayer { - -class ProfileDiskOperationsTest : public testing::Test { - protected: - base::ScopedPathOverride data_dir_override_{DIR_USER_DATA}; -#if BUILDFLAG(IS_POSIX) - base::ScopedPathOverride cache_dir_override_{base::DIR_CACHE}; -#endif -}; - -TEST_F(ProfileDiskOperationsTest, IsValidNameForNonIncognitoProfile) { - EXPECT_TRUE(internal::IsValidNameForNonIncognitoProfile("foo")); - EXPECT_TRUE(internal::IsValidNameForNonIncognitoProfile("123")); - EXPECT_FALSE(internal::IsValidNameForNonIncognitoProfile(std::string())); - - EXPECT_FALSE(internal::IsValidNameForNonIncognitoProfile("foo.bar")); - EXPECT_FALSE(internal::IsValidNameForNonIncognitoProfile("foo~")); - EXPECT_FALSE(internal::IsValidNameForNonIncognitoProfile("foo-")); -} - -TEST_F(ProfileDiskOperationsTest, CheckDirnameAndExtractName) { - EXPECT_EQ(std::string("foo123"), - internal::CheckDirNameAndExtractName("foo123")); - EXPECT_EQ(std::string("foo"), internal::CheckDirNameAndExtractName("foo.1")); - EXPECT_EQ(std::string("foo"), internal::CheckDirNameAndExtractName("foo.2")); - EXPECT_EQ(std::string("foo"), - internal::CheckDirNameAndExtractName("foo.123")); - - EXPECT_EQ(std::string(), internal::CheckDirNameAndExtractName("foo.")); - EXPECT_EQ(std::string(), internal::CheckDirNameAndExtractName("foo~")); - EXPECT_EQ(std::string(), internal::CheckDirNameAndExtractName("foo~.1")); - EXPECT_EQ(std::string(), internal::CheckDirNameAndExtractName("foo.bar")); - EXPECT_EQ(std::string(), internal::CheckDirNameAndExtractName("foo.1.2")); - EXPECT_EQ(std::string(), internal::CheckDirNameAndExtractName(std::string())); - EXPECT_EQ(std::string(), internal::CheckDirNameAndExtractName(".1")); -} - -TEST_F(ProfileDiskOperationsTest, BasicListProfileNames) { - std::vector<std::string> names{"foo", "bar", "baz"}; - for (const auto& name : names) { - ProfileInfo info = CreateProfileInfo(name, false); - EXPECT_FALSE(info.data_path.empty()); - EXPECT_FALSE(info.cache_path.empty()); - } - std::vector<std::string> listed_names = ListProfileNames(); - EXPECT_EQ(names.size(), listed_names.size()); - for (const auto& name : names) { - EXPECT_TRUE(base::Contains(listed_names, name)); - } -} - -TEST_F(ProfileDiskOperationsTest, MarkProfileAsDeleted) { - std::vector<std::string> names{"foo", "bar", "baz"}; - std::vector<ProfileInfo> infos; - for (const auto& name : names) { - ProfileInfo info = CreateProfileInfo(name, false); - infos.push_back(info); - EXPECT_FALSE(info.data_path.empty()); - EXPECT_FALSE(info.cache_path.empty()); - } - for (const auto& info : infos) { - MarkProfileAsDeleted(info); - EXPECT_TRUE(internal::IsProfileMarkedForDeletion( - info.data_path.BaseName().MaybeAsASCII())); - } - std::vector<std::string> listed_names = ListProfileNames(); - EXPECT_TRUE(listed_names.empty()); -} - -TEST_F(ProfileDiskOperationsTest, ReuseProfileName) { - constexpr int kRepeat = 3; - for (int i = 0; i < kRepeat; ++i) { - ProfileInfo info = CreateProfileInfo("foo", false); - MarkProfileAsDeleted(info); - EXPECT_TRUE(internal::IsProfileMarkedForDeletion( - info.data_path.BaseName().MaybeAsASCII())); - - std::string expected_base_name("foo"); - if (i != 0) { - expected_base_name += "."; - expected_base_name += base::NumberToString(i); - } - EXPECT_EQ(expected_base_name, info.data_path.BaseName().MaybeAsASCII()); - EXPECT_EQ(expected_base_name, info.cache_path.BaseName().MaybeAsASCII()); - - std::vector<std::string> listed_names = ListProfileNames(); - EXPECT_TRUE(listed_names.empty()); - } -} - -TEST_F(ProfileDiskOperationsTest, NukeProfile) { - std::vector<ProfileInfo> deleted_infos; - constexpr int kRepeat = 3; - for (int i = 0; i < kRepeat; ++i) { - ProfileInfo info = CreateProfileInfo("foo", false); - MarkProfileAsDeleted(info); - deleted_infos.push_back(info); - } - - { - ProfileInfo info = CreateProfileInfo("bar", false); - MarkProfileAsDeleted(info); - deleted_infos.push_back(info); - } - - { - ProfileInfo info = CreateProfileInfo("baz", false); - MarkProfileAsDeleted(info); - deleted_infos.push_back(info); - } - - ProfileInfo kept_info = CreateProfileInfo("kept", false); - - for (auto& info : deleted_infos) { - EXPECT_TRUE(base::PathExists(info.data_path)); - EXPECT_TRUE(base::PathExists(info.cache_path)); - } - EXPECT_TRUE(base::PathExists(kept_info.data_path)); - EXPECT_TRUE(base::PathExists(kept_info.cache_path)); - - NukeProfilesMarkedForDeletion(); - - for (auto& info : deleted_infos) { - EXPECT_FALSE(base::PathExists(info.data_path)); - EXPECT_FALSE(base::PathExists(info.cache_path)); - } - EXPECT_TRUE(base::PathExists(kept_info.data_path)); - EXPECT_TRUE(base::PathExists(kept_info.cache_path)); - - ProfileInfo info = CreateProfileInfo("bar", false); - EXPECT_EQ(std::string("bar"), info.data_path.BaseName().MaybeAsASCII()); - EXPECT_EQ(std::string("bar"), info.cache_path.BaseName().MaybeAsASCII()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/profile_impl.cc b/weblayer/browser/profile_impl.cc deleted file mode 100644 index a2c70ad3..0000000 --- a/weblayer/browser/profile_impl.cc +++ /dev/null
@@ -1,736 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/profile_impl.h" - -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "base/functional/bind.h" -#include "base/memory/raw_ptr.h" -#include "base/no_destructor.h" -#include "base/observer_list.h" -#include "base/ranges/algorithm.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" -#include "base/threading/thread_restrictions.h" -#include "build/build_config.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/prefs/pref_service.h" -#include "components/profile_metrics/browser_profile_type.h" -#include "components/web_cache/browser/web_cache_manager.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/browsing_data_remover.h" -#include "content/public/browser/device_service.h" -#include "content/public/browser/download_manager.h" -#include "content/public/browser/page_navigator.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_contents.h" -#include "services/network/public/mojom/network_context.mojom.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/image/image_skia_rep.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/browser_list.h" -#include "weblayer/browser/browsing_data_remover_delegate.h" -#include "weblayer/browser/cookie_manager_impl.h" -#include "weblayer/browser/favicon/favicon_service_impl.h" -#include "weblayer/browser/favicon/favicon_service_impl_factory.h" -#include "weblayer/browser/no_state_prefetch/prerender_controller_impl.h" -#include "weblayer/browser/persistence/browser_persister_file_utils.h" -#include "weblayer/browser/tab_impl.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/callback_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/android/scoped_java_ref.h" -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "components/unified_consent/pref_names.h" -#include "ui/gfx/android/java_bitmap.h" -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/java/jni/ProfileImpl_jni.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#endif - -#if BUILDFLAG(IS_POSIX) -#include "base/base_paths_posix.h" -#endif - -#if BUILDFLAG(IS_ANDROID) -using base::android::AttachCurrentThread; -#endif - -namespace weblayer { - -namespace { - -bool g_first_profile_created = false; - -// TaskRunner used by MarkProfileAsDeleted and NukeProfilesMarkedForDeletion to -// esnure that Nuke happens before any Mark in this process. -base::SequencedTaskRunner* GetBackgroundDiskOperationTaskRunner() { - static const base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>> - task_runner(base::ThreadPool::CreateSingleThreadTaskRunner( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT})); - return task_runner.get()->get(); -} - -std::set<ProfileImpl*>& GetProfiles() { - static base::NoDestructor<std::set<ProfileImpl*>> s_all_profiles; - return *s_all_profiles; -} - -base::ObserverList<ProfileImpl::ProfileObserver>::Unchecked& GetObservers() { - static base::NoDestructor< - base::ObserverList<ProfileImpl::ProfileObserver>::Unchecked> - s_observers; - return *s_observers; -} - -#if BUILDFLAG(IS_ANDROID) -void PassFilePathsToJavaCallback( - const base::android::ScopedJavaGlobalRef<jobject>& callback, - const std::vector<std::string>& file_paths) { - base::android::RunObjectCallbackAndroid( - callback, base::android::ToJavaArrayOfStrings( - base::android::AttachCurrentThread(), file_paths)); -} - -void OnGotBrowserPersistenceIds( - const base::android::ScopedJavaGlobalRef<jobject>& callback, - base::flat_set<std::string> ids) { - std::vector<std::string> as_vector; - for (const std::string& id : ids) - as_vector.push_back(id); - base::android::RunObjectCallbackAndroid( - callback, - base::android::ToJavaArrayOfStrings(AttachCurrentThread(), as_vector)); -} - -void OnDidRemoveBrowserPersistenceStorage( - const base::android::ScopedJavaGlobalRef<jobject>& callback, - bool result) { - base::android::RunBooleanCallbackAndroid(callback, result); -} - -void OnDidGetCachedFaviconForPageUrl( - const base::android::ScopedJavaGlobalRef<jobject>& callback, - gfx::Image image) { - SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).GetBitmap(); - base::android::RunObjectCallbackAndroid( - callback, favicon.empty() ? nullptr : gfx::ConvertToJavaBitmap(favicon)); -} - -#endif // BUILDFLAG(IS_ANDROID) - -} // namespace - -class ProfileImpl::DataClearer : public content::BrowsingDataRemover::Observer { - public: - DataClearer(content::BrowserContext* browser_context, - base::OnceCallback<void()> callback) - : remover_(browser_context->GetBrowsingDataRemover()), - callback_(std::move(callback)) { - remover_->AddObserver(this); - } - - void ClearData(ProfileImpl* profile, - uint64_t mask, - base::Time from_time, - base::Time to_time) { - uint64_t origin_types = - content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | - content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; - remover_->RemoveAndReply(from_time, to_time, mask, origin_types, this); - } - - // content::BrowsingDataRemover::Observer: - void OnBrowsingDataRemoverDone(uint64_t failed_data_types) override { - // Remove the observer now as after this returns the BrowserContext may - // be destroyed, which owns |remover_|. - remover_->RemoveObserver(this); - std::move(callback_).Run(); - delete this; - } - - private: - // DataClearer deletes itself when removal is done. - ~DataClearer() override = default; - - raw_ptr<content::BrowsingDataRemover> remover_; - base::OnceCallback<void()> callback_; -}; - -// static -base::FilePath ProfileImpl::GetCachePath(content::BrowserContext* context) { - DCHECK(context); - ProfileImpl* profile = FromBrowserContext(context); - return profile->info_.cache_path; -} - -ProfileImpl::ProfileImpl(const std::string& name, bool is_incognito) - : download_directory_(BrowserContextImpl::GetDefaultDownloadDirectory()) { - { - base::ScopedAllowBlocking allow_blocking; - info_ = CreateProfileInfo(name, is_incognito); - } - - GetProfiles().insert(this); - profile_metrics::SetBrowserProfileType( - GetBrowserContext(), is_incognito - ? profile_metrics::BrowserProfileType::kIncognito - : profile_metrics::BrowserProfileType::kRegular); - - for (auto& observer : GetObservers()) - observer.ProfileCreated(this); - - if (!g_first_profile_created) { - g_first_profile_created = true; - GetBackgroundDiskOperationTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&NukeProfilesMarkedForDeletion)); - } - - // Ensure WebCacheManager is created so that it starts observing - // OnRenderProcessHostCreated events. - web_cache::WebCacheManager::GetInstance(); - -#if BUILDFLAG(IS_ANDROID) - WebLayerMetricsServiceClient::GetInstance()->UpdateUkm(false); -#endif -} - -ProfileImpl::~ProfileImpl() { - // Destroy any scheduled WebContents. These implicitly refer to the - // BrowserContext and must be destroyed before the BrowserContext. - web_contents_to_delete_.clear(); - - if (browser_context_) { - // Needs to be called before ShutdownStoragePartitions(). - browser_context_->NotifyWillBeDestroyed(); - - BrowserContextDependencyManager::GetInstance() - ->DestroyBrowserContextServices(browser_context_.get()); - browser_context_->ShutdownStoragePartitions(); - } - - GetProfiles().erase(this); - for (auto& observer : GetObservers()) - observer.ProfileDestroyed(this); -} - -ProfileImpl* ProfileImpl::FromBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<BrowserContextImpl*>(browser_context)->profile_impl(); -} - -std::set<ProfileImpl*> ProfileImpl::GetAllProfiles() { - return GetProfiles(); -} - -void ProfileImpl::AddProfileObserver(ProfileObserver* observer) { - GetObservers().AddObserver(observer); -} - -void ProfileImpl::RemoveProfileObserver(ProfileObserver* observer) { - GetObservers().RemoveObserver(observer); -} - -void ProfileImpl::DeleteWebContentsSoon( - std::unique_ptr<content::WebContents> web_contents) { - if (web_contents_to_delete_.empty()) { - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(&ProfileImpl::DeleteScheduleWebContents, - weak_ptr_factory_.GetWeakPtr())); - } - web_contents_to_delete_.push_back(std::move(web_contents)); -} - -BrowserContextImpl* ProfileImpl::GetBrowserContext() { - if (browser_context_) - return browser_context_.get(); - - browser_context_ = - std::make_unique<BrowserContextImpl>(this, info_.data_path); - locale_change_subscription_ = - i18n::RegisterLocaleChangeCallback(base::BindRepeating( - &ProfileImpl::OnLocaleChanged, base::Unretained(this))); - return browser_context_.get(); -} - -void ProfileImpl::DownloadsInitialized() { -#if BUILDFLAG(IS_ANDROID) - return Java_ProfileImpl_downloadsInitialized( - base::android::AttachCurrentThread(), java_profile_); -#endif -} - -void ProfileImpl::MarkAsDeleted() { - GetBackgroundDiskOperationTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&MarkProfileAsDeleted, info_)); -} - -void ProfileImpl::ClearBrowsingData( - const std::vector<BrowsingDataType>& data_types, - base::Time from_time, - base::Time to_time, - base::OnceClosure callback) { - auto* clearer = new DataClearer(GetBrowserContext(), std::move(callback)); - // DataClearer will delete itself in OnBrowsingDataRemoverDone(). - // If Profile is destroyed during clearing, it would lead to destroying - // browser_context_ and then BrowsingDataRemover, which in turn would call - // OnBrowsingDataRemoverDone(), even though the clearing hasn't been finished. - - uint64_t remove_mask = 0; - // This follows what Chrome does: see browsing_data_bridge.cc. - for (auto data_type : data_types) { - switch (data_type) { - case BrowsingDataType::COOKIES_AND_SITE_DATA: - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_COOKIES; - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE; - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES; - remove_mask |= BrowsingDataRemoverDelegate::DATA_TYPE_ISOLATED_ORIGINS; - remove_mask |= BrowsingDataRemoverDelegate::DATA_TYPE_FAVICONS; - remove_mask |= BrowsingDataRemoverDelegate::DATA_TYPE_AD_INTERVENTIONS; - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX; - break; - case BrowsingDataType::CACHE: - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_CACHE; - ClearRendererCache(); - break; - case BrowsingDataType::SITE_SETTINGS: - remove_mask |= BrowsingDataRemoverDelegate::DATA_TYPE_SITE_SETTINGS; - break; - default: - NOTREACHED(); - } - } - clearer->ClearData(this, remove_mask, from_time, to_time); -} - -void ProfileImpl::SetDownloadDirectory(const base::FilePath& directory) { - download_directory_ = directory; -} - -void ProfileImpl::SetDownloadDelegate(DownloadDelegate* delegate) { - download_delegate_ = delegate; -} - -void ProfileImpl::SetGoogleAccountAccessTokenFetchDelegate( - GoogleAccountAccessTokenFetchDelegate* delegate) { - access_token_fetch_delegate_ = delegate; -} - -CookieManager* ProfileImpl::GetCookieManager() { - if (!cookie_manager_) - cookie_manager_ = std::make_unique<CookieManagerImpl>(GetBrowserContext()); - return cookie_manager_.get(); -} - -PrerenderController* ProfileImpl::GetPrerenderController() { - if (!prerender_controller_) - prerender_controller_ = - std::make_unique<PrerenderControllerImpl>(GetBrowserContext()); - return prerender_controller_.get(); -} - -void ProfileImpl::GetBrowserPersistenceIds( - base::OnceCallback<void(base::flat_set<std::string>)> callback) { - DCHECK(!browser_context_->IsOffTheRecord()); - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&GetBrowserPersistenceIdsOnBackgroundThread, - GetBrowserPersisterDataBaseDir()), - std::move(callback)); -} - -void ProfileImpl::RemoveBrowserPersistenceStorage( - base::OnceCallback<void(bool)> done_callback, - base::flat_set<std::string> ids) { - DCHECK(!browser_context_->IsOffTheRecord()); - RemoveBrowserPersistenceStorageImpl(this, std::move(done_callback), - std::move(ids)); -} - -// static -void ProfileImpl::NukeDataAfterRemovingData( - std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback) { - // Need PostTask to avoid reentrancy for deleting |browser_context_|. - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&ProfileImpl::DoNukeData, std::move(profile), - std::move(done_callback))); -} - -// static -void ProfileImpl::DoNukeData(std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback) { - ProfileInfo info = profile->info_; - profile.reset(); - GetBackgroundDiskOperationTaskRunner()->PostTaskAndReply( - FROM_HERE, base::BindOnce(&TryNukeProfileFromDisk, info), - std::move(done_callback)); -} - -void ProfileImpl::ClearRendererCache() { - for (content::RenderProcessHost::iterator iter = - content::RenderProcessHost::AllHostsIterator(); - !iter.IsAtEnd(); iter.Advance()) { - content::RenderProcessHost* render_process_host = iter.GetCurrentValue(); - if (render_process_host->GetBrowserContext() == GetBrowserContext() && - render_process_host->IsInitializedAndNotDead()) { - web_cache::WebCacheManager::GetInstance()->ClearCacheForProcess( - render_process_host->GetID()); - } - } -} - -void ProfileImpl::OnLocaleChanged() { - GetBrowserContext()->ForEachLoadedStoragePartition(base::BindRepeating( - [](const std::string& accept_language, - content::StoragePartition* storage_partition) { - storage_partition->GetNetworkContext()->SetAcceptLanguage( - accept_language); - }, - i18n::GetAcceptLangs())); -} - -// static -std::unique_ptr<Profile> Profile::Create(const std::string& name, - bool is_incognito) { - return std::make_unique<ProfileImpl>(name, is_incognito); -} - -// static -std::unique_ptr<Profile> Profile::DestroyAndDeleteDataFromDisk( - std::unique_ptr<Profile> profile, - base::OnceClosure done_callback) { - std::unique_ptr<ProfileImpl> impl( - static_cast<ProfileImpl*>(profile.release())); - return ProfileImpl::DestroyAndDeleteDataFromDisk(std::move(impl), - std::move(done_callback)); -} - -// static -std::unique_ptr<ProfileImpl> ProfileImpl::DestroyAndDeleteDataFromDisk( - std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback) { - if (profile->GetNumberOfBrowsers() > 0) - return profile; - - ProfileInfo profile_info = profile->info_; - GetBackgroundDiskOperationTaskRunner()->PostTaskAndReply( - FROM_HERE, base::BindOnce(&MarkProfileAsDeleted, profile_info), - base::BindOnce(&ProfileImpl::OnProfileMarked, std::move(profile), - std::move(done_callback))); - return nullptr; -} - -// static -void ProfileImpl::OnProfileMarked(std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback) { - // Try to finish all writes and remove all data before nuking the profile. - profile->GetBrowserContext()->pref_service()->CommitPendingWrite(); - - ProfileImpl* raw_profile = profile.get(); - auto* clearer = new DataClearer( - raw_profile->GetBrowserContext(), - base::BindOnce(&ProfileImpl::NukeDataAfterRemovingData, - std::move(profile), std::move(done_callback))); - uint64_t remove_all_mask = 0xffffffffffffffffull; - clearer->ClearData(raw_profile, remove_all_mask, base::Time::Min(), - base::Time::Max()); -} - -#if BUILDFLAG(IS_ANDROID) -ProfileImpl::ProfileImpl( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& name, - const base::android::JavaParamRef<jobject>& java_profile, - bool is_incognito) - : ProfileImpl(ConvertJavaStringToUTF8(env, name), is_incognito) { - java_profile_ = java_profile; -} - -static jlong JNI_ProfileImpl_CreateProfile( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& name, - const base::android::JavaParamRef<jobject>& java_profile, - jboolean is_incognito) { - return reinterpret_cast<jlong>( - new ProfileImpl(env, name, java_profile, is_incognito)); -} - -static void JNI_ProfileImpl_DeleteProfile(JNIEnv* env, jlong profile) { - delete reinterpret_cast<ProfileImpl*>(profile); -} - -static void JNI_ProfileImpl_EnumerateAllProfileNames( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& callback) { - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&ListProfileNames), - base::BindOnce(&PassFilePathsToJavaCallback, - base::android::ScopedJavaGlobalRef<jobject>(callback))); -} - -jint ProfileImpl::GetNumBrowserImpl(JNIEnv* env) { - return GetNumberOfBrowsers(); -} - -jlong ProfileImpl::GetBrowserContext(JNIEnv* env) { - return reinterpret_cast<intptr_t>(GetBrowserContext()); -} - -void ProfileImpl::DestroyAndDeleteDataFromDisk( - JNIEnv* env, - const base::android::JavaRef<jobject>& j_completion_callback) { - std::unique_ptr<ProfileImpl> ptr(this); - std::unique_ptr<ProfileImpl> result = - ProfileImpl::DestroyAndDeleteDataFromDisk( - std::move(ptr), - base::BindOnce(&base::android::RunRunnableAndroid, - base::android::ScopedJavaGlobalRef<jobject>( - j_completion_callback))); - CHECK(!result); -} - -void ProfileImpl::ClearBrowsingData( - JNIEnv* env, - const base::android::JavaParamRef<jintArray>& j_data_types, - const jlong j_from_time_millis, - const jlong j_to_time_millis, - const base::android::JavaRef<jobject>& j_callback) { - std::vector<int> data_type_ints; - base::android::JavaIntArrayToIntVector(env, j_data_types, &data_type_ints); - std::vector<BrowsingDataType> data_types; - data_types.reserve(data_type_ints.size()); - for (int type : data_type_ints) - data_types.push_back(static_cast<BrowsingDataType>(type)); - ClearBrowsingData( - data_types, - base::Time::FromJavaTime(static_cast<int64_t>(j_from_time_millis)), - base::Time::FromJavaTime(static_cast<int64_t>(j_to_time_millis)), - base::BindOnce(base::android::RunRunnableAndroid, - base::android::ScopedJavaGlobalRef<jobject>(j_callback))); -} - -void ProfileImpl::SetDownloadDirectory( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& directory) { - base::FilePath directory_path( - base::android::ConvertJavaStringToUTF8(directory)); - - SetDownloadDirectory(directory_path); -} - -jlong ProfileImpl::GetCookieManager(JNIEnv* env) { - return reinterpret_cast<jlong>(GetCookieManager()); -} - -jlong ProfileImpl::GetPrerenderController(JNIEnv* env) { - return reinterpret_cast<jlong>(GetPrerenderController()); -} - -void ProfileImpl::EnsureBrowserContextInitialized(JNIEnv* env) { - GetBrowserContext()->GetDownloadManager(); -} - -void ProfileImpl::SetBooleanSetting(JNIEnv* env, - jint j_type, - jboolean j_value) { - SetBooleanSetting(static_cast<SettingType>(j_type), j_value); -} - -jboolean ProfileImpl::GetBooleanSetting(JNIEnv* env, jint j_type) { - return GetBooleanSetting(static_cast<SettingType>(j_type)); -} - -void ProfileImpl::GetBrowserPersistenceIds( - JNIEnv* env, - const base::android::JavaRef<jobject>& j_callback) { - GetBrowserPersistenceIds( - base::BindOnce(&OnGotBrowserPersistenceIds, - base::android::ScopedJavaGlobalRef<jobject>(j_callback))); -} - -void ProfileImpl::RemoveBrowserPersistenceStorage( - JNIEnv* env, - const base::android::JavaRef<jobjectArray>& j_ids, - const base::android::JavaRef<jobject>& j_callback) { - std::vector<std::string> ids; - base::android::AppendJavaStringArrayToStringVector(env, j_ids, &ids); - RemoveBrowserPersistenceStorage( - base::BindOnce(&OnDidRemoveBrowserPersistenceStorage, - base::android::ScopedJavaGlobalRef<jobject>(j_callback)), - base::flat_set<std::string>(ids.begin(), ids.end())); -} - -void ProfileImpl::PrepareForPossibleCrossOriginNavigation(JNIEnv* env) { - PrepareForPossibleCrossOriginNavigation(); -} - -void ProfileImpl::GetCachedFaviconForPageUrl( - JNIEnv* env, - const base::android::JavaRef<jstring>& j_page_url, - const base::android::JavaRef<jobject>& j_callback) { - GetCachedFaviconForPageUrl( - GURL(base::android::ConvertJavaStringToUTF8(j_page_url)), - base::BindOnce(&OnDidGetCachedFaviconForPageUrl, - base::android::ScopedJavaGlobalRef<jobject>(j_callback))); -} - -#endif // BUILDFLAG(IS_ANDROID) - -base::FilePath ProfileImpl::GetBrowserPersisterDataBaseDir() const { - return ComputeBrowserPersisterDataBaseDir(info_); -} - -content::WebContents* ProfileImpl::OpenUrl( - const content::OpenURLParams& params) { -#if !BUILDFLAG(IS_ANDROID) - return nullptr; -#else - // We expect only NEW_FOREGROUND_TAB. The NEW_POPUP disposition is only used - // for payment handler windows, but WebLayer (and Android Chrome) do not - // support that. See ContentBrowserClient::ShowPaymentHandlerWindow(). - DCHECK_EQ(params.disposition, WindowOpenDisposition::NEW_FOREGROUND_TAB); - - JNIEnv* env = base::android::AttachCurrentThread(); - BrowserImpl* browser = reinterpret_cast<BrowserImpl*>( - Java_ProfileImpl_getBrowserForNewTab(env, java_profile_)); - if (!browser) - return nullptr; - - std::unique_ptr<content::WebContents> new_tab_contents = - content::WebContents::Create( - content::WebContents::CreateParams(GetBrowserContext())); - base::WeakPtr<content::WebContents> new_tab_contents_weak_ptr( - new_tab_contents->GetWeakPtr()); - Tab* tab = browser->CreateTab(std::move(new_tab_contents)); - - if (!new_tab_contents_weak_ptr) - return nullptr; - - Java_ProfileImpl_onTabAdded(env, java_profile_, - static_cast<TabImpl*>(tab)->GetJavaTab()); - new_tab_contents_weak_ptr->GetController().LoadURLWithParams( - content::NavigationController::LoadURLParams(params)); - return new_tab_contents_weak_ptr.get(); -#endif // !BUILDFLAG(IS_ANDROID) -} - -void ProfileImpl::SetBooleanSetting(SettingType type, bool value) { - auto* pref_service = GetBrowserContext()->pref_service(); - switch (type) { - case SettingType::BASIC_SAFE_BROWSING_ENABLED: -#if BUILDFLAG(IS_ANDROID) - safe_browsing::SetSafeBrowsingState( - pref_service, - value ? safe_browsing::SafeBrowsingState::STANDARD_PROTECTION - : safe_browsing::SafeBrowsingState::NO_SAFE_BROWSING, - /*is_esb_enabled_in_sync=*/false); -#endif - break; - case SettingType::UKM_ENABLED: { -#if BUILDFLAG(IS_ANDROID) - bool old_value = pref_service->GetBoolean(prefs::kUkmEnabled); -#endif - pref_service->SetBoolean(prefs::kUkmEnabled, value); -#if BUILDFLAG(IS_ANDROID) - // Trigger a purge if the current state no longer allows UKM. - bool must_purge = old_value && !value; - WebLayerMetricsServiceClient::GetInstance()->UpdateUkm(must_purge); -#endif - break; - } - case SettingType::EXTENDED_REPORTING_SAFE_BROWSING_ENABLED: -#if BUILDFLAG(IS_ANDROID) - pref_service->SetBoolean(::prefs::kSafeBrowsingScoutReportingEnabled, - value); -#endif - break; - case SettingType::REAL_TIME_SAFE_BROWSING_ENABLED: -#if BUILDFLAG(IS_ANDROID) - pref_service->SetBoolean( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, - value); -#endif - break; - case SettingType::NETWORK_PREDICTION_ENABLED: - pref_service->SetBoolean(prefs::kNoStatePrefetchEnabled, value); - } -} - -bool ProfileImpl::GetBooleanSetting(SettingType type) { - auto* pref_service = GetBrowserContext()->pref_service(); - switch (type) { - case SettingType::BASIC_SAFE_BROWSING_ENABLED: -#if BUILDFLAG(IS_ANDROID) - return safe_browsing::IsSafeBrowsingEnabled(*pref_service); -#else - return false; -#endif - case SettingType::UKM_ENABLED: - return pref_service->GetBoolean(prefs::kUkmEnabled); - case SettingType::EXTENDED_REPORTING_SAFE_BROWSING_ENABLED: -#if BUILDFLAG(IS_ANDROID) - return pref_service->GetBoolean( - ::prefs::kSafeBrowsingScoutReportingEnabled); -#else - return false; -#endif - case SettingType::REAL_TIME_SAFE_BROWSING_ENABLED: -#if BUILDFLAG(IS_ANDROID) - return pref_service->GetBoolean( - unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled); -#else - return false; -#endif - case SettingType::NETWORK_PREDICTION_ENABLED: - return pref_service->GetBoolean(prefs::kNoStatePrefetchEnabled); - } - NOTREACHED(); -} - -void ProfileImpl::GetCachedFaviconForPageUrl( - const GURL& page_url, - base::OnceCallback<void(gfx::Image)> callback) { - auto* service = - FaviconServiceImplFactory::GetForBrowserContext(GetBrowserContext()); - if (!service) { - std::move(callback).Run({}); - return; - } - - service->GetFaviconForPageUrl(page_url, std::move(callback), - &cancelable_task_tracker_); -} - -void ProfileImpl::PrepareForPossibleCrossOriginNavigation() { - content::RenderProcessHost::WarmupSpareRenderProcessHost(GetBrowserContext()); -} - -int ProfileImpl::GetNumberOfBrowsers() { - const auto& browsers = BrowserList::GetInstance()->browsers(); - return base::ranges::count(browsers, this, &BrowserImpl::profile); -} - -void ProfileImpl::DeleteScheduleWebContents() { - web_contents_to_delete_.clear(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/profile_impl.h b/weblayer/browser/profile_impl.h deleted file mode 100644 index 0267abf..0000000 --- a/weblayer/browser/profile_impl.h +++ /dev/null
@@ -1,227 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PROFILE_IMPL_H_ -#define WEBLAYER_BROWSER_PROFILE_IMPL_H_ - -#include <set> -#include <vector> - -#include "base/files/file_path.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/task/cancelable_task_tracker.h" -#include "build/build_config.h" -#include "weblayer/browser/browser_list_observer.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/browser/profile_disk_operations.h" -#include "weblayer/public/profile.h" - -#if BUILDFLAG(IS_ANDROID) -#include <jni.h> -#include "base/android/scoped_java_ref.h" -#endif - -namespace content { -class BrowserContext; -class WebContents; -struct OpenURLParams; -} // namespace content - -namespace weblayer { -class BrowserContextImpl; -class CookieManagerImpl; -class PrerenderControllerImpl; - -class ProfileImpl : public Profile { - public: - // Return the cache directory path for this BrowserContext. On some - // platforms, file in cache directory may be deleted by the operating - // system. So it is suitable for storing data that can be recreated such - // as caches. - // |context| must not be null. - static base::FilePath GetCachePath(content::BrowserContext* context); - - static std::unique_ptr<ProfileImpl> DestroyAndDeleteDataFromDisk( - std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback); - - ProfileImpl(const std::string& name, bool is_incognito); - - ProfileImpl(const ProfileImpl&) = delete; - ProfileImpl& operator=(const ProfileImpl&) = delete; - - ~ProfileImpl() override; - - // Returns the ProfileImpl from the specified BrowserContext. - static ProfileImpl* FromBrowserContext( - content::BrowserContext* browser_context); - - static std::set<ProfileImpl*> GetAllProfiles(); - - // Allows getting notified when profiles are created or destroyed. - class ProfileObserver { - public: - virtual void ProfileCreated(ProfileImpl* profile) {} - virtual void ProfileDestroyed(ProfileImpl* profile) {} - - protected: - virtual ~ProfileObserver() = default; - }; - - static void AddProfileObserver(ProfileObserver* observer); - static void RemoveProfileObserver(ProfileObserver* observer); - - // Deletes |web_contents| after a delay. This is used if the owning Tab is - // deleted and it's not safe to delete the WebContents. - void DeleteWebContentsSoon( - std::unique_ptr<content::WebContents> web_contents); - - BrowserContextImpl* GetBrowserContext(); - - // Called when the download subsystem has finished initializing. By this point - // information about downloads that were interrupted by a previous crash would - // be available. - void DownloadsInitialized(); - - // Path data is stored at, empty if off-the-record. - const base::FilePath& data_path() const { return info_.data_path; } - const std::string& name() const { return info_.name; } - DownloadDelegate* download_delegate() { return download_delegate_; } - GoogleAccountAccessTokenFetchDelegate* access_token_fetch_delegate() { - return access_token_fetch_delegate_; - } - - void MarkAsDeleted(); - - // Profile implementation: - void ClearBrowsingData(const std::vector<BrowsingDataType>& data_types, - base::Time from_time, - base::Time to_time, - base::OnceClosure callback) override; - void SetDownloadDirectory(const base::FilePath& directory) override; - void SetDownloadDelegate(DownloadDelegate* delegate) override; - void SetGoogleAccountAccessTokenFetchDelegate( - GoogleAccountAccessTokenFetchDelegate* delegate) override; - CookieManager* GetCookieManager() override; - PrerenderController* GetPrerenderController() override; - void GetBrowserPersistenceIds( - base::OnceCallback<void(base::flat_set<std::string>)> callback) override; - void RemoveBrowserPersistenceStorage( - base::OnceCallback<void(bool)> done_callback, - base::flat_set<std::string> ids) override; - void SetBooleanSetting(SettingType type, bool value) override; - bool GetBooleanSetting(SettingType type) override; - void GetCachedFaviconForPageUrl( - const GURL& page_url, - base::OnceCallback<void(gfx::Image)> callback) override; - void PrepareForPossibleCrossOriginNavigation() override; - -#if BUILDFLAG(IS_ANDROID) - ProfileImpl(JNIEnv* env, - const base::android::JavaParamRef<jstring>& path, - const base::android::JavaParamRef<jobject>& java_profile, - bool is_incognito); - - jint GetNumBrowserImpl(JNIEnv* env); - jlong GetBrowserContext(JNIEnv* env); - void DestroyAndDeleteDataFromDisk( - JNIEnv* env, - const base::android::JavaRef<jobject>& j_completion_callback); - void ClearBrowsingData( - JNIEnv* env, - const base::android::JavaParamRef<jintArray>& j_data_types, - const jlong j_from_time_millis, - const jlong j_to_time_millis, - const base::android::JavaRef<jobject>& j_callback); - void SetDownloadDirectory( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& directory); - jlong GetCookieManager(JNIEnv* env); - jlong GetPrerenderController(JNIEnv* env); - void EnsureBrowserContextInitialized(JNIEnv* env); - void SetBooleanSetting(JNIEnv* env, jint j_type, jboolean j_value); - jboolean GetBooleanSetting(JNIEnv* env, jint j_type); - void GetBrowserPersistenceIds( - JNIEnv* env, - const base::android::JavaRef<jobject>& j_callback); - void RemoveBrowserPersistenceStorage( - JNIEnv* env, - const base::android::JavaRef<jobjectArray>& j_ids, - const base::android::JavaRef<jobject>& j_callback); - void PrepareForPossibleCrossOriginNavigation(JNIEnv* env); - void GetCachedFaviconForPageUrl( - JNIEnv* env, - const base::android::JavaRef<jstring>& j_page_url, - const base::android::JavaRef<jobject>& j_callback); - void MarkAsDeleted(JNIEnv* env) { MarkAsDeleted(); } - base::android::ScopedJavaGlobalRef<jobject> GetJavaProfile() { - return java_profile_; - } -#endif - - const base::FilePath& download_directory() { return download_directory_; } - - // Get the directory where BrowserPersister stores tab state data. This will - // be a real file path even for the off-the-record profile. - base::FilePath GetBrowserPersisterDataBaseDir() const; - - // Creates a new web contents and navigates it according to `params`, but only - // if an OpenUrlCallback has been set by the embedder. This is used for - // navigations originating from service workers, which don't necessarily have - // an associated tab. It may return null if the operation fails. - content::WebContents* OpenUrl(const content::OpenURLParams& params); - - private: - class DataClearer; - - static void OnProfileMarked(std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback); - static void NukeDataAfterRemovingData(std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback); - static void DoNukeData(std::unique_ptr<ProfileImpl> profile, - base::OnceClosure done_callback); - void ClearRendererCache(); - - // Callback when the system locale has been updated. - void OnLocaleChanged(); - - // Returns the number of Browsers with this profile. - int GetNumberOfBrowsers(); - - void DeleteScheduleWebContents(); - - ProfileInfo info_; - - std::unique_ptr<BrowserContextImpl> browser_context_; - - base::FilePath download_directory_; - - raw_ptr<DownloadDelegate> download_delegate_ = nullptr; - raw_ptr<GoogleAccountAccessTokenFetchDelegate> access_token_fetch_delegate_ = - nullptr; - - base::CallbackListSubscription locale_change_subscription_; - - std::unique_ptr<CookieManagerImpl> cookie_manager_; - std::unique_ptr<PrerenderControllerImpl> prerender_controller_; - -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> java_profile_; -#endif - - // The typical pattern for CancelableTaskTrackers is to have the caller - // supply one. This code is predominantly called from the Java side, where - // CancelableTaskTracker isn't applicable. Because of this, the - // CancelableTaskTracker is owned by Profile. - base::CancelableTaskTracker cancelable_task_tracker_; - - std::vector<std::unique_ptr<content::WebContents>> web_contents_to_delete_; - - base::WeakPtrFactory<ProfileImpl> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PROFILE_IMPL_H_
diff --git a/weblayer/browser/proxying_url_loader_factory_impl.cc b/weblayer/browser/proxying_url_loader_factory_impl.cc deleted file mode 100644 index 596fb204..0000000 --- a/weblayer/browser/proxying_url_loader_factory_impl.cc +++ /dev/null
@@ -1,273 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/proxying_url_loader_factory_impl.h" - -#include "base/time/time.h" -#include "components/embedder_support/android/util/android_stream_reader_url_loader.h" -#include "components/embedder_support/android/util/response_delegate_impl.h" -#include "components/embedder_support/android/util/web_resource_response.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/web_contents.h" -#include "mojo/public/cpp/system/data_pipe_producer.h" -#include "mojo/public/cpp/system/string_data_source.h" -#include "weblayer/browser/navigation_entry_data.h" - -namespace weblayer { - -namespace { - -struct WriteData { - mojo::Remote<network::mojom::URLLoaderClient> client; - std::string data; - std::unique_ptr<mojo::DataPipeProducer> producer; -}; - -void OnWrite(std::unique_ptr<WriteData> write_data, MojoResult result) { - if (result != MOJO_RESULT_OK) { - write_data->client->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_FAILED)); - return; - } - - network::URLLoaderCompletionStatus status(net::OK); - status.encoded_data_length = write_data->data.size(); - status.encoded_body_length = write_data->data.size(); - status.decoded_body_length = write_data->data.size(); - write_data->client->OnComplete(status); -} - -void StartCachedLoad( - mojo::PendingRemote<network::mojom::URLLoaderClient> pending_client, - network::mojom::URLResponseHeadPtr response_head, - const std::string& data) { - mojo::Remote<network::mojom::URLLoaderClient> client( - std::move(pending_client)); - - mojo::ScopedDataPipeProducerHandle producer; - mojo::ScopedDataPipeConsumerHandle consumer; - if (CreateDataPipe(nullptr, producer, consumer) != MOJO_RESULT_OK) { - client->OnComplete( - network::URLLoaderCompletionStatus(net::ERR_INSUFFICIENT_RESOURCES)); - return; - } - - client->OnReceiveResponse(std::move(response_head), std::move(consumer), - absl::nullopt); - - auto write_data = std::make_unique<WriteData>(); - write_data->client = std::move(client); - write_data->data = std::move(data); - write_data->producer = - std::make_unique<mojo::DataPipeProducer>(std::move(producer)); - - mojo::DataPipeProducer* producer_ptr = write_data->producer.get(); - base::StringPiece string_piece(write_data->data); - - producer_ptr->Write( - std::make_unique<mojo::StringDataSource>( - string_piece, mojo::StringDataSource::AsyncWritingMode:: - STRING_STAYS_VALID_UNTIL_COMPLETION), - base::BindOnce(OnWrite, std::move(write_data))); -} - -// Returns a NavigationEntry (pending or committed) for the given id if it -// exists. -content::NavigationEntry* GetNavigationEntryFromUniqueId( - int frame_tree_node_id, - int navigation_entry_unique_id) { - auto* web_contents = - content::WebContents::FromFrameTreeNodeId(frame_tree_node_id); - if (!web_contents) - return nullptr; - auto& controller = web_contents->GetController(); - auto* pending_entry = controller.GetPendingEntry(); - if (pending_entry && - pending_entry->GetUniqueID() == navigation_entry_unique_id) { - return pending_entry; - } - - // Entry might have committed. - for (int i = 0; i < controller.GetEntryCount(); ++i) { - if (controller.GetEntryAtIndex(i)->GetUniqueID() == - navigation_entry_unique_id) - return controller.GetEntryAtIndex(i); - } - - return nullptr; -} - -// Returns true if the response headers indicate that the response is still -// valid without going over the network. -bool IsCachedResponseValid(net::HttpResponseHeaders* headers, - base::Time request_time, - base::Time response_time) { - return headers->RequiresValidation(request_time, response_time, - base::Time::Now()) == net::VALIDATION_NONE; -} - -// A ResponseDelegate for AndroidStreamReaderURLLoader which will cache the -// response if it's successful. This allows back-forward navigations to reuse an -// InputStream. -class CachingResponseDelegate : public embedder_support::ResponseDelegateImpl { - public: - CachingResponseDelegate( - std::unique_ptr<embedder_support::WebResourceResponse> response, - int frame_tree_node_id, - int navigation_entry_unique_id) - : ResponseDelegateImpl(std::move(response)), - frame_tree_node_id_(frame_tree_node_id), - navigation_entry_unique_id_(navigation_entry_unique_id), - request_time_(base::Time::Now()) {} - - ~CachingResponseDelegate() override = default; - - // embedder_support::ResponseDelegateImpl implementation: - bool ShouldCacheResponse(network::mojom::URLResponseHead* response) override { - response_time_ = base::Time::Now(); - - // If at this point the response isn't cacheable it'll never be. - if (!IsCachedResponseValid(response->headers.get(), request_time_, - response_time_)) { - return false; - } - - response_head_ = response->Clone(); - return true; - } - - void OnResponseCache(const std::string& data) override { - content::NavigationEntry* entry = GetNavigationEntryFromUniqueId( - frame_tree_node_id_, navigation_entry_unique_id_); - if (!entry) - return; - - auto* entry_data = NavigationEntryData::Get(entry); - auto response_data = std::make_unique<NavigationEntryData::ResponseData>(); - response_data->response_head = std::move(response_head_); - response_data->data = data; - response_data->request_time = request_time_; - response_data->response_time = response_time_; - entry_data->set_response_data(std::move(response_data)); - } - - private: - int frame_tree_node_id_; - int navigation_entry_unique_id_; - - // The time that this object was created. - base::Time request_time_; - // The time that we sent the response headers. - base::Time response_time_; - - network::mojom::URLResponseHeadPtr response_head_; -}; - -} // namespace - -ProxyingURLLoaderFactoryImpl::ProxyingURLLoaderFactoryImpl( - mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver, - mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_remote, - const GURL& url_for_response, - std::unique_ptr<embedder_support::WebResourceResponse> response, - int frame_tree_node_id, - int navigation_entry_unique_id) - : url_for_response_(url_for_response), - response_(std::move(response)), - frame_tree_node_id_(frame_tree_node_id), - navigation_entry_unique_id_(navigation_entry_unique_id) { - DCHECK(response_ || - HasCachedInputStream(frame_tree_node_id, navigation_entry_unique_id)); - target_factory_.Bind(std::move(target_factory_remote)); - target_factory_.set_disconnect_handler( - base::BindOnce(&ProxyingURLLoaderFactoryImpl::OnTargetFactoryError, - base::Unretained(this))); - - proxy_receivers_.Add(this, std::move(loader_receiver)); - proxy_receivers_.set_disconnect_handler( - base::BindRepeating(&ProxyingURLLoaderFactoryImpl::OnProxyBindingError, - base::Unretained(this))); -} - -ProxyingURLLoaderFactoryImpl::~ProxyingURLLoaderFactoryImpl() = default; - -bool ProxyingURLLoaderFactoryImpl::HasCachedInputStream( - int frame_tree_node_id, - int navigation_entry_unique_id) { - auto* entry = GetNavigationEntryFromUniqueId(frame_tree_node_id, - navigation_entry_unique_id); - if (!entry) - return false; - - auto* entry_data = NavigationEntryData::Get(entry); - if (!entry_data) - return false; - - auto* response_data = entry_data->response_data(); - if (!response_data) - return false; - - if (!IsCachedResponseValid(response_data->response_head->headers.get(), - response_data->request_time, - response_data->response_time)) { - // Cache expired so remove it. - entry_data->reset_response_data(); - return false; - } - - return true; -} - -void ProxyingURLLoaderFactoryImpl::CreateLoaderAndStart( - mojo::PendingReceiver<network::mojom::URLLoader> loader, - int32_t request_id, - uint32_t options, - const network::ResourceRequest& request, - mojo::PendingRemote<network::mojom::URLLoaderClient> client, - const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { - if (url_for_response_ == request.url) { - if (response_) { - auto* stream_loader = new embedder_support::AndroidStreamReaderURLLoader( - request, std::move(client), traffic_annotation, - std::make_unique<CachingResponseDelegate>( - std::move(response_), frame_tree_node_id_, - navigation_entry_unique_id_), - absl::nullopt); - stream_loader->Start(); - return; - } - - if (HasCachedInputStream(frame_tree_node_id_, - navigation_entry_unique_id_)) { - auto* entry = GetNavigationEntryFromUniqueId(frame_tree_node_id_, - navigation_entry_unique_id_); - auto* entry_data = NavigationEntryData::Get(entry); - auto* response_data = entry_data->response_data(); - StartCachedLoad(std::move(client), response_data->response_head->Clone(), - response_data->data); - return; - } - } - - target_factory_->CreateLoaderAndStart(std::move(loader), request_id, options, - request, std::move(client), - traffic_annotation); -} - -void ProxyingURLLoaderFactoryImpl::Clone( - mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver) { - proxy_receivers_.Add(this, std::move(loader_receiver)); -} - -void ProxyingURLLoaderFactoryImpl::OnTargetFactoryError() { - delete this; -} - -void ProxyingURLLoaderFactoryImpl::OnProxyBindingError() { - if (proxy_receivers_.empty()) - delete this; -} - -} // namespace weblayer
diff --git a/weblayer/browser/proxying_url_loader_factory_impl.h b/weblayer/browser/proxying_url_loader_factory_impl.h deleted file mode 100644 index 865b523..0000000 --- a/weblayer/browser/proxying_url_loader_factory_impl.h +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_PROXYING_URL_LOADER_FACTORY_IMPL_H_ -#define WEBLAYER_BROWSER_PROXYING_URL_LOADER_FACTORY_IMPL_H_ - -#include "mojo/public/cpp/bindings/receiver_set.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "services/network/public/mojom/url_loader_factory.mojom.h" -#include "url/gurl.h" - -namespace embedder_support { -class WebResourceResponse; -} - -namespace weblayer { - -// Used to service navigations when the WebResourceResponse was specified. -// Otherwise it will forward the request to the original URLLoaderFactory. -class ProxyingURLLoaderFactoryImpl : public network::mojom::URLLoaderFactory { - public: - ProxyingURLLoaderFactoryImpl( - mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver, - mojo::PendingRemote<network::mojom::URLLoaderFactory> - target_factory_remote, - const GURL& url_for_response, - std::unique_ptr<embedder_support::WebResourceResponse> response, - int frame_tree_node_id, - int navigation_entry_unique_id); - - ProxyingURLLoaderFactoryImpl(const ProxyingURLLoaderFactoryImpl&) = delete; - ProxyingURLLoaderFactoryImpl& operator=(const ProxyingURLLoaderFactoryImpl&) = - delete; - - static bool HasCachedInputStream(int frame_tree_node_id, - int navigation_entry_unique_id); - - void CreateLoaderAndStart( - mojo::PendingReceiver<network::mojom::URLLoader> loader, - int32_t request_id, - uint32_t options, - const network::ResourceRequest& request, - mojo::PendingRemote<network::mojom::URLLoaderClient> client, - const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) - override; - void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> - loader_receiver) override; - - private: - ~ProxyingURLLoaderFactoryImpl() override; - void OnTargetFactoryError(); - void OnProxyBindingError(); - - mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_; - mojo::Remote<network::mojom::URLLoaderFactory> target_factory_; - GURL url_for_response_; - std::unique_ptr<embedder_support::WebResourceResponse> response_; - const int frame_tree_node_id_; - const int navigation_entry_unique_id_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_PROXYING_URL_LOADER_FACTORY_IMPL_H_
diff --git a/weblayer/browser/reduce_accept_language_factory.cc b/weblayer/browser/reduce_accept_language_factory.cc deleted file mode 100644 index 827f34dd..0000000 --- a/weblayer/browser/reduce_accept_language_factory.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/reduce_accept_language_factory.h" - -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/reduce_accept_language/browser/reduce_accept_language_service.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -reduce_accept_language::ReduceAcceptLanguageService* -ReduceAcceptLanguageFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<reduce_accept_language::ReduceAcceptLanguageService*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -ReduceAcceptLanguageFactory* ReduceAcceptLanguageFactory::GetInstance() { - static base::NoDestructor<ReduceAcceptLanguageFactory> instance; - return instance.get(); -} - -ReduceAcceptLanguageFactory::ReduceAcceptLanguageFactory() - : BrowserContextKeyedServiceFactory( - "ReduceAcceptLanguage", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -ReduceAcceptLanguageFactory::~ReduceAcceptLanguageFactory() = default; - -std::unique_ptr<KeyedService> -ReduceAcceptLanguageFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<reduce_accept_language::ReduceAcceptLanguageService>( - HostContentSettingsMapFactory::GetForBrowserContext(context), - static_cast<BrowserContextImpl*>(context)->pref_service(), - context->IsOffTheRecord()); -} - -content::BrowserContext* ReduceAcceptLanguageFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/reduce_accept_language_factory.h b/weblayer/browser/reduce_accept_language_factory.h deleted file mode 100644 index 9dedb359..0000000 --- a/weblayer/browser/reduce_accept_language_factory.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_REDUCE_ACCEPT_LANGUAGE_FACTORY_H_ -#define WEBLAYER_BROWSER_REDUCE_ACCEPT_LANGUAGE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" -#include "components/reduce_accept_language/browser/reduce_accept_language_service.h" -#include "content/public/browser/reduce_accept_language_controller_delegate.h" - -namespace weblayer { - -class ReduceAcceptLanguageFactory : public BrowserContextKeyedServiceFactory { - public: - static reduce_accept_language::ReduceAcceptLanguageService* - GetForBrowserContext(content::BrowserContext* context); - - static ReduceAcceptLanguageFactory* GetInstance(); - - // Non-copyable, non-moveable. - ReduceAcceptLanguageFactory(const ReduceAcceptLanguageFactory&) = delete; - ReduceAcceptLanguageFactory& operator=(const ReduceAcceptLanguageFactory&) = - delete; - - private: - friend base::NoDestructor<ReduceAcceptLanguageFactory>; - - ReduceAcceptLanguageFactory(); - ~ReduceAcceptLanguageFactory() override; - - // BrowserContextKeyedServiceFactory methods: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_REDUCE_ACCEPT_LANGUAGE_FACTORY_H_
diff --git a/weblayer/browser/reduce_accept_language_service_browsertest.cc b/weblayer/browser/reduce_accept_language_service_browsertest.cc deleted file mode 100644 index 83fe91b..0000000 --- a/weblayer/browser/reduce_accept_language_service_browsertest.cc +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/language/core/browser/language_prefs.h" -#include "components/language/core/browser/pref_names.h" -#include "components/prefs/pref_service.h" -#include "components/reduce_accept_language/browser/reduce_accept_language_service.h" -#include "components/reduce_accept_language/browser/reduce_accept_language_service_test_util.h" -#include "url/gurl.h" -#include "url/origin.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/reduce_accept_language_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -using reduce_accept_language::test::ReduceAcceptLanguageServiceTester; - -namespace weblayer { - -class ReduceAcceptLanguageServiceTest : public WebLayerBrowserTest { - public: - void SetUpOnMainThread() override { - WebLayerBrowserTest::SetUpOnMainThread(); - service_tester_ = std::make_unique<ReduceAcceptLanguageServiceTester>( - settings_map(), service(), prefs()); - language::LanguagePrefs(prefs()).SetUserSelectedLanguagesList( - {"en", "ja", "it"}); - } - - content::WebContents* web_contents() { - return static_cast<TabImpl*>(shell()->tab())->web_contents(); - } - - HostContentSettingsMap* settings_map() { - return HostContentSettingsMapFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); - } - - PrefService* prefs() { - return static_cast<BrowserContextImpl*>(web_contents()->GetBrowserContext()) - ->pref_service(); - } - - reduce_accept_language::ReduceAcceptLanguageService* service() { - return ReduceAcceptLanguageFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); - } - - ReduceAcceptLanguageServiceTester* tester() { return service_tester_.get(); } - - private: - std::unique_ptr<ReduceAcceptLanguageServiceTester> service_tester_; -}; - -IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest, GetAcceptLanguageList) { - tester()->VerifyFetchAcceptLanguageList({"en", "ja", "it"}); - reduce_accept_language::ReduceAcceptLanguageService incognito_service( - settings_map(), prefs(), true); - // Verify incognito mode only has first accept language. - EXPECT_EQ(std::vector<std::string>{"en"}, - incognito_service.GetUserAcceptLanguages()); -} - -IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest, PersistLanguageFail) { - tester()->VerifyPersistFail(GURL("ws://example.com/"), "Zh-CN"); -} - -IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest, - PersistLanguageSuccessJavaScriptNotEnabled) { - tester()->VerifyPersistSuccessOnJavaScriptDisable( - GURL("https://example.com/"), "Zh-CN"); -} - -IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest, - PersistLanguageSuccess) { - tester()->VerifyPersistSuccess(GURL("https://example.com/"), "Zh-CN"); -} - -IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest, - PersistLanguageMultipleHosts) { - tester()->VerifyPersistMultipleHostsSuccess( - {GURL("https://example1.com/"), GURL("https://example2.com/"), - GURL("http://example.com/")}, - {"en-US", "es-MX", "zh-CN"}); -} - -} // namespace weblayer
diff --git a/weblayer/browser/resources/weblayer_internals/weblayer_internals.html b/weblayer/browser/resources/weblayer_internals/weblayer_internals.html deleted file mode 100644 index 0d23f12..0000000 --- a/weblayer/browser/resources/weblayer_internals/weblayer_internals.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!doctype html> -<html lang="en" dir="ltr"> - <head> - <meta charset="utf-8"> - <title>WebLayer Internals</title> - <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> - <script type="module" src="weblayer_internals.js"></script> - </head> - <body> - <h1>WebLayer Internals</h1> - <div> - <label id="remote-debug-label" hidden> - <input type="checkbox" id="remote-debug"> - Enable remote debugging - </label> - </div> - </body> -</html>
diff --git a/weblayer/browser/resources/weblayer_internals/weblayer_internals.js b/weblayer/browser/resources/weblayer_internals/weblayer_internals.js deleted file mode 100644 index a6156dc..0000000 --- a/weblayer/browser/resources/weblayer_internals/weblayer_internals.js +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* Javascript module for chrome://weblayer. */ - -import {isAndroid} from 'chrome://resources/js/platform.js'; -import {$} from 'chrome://resources/js/util_ts.js'; - -import {PageHandler} from './weblayer_internals.mojom-webui.js'; - -/* Main entry point. */ -window.document.addEventListener('DOMContentLoaded', async function() { - // Setup backend mojo. - const pageHandler = PageHandler.getRemote(); - if (isAndroid) { - const {enabled} = await pageHandler.getRemoteDebuggingEnabled(); - const checkbox = $('remote-debug'); - checkbox.checked = enabled; - checkbox.addEventListener('click', (event) => { - pageHandler.setRemoteDebuggingEnabled(event.target.checked); - }); - - $('remote-debug-label').removeAttribute('hidden'); - } -});
diff --git a/weblayer/browser/safe_browsing/DEPS b/weblayer/browser/safe_browsing/DEPS deleted file mode 100644 index 031570e07..0000000 --- a/weblayer/browser/safe_browsing/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - "+components/safe_browsing/content/browser", - "+components/safe_browsing/content/common", - "+services/network/test", -]
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc b/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc deleted file mode 100644 index 202c517..0000000 --- a/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" - -#include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/content/browser/client_side_detection_service.h" -#include "components/safe_browsing/content/browser/client_side_phishing_model.h" -#include "components/safe_browsing/content/common/safe_browsing.mojom.h" -#include "components/safe_browsing/core/common/proto/client_model.pb.h" -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "content/public/test/browser_test.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/common/features.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -using safe_browsing::ClientSideDetectionService; -using safe_browsing::ClientSideModel; -using safe_browsing::ClientSidePhishingModel; -using ::testing::_; -using ::testing::ReturnRef; -using ::testing::StrictMock; - -class ClientSideDetectionServiceBrowserTest : public WebLayerBrowserTest { - public: - ClientSideDetectionServiceBrowserTest() { - feature_list_.InitAndEnableFeature( - features::kWebLayerClientSidePhishingDetection); - } - content::WebContents* GetWebContents() { - return static_cast<TabImpl*>(shell()->tab())->web_contents(); - } - - private: - void SetUpOnMainThread() override { - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - } - base::test::ScopedFeatureList feature_list_; -}; - -// TODO(crbug.com/1217128): Re-enable this test, once we have a more reliable -// method of ensuring the SetPhishingModel IPC comes before the -// StartPhishingDetection IPC. -IN_PROC_BROWSER_TEST_F(ClientSideDetectionServiceBrowserTest, - DISABLED_NewHostGetsModel) { - PrefService* prefs = GetProfile()->GetBrowserContext()->pref_service(); - prefs->SetBoolean(::prefs::kSafeBrowsingEnabled, false); - - ClientSideModel model; - model.set_max_words_per_term(0); - std::string model_str; - model.SerializeToString(&model_str); - - ClientSidePhishingModel::GetInstance()->SetModelStrForTesting(model_str); - - // Enable Safe Browsing and the CSD service. - prefs->SetBoolean(::prefs::kSafeBrowsingEnabled, true); - - base::RunLoop run_loop; - - content::RenderFrameHost* rfh = GetWebContents()->GetPrimaryMainFrame(); - mojo::Remote<safe_browsing::mojom::PhishingDetector> phishing_detector; - rfh->GetRemoteInterfaces()->GetInterface( - phishing_detector.BindNewPipeAndPassReceiver()); - - safe_browsing::mojom::PhishingDetectorResult result; - std::string verdict; - phishing_detector->StartPhishingDetection( - GURL("about:blank"), - base::BindOnce( - [](base::RepeatingClosure quit_closure, - safe_browsing::mojom::PhishingDetectorResult* out_result, - std::string* out_verdict, - safe_browsing::mojom::PhishingDetectorResult result, - const std::string& verdict) { - *out_result = result; - *out_verdict = verdict; - quit_closure.Run(); - }, - run_loop.QuitClosure(), &result, &verdict)); - - run_loop.Run(); - - // The model classification will run, but will return an invalid score. - EXPECT_EQ(result, - safe_browsing::mojom::PhishingDetectorResult::INVALID_SCORE); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_factory.cc b/weblayer/browser/safe_browsing/client_side_detection_service_factory.cc deleted file mode 100644 index 3db1a088..0000000 --- a/weblayer/browser/safe_browsing/client_side_detection_service_factory.cc +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/safe_browsing/content/browser/client_side_detection_service.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/feature_list_creator.h" -#include "weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.h" -#include "weblayer/common/features.h" - -namespace weblayer { - -// static -safe_browsing::ClientSideDetectionService* -ClientSideDetectionServiceFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - if (base::FeatureList::IsEnabled( - features::kWebLayerClientSidePhishingDetection)) { - return static_cast<safe_browsing::ClientSideDetectionService*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - /* create= */ true)); - } - return nullptr; -} - -// static -ClientSideDetectionServiceFactory* -ClientSideDetectionServiceFactory::GetInstance() { - static base::NoDestructor<ClientSideDetectionServiceFactory> factory; - return factory.get(); -} - -ClientSideDetectionServiceFactory::ClientSideDetectionServiceFactory() - : BrowserContextKeyedServiceFactory( - "ClientSideDetectionService", - BrowserContextDependencyManager::GetInstance()) {} - -ClientSideDetectionServiceFactory::~ClientSideDetectionServiceFactory() = - default; - -std::unique_ptr<KeyedService> -ClientSideDetectionServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<safe_browsing::ClientSideDetectionService>( - std::make_unique<WebLayerClientSideDetectionServiceDelegate>( - static_cast<BrowserContextImpl*>(context)), - /*opt_guide=*/nullptr, - /*background_task_runner=*/nullptr); -} - -content::BrowserContext* -ClientSideDetectionServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_factory.h b/weblayer/browser/safe_browsing/client_side_detection_service_factory.h deleted file mode 100644 index e5b5de729..0000000 --- a/weblayer/browser/safe_browsing/client_side_detection_service_factory.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class KeyedService; - -namespace content { -class BrowserContext; -} - -namespace safe_browsing { -class ClientSideDetectionService; -} - -namespace weblayer { - -// Singleton that owns ClientSideDetectionServiceFactory objects and associates -// them them with BrowserContextImpl instances. -class ClientSideDetectionServiceFactory - : public BrowserContextKeyedServiceFactory { - public: - ClientSideDetectionServiceFactory(const ClientSideDetectionServiceFactory&) = - delete; - ClientSideDetectionServiceFactory& operator=( - const ClientSideDetectionServiceFactory&) = delete; - - // Creates the service if it doesn't exist already for the given - // |browser_context|. If the service already exists, return its pointer. - static safe_browsing::ClientSideDetectionService* GetForBrowserContext( - content::BrowserContext* browser_context); - - // Get the singleton instance. - static ClientSideDetectionServiceFactory* GetInstance(); - - private: - friend class base::NoDestructor<ClientSideDetectionServiceFactory>; - - ClientSideDetectionServiceFactory(); - ~ClientSideDetectionServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/safe_browsing/client_side_detection_service_factory_browsertest.cc b/weblayer/browser/safe_browsing/client_side_detection_service_factory_browsertest.cc deleted file mode 100644 index cf644ee0..0000000 --- a/weblayer/browser/safe_browsing/client_side_detection_service_factory_browsertest.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" - -#include "base/test/scoped_feature_list.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/common/features.h" -#include "weblayer/test/weblayer_browser_test.h" - -namespace weblayer { - -class ClientSideDetectionServiceFactoryBrowserTest - : public WebLayerBrowserTest { - public: - ClientSideDetectionServiceFactoryBrowserTest() { - feature_list_.InitAndDisableFeature( - features::kWebLayerClientSidePhishingDetection); - } - - private: - void SetUpOnMainThread() override {} - base::test::ScopedFeatureList feature_list_; -}; - -IN_PROC_BROWSER_TEST_F(ClientSideDetectionServiceFactoryBrowserTest, - ClientDetectionServiceNullWhenDisabled) { - EXPECT_EQ(nullptr, ClientSideDetectionServiceFactory::GetForBrowserContext( - GetProfile()->GetBrowserContext())); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.cc b/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.cc deleted file mode 100644 index 5c7782e..0000000 --- a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h" - -#include "base/functional/bind.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/safe_browsing/core/browser/realtime/url_lookup_service.h" -#include "components/safe_browsing/core/browser/safe_browsing_token_fetcher.h" -#include "components/safe_browsing/core/common/utils.h" -#include "content/public/browser/browser_context.h" -#include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/feature_list_creator.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#include "weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h" -#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" -#include "weblayer/browser/verdict_cache_manager_factory.h" - -namespace weblayer { - -// static -safe_browsing::RealTimeUrlLookupService* -RealTimeUrlLookupServiceFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<safe_browsing::RealTimeUrlLookupService*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - /* create= */ true)); -} - -// static -RealTimeUrlLookupServiceFactory* -RealTimeUrlLookupServiceFactory::GetInstance() { - return base::Singleton<RealTimeUrlLookupServiceFactory>::get(); -} - -RealTimeUrlLookupServiceFactory::RealTimeUrlLookupServiceFactory() - : BrowserContextKeyedServiceFactory( - "RealTimeUrlLookupService", - BrowserContextDependencyManager::GetInstance()) {} - -std::unique_ptr<KeyedService> -RealTimeUrlLookupServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - auto url_loader_factory = - std::make_unique<network::CrossThreadPendingSharedURLLoaderFactory>( - BrowserProcess::GetInstance() - ->GetSafeBrowsingService() - ->GetURLLoaderFactory()); - - return std::make_unique<safe_browsing::RealTimeUrlLookupService>( - network::SharedURLLoaderFactory::Create(std::move(url_loader_factory)), - VerdictCacheManagerFactory::GetForBrowserContext(context), - base::BindRepeating(&GetUserPopulationForBrowserContext, context), - static_cast<BrowserContextImpl*>(context)->pref_service(), - std::make_unique<SafeBrowsingTokenFetcherImpl>(base::BindRepeating( - &ProfileImpl::access_token_fetch_delegate, - base::Unretained(ProfileImpl::FromBrowserContext(context)))), - // TODO(crbug.com/1171215): Change this to production mechanism for - // enabling Gaia-keyed URL lookups once that mechanism is determined. - base::BindRepeating(&RealTimeUrlLookupServiceFactory:: - access_token_fetches_enabled_for_testing, - base::Unretained(this)), - static_cast<BrowserContextImpl*>(context)->IsOffTheRecord(), - FeatureListCreator::GetInstance()->variations_service(), - // Referrer chain provider is currently not available on WebLayer. Once it - // is implemented, inject it to enable referrer chain in real time - // requests. - /*referrer_chain_provider=*/nullptr); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h b/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h deleted file mode 100644 index 55a8d54..0000000 --- a/weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_REAL_TIME_URL_LOOKUP_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_REAL_TIME_URL_LOOKUP_SERVICE_FACTORY_H_ - -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class KeyedService; - -namespace content { -class BrowserContext; -} - -namespace safe_browsing { -class RealTimeUrlLookupService; -} // namespace safe_browsing - -namespace weblayer { - -// Singleton that owns RealTimeUrlLookupService objects and associates them -// them with BrowserContextImpl instances. -class RealTimeUrlLookupServiceFactory - : public BrowserContextKeyedServiceFactory { - public: - // Creates the service if it doesn't exist already for the given - // |browser_context|. If the service already exists, return its pointer. - static safe_browsing::RealTimeUrlLookupService* GetForBrowserContext( - content::BrowserContext* browser_context); - - // Get the singleton instance. - static RealTimeUrlLookupServiceFactory* GetInstance(); - - // TODO(crbug.com/1171215): Remove this once browsertests can enable this - // functionality via the production mechanism for doing so. - void set_access_token_fetches_enabled_for_testing() { - access_token_fetches_enabled_for_testing_ = true; - } - - private: - friend struct base::DefaultSingletonTraits<RealTimeUrlLookupServiceFactory>; - - RealTimeUrlLookupServiceFactory(); - ~RealTimeUrlLookupServiceFactory() override = default; - RealTimeUrlLookupServiceFactory(const RealTimeUrlLookupServiceFactory&) = - delete; - RealTimeUrlLookupServiceFactory& operator=( - const RealTimeUrlLookupServiceFactory&) = delete; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - - // TODO(crbug.com/1171215): Remove this once browsertests can enable this - // functionality via the production mechanism for doing so. - bool access_token_fetches_enabled_for_testing( - bool user_has_enabled_enhanced_protection) const { - return access_token_fetches_enabled_for_testing_; - } - - // TODO(crbug.com/1171215): Remove this once browsertests can enable this - // functionality via the production mechanism for doing so. - bool access_token_fetches_enabled_for_testing_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_REAL_TIME_URL_LOOKUP_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc b/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc deleted file mode 100644 index 07fdf49..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc +++ /dev/null
@@ -1,495 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <map> - -#include "base/memory/raw_ptr.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/android/safe_browsing_api_handler_bridge.h" -#include "components/safe_browsing/content/browser/base_blocking_page.h" -#include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h" -#include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" -#include "components/safe_browsing/core/browser/safe_browsing_token_fetcher.h" -#include "components/security_interstitials/content/security_interstitial_page.h" -#include "components/security_interstitials/content/security_interstitial_tab_helper.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/test_utils.h" -#include "google_apis/gaia/gaia_constants.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/safe_browsing/real_time_url_lookup_service_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/google_account_access_token_fetch_delegate.h" -#include "weblayer/public/navigation.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/navigation_observer.h" -#include "weblayer/public/profile.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/load_completion_observer.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -// Implementation of GoogleAccountAccessTokenFetchDelegate used to exercise safe -// browsing access token fetches. -class TestAccessTokenFetchDelegate - : public GoogleAccountAccessTokenFetchDelegate { - public: - TestAccessTokenFetchDelegate() = default; - ~TestAccessTokenFetchDelegate() override = default; - - // GoogleAccountAccessTokenFetchDelegate: - void FetchAccessToken(const std::set<std::string>& scopes, - OnTokenFetchedCallback callback) override { - has_received_request_ = true; - scopes_from_most_recent_request_ = scopes; - - if (should_respond_to_request_) { - std::move(callback).Run("token"); - } else { - outstanding_request_ = std::move(callback); - } - } - - void OnAccessTokenIdentifiedAsInvalid(const std::set<std::string>& scopes, - const std::string& token) override { - NOTREACHED(); - } - - void set_should_respond_to_request(bool should_respond) { - should_respond_to_request_ = should_respond; - } - - bool has_received_request() { return has_received_request_; } - const std::set<std::string>& scopes_from_most_recent_request() { - return scopes_from_most_recent_request_; - } - - private: - bool should_respond_to_request_ = false; - bool has_received_request_ = false; - std::set<std::string> scopes_from_most_recent_request_; - OnTokenFetchedCallback outstanding_request_; -}; - -// Observer customized for safe browsing navigation failures. -class SafeBrowsingErrorNavigationObserver : public NavigationObserver { - public: - SafeBrowsingErrorNavigationObserver(const GURL& url, Shell* shell) - : url_(url), tab_(shell->tab()) { - tab_->GetNavigationController()->AddObserver(this); - } - - ~SafeBrowsingErrorNavigationObserver() override { - tab_->GetNavigationController()->RemoveObserver(this); - } - - void NavigationFailed(Navigation* navigation) override { - if (navigation->GetURL() != url_) - return; - - EXPECT_EQ(navigation->GetLoadError(), - Navigation::LoadError::kSafeBrowsingError); - run_loop_.Quit(); - } - - // Begins waiting for a Navigation within |shell_| and to |url_| to fail. In - // the failure callback verifies that the navigation failed with a safe - // browsing error. - void WaitForNavigationFailureWithSafeBrowsingError() { run_loop_.Run(); } - - private: - const GURL url_; - raw_ptr<Tab> tab_; - base::RunLoop run_loop_; -}; - -using SbBridge = safe_browsing::SafeBrowsingApiHandlerBridge; - -void RunCallbackOnIOThread(std::unique_ptr<SbBridge::ResponseCallback> callback, - safe_browsing::SBThreatType threat_type, - const safe_browsing::ThreatMetadata& metadata) { - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(*callback), threat_type, metadata)); -} - -} // namespace - -class TestUrlCheckInterceptor : public safe_browsing::UrlCheckInterceptor { - public: - void Add(const GURL& url, safe_browsing::SBThreatType threat_type) { - map_[url] = threat_type; - } - - void Clear() { map_.clear(); } - - // safe_browsing::UrlCheckInterceptor - void CheckBySafetyNet(std::unique_ptr<SbBridge::ResponseCallback> callback, - const GURL& url) override { - RunCallbackOnIOThread(std::move(callback), Find(url), - safe_browsing::ThreatMetadata()); - } - void CheckBySafeBrowsing(std::unique_ptr<SbBridge::ResponseCallback> callback, - const GURL& url) override { - NOTREACHED(); - } - ~TestUrlCheckInterceptor() override = default; - - private: - safe_browsing::SBThreatType Find(const GURL& url) const { - auto it = map_.find(url); - if (it != map_.end()) - return it->second; - - // If the url is not in the map assume it is safe. - return safe_browsing::SB_THREAT_TYPE_SAFE; - } - - std::map<GURL, safe_browsing::SBThreatType> map_; -}; - -class SafeBrowsingBrowserTest : public WebLayerBrowserTest { - public: - SafeBrowsingBrowserTest() - : url_check_interceptor_(std::make_unique<TestUrlCheckInterceptor>()) {} - - SafeBrowsingBrowserTest(const SafeBrowsingBrowserTest&) = delete; - SafeBrowsingBrowserTest& operator=(const SafeBrowsingBrowserTest&) = delete; - - ~SafeBrowsingBrowserTest() override = default; - - void SetUpOnMainThread() override { - InitializeOnMainThread(); - // Safe Browsing is enabled by default - ASSERT_TRUE(GetSafeBrowsingEnabled()); - - profile()->SetGoogleAccountAccessTokenFetchDelegate( - &access_token_fetch_delegate_); - } - - void TearDown() override { - profile()->SetGoogleAccountAccessTokenFetchDelegate(nullptr); - SbBridge::GetInstance().SetInterceptorForTesting(nullptr); - } - - void InitializeOnMainThread() { - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - SbBridge::GetInstance().SetInterceptorForTesting( - url_check_interceptor_.get()); - - // Some tests need to be able to navigate to URLs on domains that are not - // explicitly localhost (e.g., so that realtime URL lookups occur on these - // navigations). - host_resolver()->AddRule("*", "127.0.0.1"); - - ASSERT_TRUE(embedded_test_server()->Start()); - url_ = embedded_test_server()->GetURL("/simple_page.html"); - } - - void SetSafeBrowsingEnabled(bool value) { - GetProfile()->SetBooleanSetting(SettingType::BASIC_SAFE_BROWSING_ENABLED, - value); - } - - void SetRealTimeURLLookupsEnabled(bool value) { - GetProfile()->SetBooleanSetting( - SettingType::REAL_TIME_SAFE_BROWSING_ENABLED, value); - } - - void EnableSafeBrowsingAccessTokenFetches() { - RealTimeUrlLookupServiceFactory::GetInstance() - ->set_access_token_fetches_enabled_for_testing(); - } - - bool GetSafeBrowsingEnabled() { - return GetProfile()->GetBooleanSetting( - SettingType::BASIC_SAFE_BROWSING_ENABLED); - } - - void NavigateWithThreatType(const safe_browsing::SBThreatType& threatType, - bool expect_interstitial) { - url_check_interceptor_->Add(url_, threatType); - Navigate(url_, expect_interstitial); - } - - void Navigate(const GURL& url, bool expect_interstitial) { - LoadCompletionObserver load_observer(shell()); - shell()->tab()->GetNavigationController()->Navigate(url); - load_observer.Wait(); - EXPECT_EQ(expect_interstitial, HasInterstitial()); - if (expect_interstitial) { - ASSERT_EQ(safe_browsing::SafeBrowsingBlockingPage::kTypeForTesting, - GetSecurityInterstitialPage()->GetTypeForTesting()); - EXPECT_TRUE(GetSecurityInterstitialPage()->GetHTMLContents().length() > - 0); - } - } - - void NavigateWithSubResourceAndThreatType( - const safe_browsing::SBThreatType& threat_type, - bool expect_interstitial) { - GURL page_with_script_url = - embedded_test_server()->GetURL("/simple_page_with_script.html"); - GURL script_url = embedded_test_server()->GetURL("/script.js"); - url_check_interceptor_->Add(script_url, threat_type); - Navigate(page_with_script_url, expect_interstitial); - } - - protected: - content::WebContents* GetWebContents() { - Tab* tab = shell()->tab(); - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - return tab_impl->web_contents(); - } - - security_interstitials::SecurityInterstitialPage* - GetSecurityInterstitialPage() { - security_interstitials::SecurityInterstitialTabHelper* helper = - security_interstitials::SecurityInterstitialTabHelper::FromWebContents( - GetWebContents()); - return helper - ? helper - ->GetBlockingPageForCurrentlyCommittedNavigationForTesting() - : nullptr; - } - - bool HasInterstitial() { return GetSecurityInterstitialPage() != nullptr; } - - void KillRenderer() { - content::RenderProcessHost* child_process = - static_cast<TabImpl*>(shell()->tab()) - ->web_contents() - ->GetPrimaryMainFrame() - ->GetProcess(); - content::RenderProcessHostWatcher crash_observer( - child_process, - content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); - child_process->Shutdown(0); - crash_observer.Wait(); - } - - std::unique_ptr<TestUrlCheckInterceptor> url_check_interceptor_; - GURL url_; - - ProfileImpl* profile() { - auto* tab_impl = static_cast<TabImpl*>(shell()->tab()); - return tab_impl->profile(); - } - - TestAccessTokenFetchDelegate* access_token_fetch_delegate() { - return &access_token_fetch_delegate_; - } - - private: - TestAccessTokenFetchDelegate access_token_fetch_delegate_; -}; - -class SafeBrowsingDisabledBrowserTest : public SafeBrowsingBrowserTest { - public: - SafeBrowsingDisabledBrowserTest() {} - - SafeBrowsingDisabledBrowserTest(const SafeBrowsingDisabledBrowserTest&) = - delete; - SafeBrowsingDisabledBrowserTest& operator=( - const SafeBrowsingDisabledBrowserTest&) = delete; - - ~SafeBrowsingDisabledBrowserTest() override = default; - - void SetUpOnMainThread() override { - SetSafeBrowsingEnabled(false); - SafeBrowsingBrowserTest::InitializeOnMainThread(); - ASSERT_FALSE(GetSafeBrowsingEnabled()); - } -}; - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, - DoesNotShowInterstitial_NoRestriction) { - Navigate(url_, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, DoesNotShowInterstitial_Safe) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_SAFE, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Malware) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_MALWARE, true); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Phishing) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, true); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, CheckNavigationErrorType) { - auto threat_types = { - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, - safe_browsing::SB_THREAT_TYPE_URL_MALWARE, - safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, - safe_browsing::SB_THREAT_TYPE_BILLING, - }; - - for (auto threat_type : threat_types) { - SafeBrowsingErrorNavigationObserver observer(url_, shell()); - - url_check_interceptor_->Clear(); - url_check_interceptor_->Add(url_, threat_type); - shell()->tab()->GetNavigationController()->Navigate(url_); - - observer.WaitForNavigationFailureWithSafeBrowsingError(); - } -} - -// Tests below are disabled due to failures on Android. -// See crbug.com/1340200. -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Unwanted) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, true); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Billing) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_BILLING, true); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, - ShowsInterstitial_Malware_Subresource) { - NavigateWithSubResourceAndThreatType( - safe_browsing::SB_THREAT_TYPE_URL_MALWARE, true); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, - DoesNotShowInterstitial_Phishing_disableSB) { - // Test that the browser checks the safe browsing setting for new navigations. - SetSafeBrowsingEnabled(false); - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, - DoesNotShowInterstitial_Malware_Subresource_disableSB) { - // Test that new renderer checks the safe browsing setting. - SetSafeBrowsingEnabled(false); - KillRenderer(); - NavigateWithSubResourceAndThreatType( - safe_browsing::SB_THREAT_TYPE_URL_MALWARE, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, CheckSetsPrefs) { - // Check that changing safe browsing setting sets corresponding pref, - // which is persistent. - PrefService* prefs = GetProfile()->GetBrowserContext()->pref_service(); - SetSafeBrowsingEnabled(true); - EXPECT_TRUE(prefs->GetBoolean(::prefs::kSafeBrowsingEnabled)); - SetSafeBrowsingEnabled(false); - EXPECT_FALSE(prefs->GetBoolean(::prefs::kSafeBrowsingEnabled)); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest, - DoesNotShowInterstitial_NoRestriction) { - Navigate(url_, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest, - DoesNotShowInterstitial_Safe) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_SAFE, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest, - DoesNotShowInterstitial_Malware) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_MALWARE, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest, - DoesNotShowInterstitial_Phishing) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest, - DoesNotShowInterstitial_Unwanted) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest, - DoesNotShowInterstitial_Billing) { - NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_BILLING, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingDisabledBrowserTest, - DoesNotShowInterstitial_Malware_Subresource) { - NavigateWithSubResourceAndThreatType( - safe_browsing::SB_THREAT_TYPE_URL_MALWARE, false); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, - NoAccessTokenFetchWhenSafeBrowsingNotEnabled) { - GURL a_url(embedded_test_server()->GetURL("a.com", "/simple_page.html")); - NavigateAndWaitForCompletion(a_url, shell()->tab()); - - EXPECT_FALSE(access_token_fetch_delegate()->has_received_request()); -} - -IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, - NoAccessTokenFetchInBasicSafeBrowsing) { - SetSafeBrowsingEnabled(true); - - GURL a_url(embedded_test_server()->GetURL("a.com", "/simple_page.html")); - NavigateAndWaitForCompletion(a_url, shell()->tab()); - - EXPECT_FALSE(access_token_fetch_delegate()->has_received_request()); -} - -// Disabled due to https://crbug.com/1448377. -IN_PROC_BROWSER_TEST_F( - SafeBrowsingBrowserTest, - DISABLED_NoAccessTokenFetchInRealTimeUrlLookupsUnlessEnabled) { - SetRealTimeURLLookupsEnabled(true); - - GURL a_url(embedded_test_server()->GetURL("a.com", "/simple_page.html")); - NavigateAndWaitForCompletion(a_url, shell()->tab()); - - EXPECT_FALSE(access_token_fetch_delegate()->has_received_request()); - - EnableSafeBrowsingAccessTokenFetches(); - access_token_fetch_delegate()->set_should_respond_to_request(true); - - GURL b_url(embedded_test_server()->GetURL("a.com", "/simple_page.html")); - NavigateAndWaitForCompletion(a_url, shell()->tab()); - - std::set<std::string> safe_browsing_scopes = { - GaiaConstants::kChromeSafeBrowsingOAuth2Scope}; - EXPECT_TRUE(access_token_fetch_delegate()->has_received_request()); - EXPECT_EQ(safe_browsing_scopes, - access_token_fetch_delegate()->scopes_from_most_recent_request()); -} - -// Tests that even if the embedder does not respond to an access token fetch -// that is made by safe browsing as part of a navigation, the navigation -// completes due to Safe Browsing's timing out the access token fetch. -// Disabled due to https://crbug.com/1448377. -IN_PROC_BROWSER_TEST_F( - SafeBrowsingBrowserTest, - DISABLED_UnfulfilledAccessTokenFetchTimesOutAndNavigationCompletes) { - SetRealTimeURLLookupsEnabled(true); - EnableSafeBrowsingAccessTokenFetches(); - access_token_fetch_delegate()->set_should_respond_to_request(false); - - GURL a_url(embedded_test_server()->GetURL("a.com", "/simple_page.html")); - NavigateAndWaitForCompletion(a_url, shell()->tab()); - - std::set<std::string> safe_browsing_scopes = { - GaiaConstants::kChromeSafeBrowsingOAuth2Scope}; - EXPECT_TRUE(access_token_fetch_delegate()->has_received_request()); - EXPECT_EQ(safe_browsing_scopes, - access_token_fetch_delegate()->scopes_from_most_recent_request()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.cc b/weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.cc deleted file mode 100644 index 7d12c9b..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/safe_browsing/core/browser/safe_browsing_metrics_collector.h" -#include "weblayer/browser/browser_context_impl.h" - -namespace weblayer { - -// static -safe_browsing::SafeBrowsingMetricsCollector* -SafeBrowsingMetricsCollectorFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<safe_browsing::SafeBrowsingMetricsCollector*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - /* create= */ true)); -} - -// static -SafeBrowsingMetricsCollectorFactory* -SafeBrowsingMetricsCollectorFactory::GetInstance() { - static base::NoDestructor<SafeBrowsingMetricsCollectorFactory> factory; - return factory.get(); -} - -// static -SafeBrowsingMetricsCollectorFactory::SafeBrowsingMetricsCollectorFactory() - : BrowserContextKeyedServiceFactory( - "SafeBrowsingMetricsCollector", - BrowserContextDependencyManager::GetInstance()) {} - -std::unique_ptr<KeyedService> -SafeBrowsingMetricsCollectorFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - BrowserContextImpl* context_impl = static_cast<BrowserContextImpl*>(context); - return std::make_unique<safe_browsing::SafeBrowsingMetricsCollector>( - context_impl->pref_service()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h b/weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h deleted file mode 100644 index 4bbb3a58..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_METRICS_COLLECTOR_FACTORY_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_METRICS_COLLECTOR_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class KeyedService; - -namespace content { -class BrowserContext; -} - -namespace safe_browsing { -class SafeBrowsingMetricsCollector; -} - -namespace weblayer { - -// Singleton that owns SafeBrowsingMetricsCollector objects, one for each active -// BrowserContext. It returns nullptr in incognito mode. -class SafeBrowsingMetricsCollectorFactory - : public BrowserContextKeyedServiceFactory { - public: - SafeBrowsingMetricsCollectorFactory( - const SafeBrowsingMetricsCollectorFactory&) = delete; - SafeBrowsingMetricsCollectorFactory& operator=( - const SafeBrowsingMetricsCollectorFactory&) = delete; - - // Creates the object if it doesn't exist already for the given - // |browser_context|. If the object already exists, returns its pointer. - static safe_browsing::SafeBrowsingMetricsCollector* GetForBrowserContext( - content::BrowserContext* browser_context); - - // Get the singleton instance. - static SafeBrowsingMetricsCollectorFactory* GetInstance(); - - private: - friend class base::NoDestructor<SafeBrowsingMetricsCollectorFactory>; - - SafeBrowsingMetricsCollectorFactory(); - ~SafeBrowsingMetricsCollectorFactory() override = default; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_METRICS_COLLECTOR_FACTORY_H_
diff --git a/weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc b/weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc deleted file mode 100644 index 229bc637..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" -#include "weblayer/browser/browser_context_impl.h" - -namespace weblayer { - -// static -safe_browsing::SafeBrowsingNavigationObserverManager* -SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<safe_browsing::SafeBrowsingNavigationObserverManager*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - /*create=*/true)); -} - -// static -SafeBrowsingNavigationObserverManagerFactory* -SafeBrowsingNavigationObserverManagerFactory::GetInstance() { - static base::NoDestructor<SafeBrowsingNavigationObserverManagerFactory> - factory; - return factory.get(); -} - -SafeBrowsingNavigationObserverManagerFactory:: - SafeBrowsingNavigationObserverManagerFactory() - : BrowserContextKeyedServiceFactory( - "SafeBrowsingNavigationObserverManager", - BrowserContextDependencyManager::GetInstance()) {} - -std::unique_ptr<KeyedService> SafeBrowsingNavigationObserverManagerFactory:: - BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - BrowserContextImpl* context_impl = static_cast<BrowserContextImpl*>(context); - return std::make_unique<safe_browsing::SafeBrowsingNavigationObserverManager>( - context_impl->pref_service()); -} - -content::BrowserContext* -SafeBrowsingNavigationObserverManagerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h b/weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h deleted file mode 100644 index f285132..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_FACTORY_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class KeyedService; - -namespace content { -class BrowserContext; -} - -namespace safe_browsing { -class SafeBrowsingNavigationObserverManager; -} - -namespace weblayer { - -// Singleton that owns SafeBrowsingNavigationObserverManager objects, one for -// each active BrowserContext. It returns a separate instance if the -// BrowserContext is in incognito mode. -class SafeBrowsingNavigationObserverManagerFactory - : public BrowserContextKeyedServiceFactory { - public: - SafeBrowsingNavigationObserverManagerFactory( - const SafeBrowsingNavigationObserverManagerFactory&) = delete; - SafeBrowsingNavigationObserverManagerFactory& operator=( - const SafeBrowsingNavigationObserverManagerFactory&) = delete; - - // Creates the service if it doesn't exist already for the given - // |browser_context|. If the service already exists, returns its pointer. - static safe_browsing::SafeBrowsingNavigationObserverManager* - GetForBrowserContext(content::BrowserContext* browser_context); - - // Get the singleton instance. - static SafeBrowsingNavigationObserverManagerFactory* GetInstance(); - - private: - friend class base::NoDestructor<SafeBrowsingNavigationObserverManagerFactory>; - - SafeBrowsingNavigationObserverManagerFactory(); - ~SafeBrowsingNavigationObserverManagerFactory() override = default; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_FACTORY_H_
diff --git a/weblayer/browser/safe_browsing/safe_browsing_service.cc b/weblayer/browser/safe_browsing/safe_browsing_service.cc deleted file mode 100644 index d7605ed..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_service.cc +++ /dev/null
@@ -1,333 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" - -#include <memory> - -#include "base/functional/bind.h" -#include "base/path_service.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/android/remote_database_manager.h" -#include "components/safe_browsing/android/safe_browsing_api_handler_bridge.h" -#include "components/safe_browsing/content/browser/browser_url_loader_throttle.h" -#include "components/safe_browsing/content/browser/mojo_safe_browsing_impl.h" -#include "components/safe_browsing/content/browser/safe_browsing_navigation_throttle.h" -#include "components/safe_browsing/content/browser/safe_browsing_network_context.h" -#include "components/safe_browsing/content/browser/triggers/trigger_manager.h" -#include "components/safe_browsing/core/browser/realtime/url_lookup_service.h" -#include "components/safe_browsing/core/common/features.h" -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/network_service_instance.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/resource_context.h" -#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" -#include "services/network/public/mojom/network_context.mojom.h" -#include "services/network/public/mojom/network_service.mojom.h" -#include "third_party/blink/public/common/loader/url_loader_throttle.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/safe_browsing/url_checker_delegate_impl.h" -#include "weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.h" -#include "weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.h" -#include "weblayer/browser/system_network_context_manager.h" -#include "weblayer/common/features.h" - -namespace weblayer { - -namespace { - -network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams( - const std::string& user_agent) { - network::mojom::NetworkContextParamsPtr network_context_params = - network::mojom::NetworkContextParams::New(); - network_context_params->cert_verifier_params = content::GetCertVerifierParams( - cert_verifier::mojom::CertVerifierCreationParams::New()); - network_context_params->user_agent = user_agent; - return network_context_params; -} - -// Helper method that checks the RenderProcessHost is still alive and checks the -// latest Safe Browsing pref value on the UI thread before hopping over to the -// IO thread. -void MaybeCreateSafeBrowsing( - int rph_id, - base::WeakPtr<content::ResourceContext> resource_context, - base::RepeatingCallback<scoped_refptr<safe_browsing::UrlCheckerDelegate>()> - get_checker_delegate, - mojo::PendingReceiver<safe_browsing::mojom::SafeBrowsing> receiver) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - content::RenderProcessHost* render_process_host = - content::RenderProcessHost::FromID(rph_id); - if (!render_process_host) { - return; - } - - bool is_safe_browsing_enabled = safe_browsing::IsSafeBrowsingEnabled( - *static_cast<BrowserContextImpl*>( - render_process_host->GetBrowserContext()) - ->pref_service()); - - if (!is_safe_browsing_enabled) { - return; - } - - if (base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread)) { - safe_browsing::MojoSafeBrowsingImpl::MaybeCreate( - rph_id, std::move(resource_context), std::move(get_checker_delegate), - std::move(receiver)); - } else { - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&safe_browsing::MojoSafeBrowsingImpl::MaybeCreate, - rph_id, std::move(resource_context), - std::move(get_checker_delegate), std::move(receiver))); - } -} - -} // namespace - -SafeBrowsingService::SafeBrowsingService(const std::string& user_agent) - : user_agent_(user_agent) {} - -SafeBrowsingService::~SafeBrowsingService() = default; - -void SafeBrowsingService::Initialize() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - if (network_context_) { - // already initialized - return; - } - - base::FilePath user_data_dir; - bool result = - base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir); - DCHECK(result); - - // safebrowsing network context needs to be created on the UI thread. - network_context_ = - std::make_unique<safe_browsing::SafeBrowsingNetworkContext>( - user_data_dir, /*trigger_migration=*/false, - base::BindRepeating(CreateDefaultNetworkContextParams, user_agent_)); - - CreateSafeBrowsingUIManager(); - - // Needs to happen after |ui_manager_| is created. - CreateTriggerManager(); -} - -std::unique_ptr<blink::URLLoaderThrottle> -SafeBrowsingService::CreateURLLoaderThrottle( - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - int frame_tree_node_id, - safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - return safe_browsing::BrowserURLLoaderThrottle::Create( - base::BindOnce( - [](SafeBrowsingService* sb_service) { - return sb_service->GetSafeBrowsingUrlCheckerDelegate(); - }, - base::Unretained(this)), - wc_getter, frame_tree_node_id, - url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr, - /*hash_realtime_service=*/nullptr, - /*ping_manager=*/nullptr, - /*hash_realtime_selection=*/ - safe_browsing::hash_realtime_utils::HashRealTimeSelection::kNone); -} - -std::unique_ptr<content::NavigationThrottle> -SafeBrowsingService::MaybeCreateSafeBrowsingNavigationThrottleFor( - content::NavigationHandle* handle) { - if (!base::FeatureList::IsEnabled(features::kWebLayerSafeBrowsing)) { - return nullptr; - } - - return safe_browsing::SafeBrowsingNavigationThrottle::MaybeCreateThrottleFor( - handle, GetSafeBrowsingUIManager().get()); -} - -scoped_refptr<safe_browsing::UrlCheckerDelegate> -SafeBrowsingService::GetSafeBrowsingUrlCheckerDelegate() { - DCHECK_CURRENTLY_ON( - base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread) - ? content::BrowserThread::UI - : content::BrowserThread::IO); - - if (!safe_browsing_url_checker_delegate_) { - safe_browsing_url_checker_delegate_ = new UrlCheckerDelegateImpl( - GetSafeBrowsingDBManager(), GetSafeBrowsingUIManager()); - } - - return safe_browsing_url_checker_delegate_; -} - -scoped_refptr<safe_browsing::RemoteSafeBrowsingDatabaseManager> -SafeBrowsingService::GetSafeBrowsingDBManager() { - if (!safe_browsing_db_manager_) { - CreateAndStartSafeBrowsingDBManager(); - } - return safe_browsing_db_manager_; -} - -scoped_refptr<safe_browsing::SafeBrowsingUIManager> -SafeBrowsingService::GetSafeBrowsingUIManager() { - return ui_manager_; -} - -safe_browsing::TriggerManager* SafeBrowsingService::GetTriggerManager() { - return trigger_manager_.get(); -} - -void SafeBrowsingService::CreateSafeBrowsingUIManager() { - DCHECK(!ui_manager_); - ui_manager_ = new safe_browsing::SafeBrowsingUIManager( - std::make_unique<WebLayerSafeBrowsingUIManagerDelegate>(), - std::make_unique<WebLayerSafeBrowsingBlockingPageFactory>(), - GURL(url::kAboutBlankURL)); -} - -void SafeBrowsingService::CreateTriggerManager() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - trigger_manager_ = std::make_unique<safe_browsing::TriggerManager>( - ui_manager_.get(), BrowserProcess::GetInstance()->GetLocalState()); -} - -void SafeBrowsingService::CreateAndStartSafeBrowsingDBManager() { - DCHECK(!safe_browsing_db_manager_); - - safe_browsing_db_manager_ = - new safe_browsing::RemoteSafeBrowsingDatabaseManager(); - - auto task_runner = - base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread) - ? content::GetUIThreadTaskRunner({}) - : content::GetIOThreadTaskRunner({}); - if (!task_runner->BelongsToCurrentThread()) { - // Posting a task to start the DB here ensures that it will be started by - // the time that a consumer uses it on the IO thread, as such a consumer - // would need to make it available for usage on the IO thread via a - // PostTask() that will be ordered after this one. - task_runner->PostTask( - FROM_HERE, - base::BindOnce( - &SafeBrowsingService::StartSafeBrowsingDBManagerOnSBThread, - base::Unretained(this))); - } else { - StartSafeBrowsingDBManagerOnSBThread(); - } -} - -void SafeBrowsingService::StartSafeBrowsingDBManagerOnSBThread() { - DCHECK_CURRENTLY_ON( - base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread) - ? content::BrowserThread::UI - : content::BrowserThread::IO); - DCHECK(safe_browsing_db_manager_); - - if (started_db_manager_) { - return; - } - - started_db_manager_ = true; - - // V4ProtocolConfig is not used. Just create one with empty values. - safe_browsing::V4ProtocolConfig config("", false, "", ""); - - scoped_refptr<network::SharedURLLoaderFactory> factory; - if (base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread)) { - factory = - SystemNetworkContextManager::GetInstance()->GetSharedURLLoaderFactory(); - } else { - factory = GetURLLoaderFactoryOnIOThread(); - } - safe_browsing_db_manager_->StartOnSBThread(factory, config); -} - -scoped_refptr<network::SharedURLLoaderFactory> -SafeBrowsingService::GetURLLoaderFactoryOnIOThread() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!shared_url_loader_factory_on_io_) { - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&SafeBrowsingService::CreateURLLoaderFactoryForIO, - base::Unretained(this), - url_loader_factory_on_io_.BindNewPipeAndPassReceiver())); - shared_url_loader_factory_on_io_ = - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - url_loader_factory_on_io_.get()); - } - return shared_url_loader_factory_on_io_; -} - -void SafeBrowsingService::CreateURLLoaderFactoryForIO( - mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - auto url_loader_factory_params = - network::mojom::URLLoaderFactoryParams::New(); - url_loader_factory_params->process_id = network::mojom::kBrowserProcessId; - url_loader_factory_params->is_corb_enabled = false; - network_context_->GetNetworkContext()->CreateURLLoaderFactory( - std::move(receiver), std::move(url_loader_factory_params)); -} - -void SafeBrowsingService::AddInterface( - service_manager::BinderRegistry* registry, - content::RenderProcessHost* render_process_host) { - content::ResourceContext* resource_context = - render_process_host->GetBrowserContext()->GetResourceContext(); - registry->AddInterface( - base::BindRepeating( - &MaybeCreateSafeBrowsing, render_process_host->GetID(), - resource_context->GetWeakPtr(), - base::BindRepeating( - &SafeBrowsingService::GetSafeBrowsingUrlCheckerDelegate, - base::Unretained(this))), - content::GetUIThreadTaskRunner({})); -} - -void SafeBrowsingService::StopDBManager() { - if (base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread)) { - StopDBManagerOnSBThread(); - } else { - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&SafeBrowsingService::StopDBManagerOnSBThread, - base::Unretained(this))); - } -} - -void SafeBrowsingService::StopDBManagerOnSBThread() { - DCHECK_CURRENTLY_ON( - base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread) - ? content::BrowserThread::UI - : content::BrowserThread::IO); - if (safe_browsing_db_manager_) { - safe_browsing_db_manager_->StopOnSBThread(true /*shutdown*/); - safe_browsing_db_manager_.reset(); - started_db_manager_ = false; - } -} - -network::mojom::NetworkContext* SafeBrowsingService::GetNetworkContext() { - if (!network_context_) { - return nullptr; - } - return network_context_->GetNetworkContext(); -} - -scoped_refptr<network::SharedURLLoaderFactory> -SafeBrowsingService::GetURLLoaderFactory() { - if (!network_context_) { - return nullptr; - } - return network_context_->GetURLLoaderFactory(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/safe_browsing_service.h b/weblayer/browser/safe_browsing/safe_browsing_service.h deleted file mode 100644 index 54a1283..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_service.h +++ /dev/null
@@ -1,136 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_ - -#include "components/safe_browsing/content/browser/base_ui_manager.h" - -#include "components/safe_browsing/content/browser/ui_manager.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/service_manager/public/cpp/binder_registry.h" - -namespace content { -class NavigationHandle; -class NavigationThrottle; -class RenderProcessHost; -} // namespace content - -namespace blink { -class URLLoaderThrottle; -} - -namespace network { -namespace mojom { -class NetworkContext; -} -class SharedURLLoaderFactory; -} // namespace network - -namespace safe_browsing { -class UrlCheckerDelegate; -class RealTimeUrlLookupServiceBase; -class RemoteSafeBrowsingDatabaseManager; -class SafeBrowsingApiHandlerBridge; -class SafeBrowsingNetworkContext; -class TriggerManager; -} // namespace safe_browsing - -namespace weblayer { -class UrlCheckerDelegateImpl; - -// Class for managing safebrowsing related functionality. In particular this -// class owns both the safebrowsing database and UI managers and provides -// support for initialization and construction of these objects. -class SafeBrowsingService { - public: - explicit SafeBrowsingService(const std::string& user_agent); - - SafeBrowsingService(const SafeBrowsingService&) = delete; - SafeBrowsingService& operator=(const SafeBrowsingService&) = delete; - - ~SafeBrowsingService(); - - // Executed on UI thread - void Initialize(); - std::unique_ptr<blink::URLLoaderThrottle> CreateURLLoaderThrottle( - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - int frame_tree_node_id, - safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service); - std::unique_ptr<content::NavigationThrottle> - MaybeCreateSafeBrowsingNavigationThrottleFor( - content::NavigationHandle* handle); - void AddInterface(service_manager::BinderRegistry* registry, - content::RenderProcessHost* render_process_host); - void StopDBManager(); - - network::mojom::NetworkContext* GetNetworkContext(); - - scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory(); - - // May be called on the UI or IO thread. The instance returned should be - // *accessed* only on the IO thread. - scoped_refptr<safe_browsing::RemoteSafeBrowsingDatabaseManager> - GetSafeBrowsingDBManager(); - - scoped_refptr<safe_browsing::SafeBrowsingUIManager> - GetSafeBrowsingUIManager(); - - safe_browsing::TriggerManager* GetTriggerManager(); - - private: - // Executed on IO thread - scoped_refptr<safe_browsing::UrlCheckerDelegate> - GetSafeBrowsingUrlCheckerDelegate(); - - // Safe to call multiple times; invocations after the first will be no-ops. - void StartSafeBrowsingDBManagerOnSBThread(); - void CreateSafeBrowsingUIManager(); - void CreateTriggerManager(); - void CreateAndStartSafeBrowsingDBManager(); - scoped_refptr<network::SharedURLLoaderFactory> - GetURLLoaderFactoryOnIOThread(); - void CreateURLLoaderFactoryForIO( - mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver); - void StopDBManagerOnSBThread(); - - // The UI manager handles showing interstitials. Accessed on both UI and IO - // thread. - scoped_refptr<safe_browsing::SafeBrowsingUIManager> ui_manager_; - - // This is what owns the URLRequestContext inside the network service. This - // is used by SimpleURLLoader for Safe Browsing requests. - std::unique_ptr<safe_browsing::SafeBrowsingNetworkContext> network_context_; - - // May be created on UI thread and have references obtained to it on that - // thread for later passing to the IO thread, but should be *accessed* only - // on the IO thread. - scoped_refptr<safe_browsing::RemoteSafeBrowsingDatabaseManager> - safe_browsing_db_manager_; - - // A SharedURLLoaderFactory and its remote used on the IO thread. - mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_on_io_; - scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> - shared_url_loader_factory_on_io_; - - scoped_refptr<UrlCheckerDelegateImpl> safe_browsing_url_checker_delegate_; - - std::unique_ptr<safe_browsing::SafeBrowsingApiHandlerBridge> - safe_browsing_api_handler_; - - std::string user_agent_; - - // Whether |safe_browsing_db_manager_| has been started. Accessed only on the - // IO thread. - bool started_db_manager_ = false; - - // Collects data and sends reports to Safe Browsing. Accessed on UI thread. - std::unique_ptr<safe_browsing::TriggerManager> trigger_manager_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_
diff --git a/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.cc b/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.cc deleted file mode 100644 index 7266953..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.cc +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h" - -#include "base/functional/bind.h" -#include "base/memory/weak_ptr.h" -#include "google_apis/gaia/gaia_constants.h" -#include "weblayer/public/google_account_access_token_fetch_delegate.h" - -namespace weblayer { - -SafeBrowsingTokenFetcherImpl::SafeBrowsingTokenFetcherImpl( - const AccessTokenFetchDelegateGetter& delegate_getter) - : delegate_getter_(delegate_getter) {} - -SafeBrowsingTokenFetcherImpl::~SafeBrowsingTokenFetcherImpl() = default; - -void SafeBrowsingTokenFetcherImpl::Start(Callback callback) { - auto* delegate = delegate_getter_.Run(); - - if (!delegate) { - std::move(callback).Run(""); - return; - } - - // NOTE: When a token fetch timeout occurs |token_fetch_tracker_| will invoke - // the client callback, which may end up synchronously destroying this object - // before this object's own callback is invoked. Hence we bind our own - // callback via a WeakPtr. - const int request_id = token_fetch_tracker_.StartTrackingTokenFetch( - std::move(callback), - base::BindOnce(&SafeBrowsingTokenFetcherImpl::OnTokenTimeout, - weak_ptr_factory_.GetWeakPtr())); - request_ids_.insert(request_id); - - // In contrast, this object does *not* have a determined lifetime relationship - // with |delegate|. - delegate->FetchAccessToken( - {GaiaConstants::kChromeSafeBrowsingOAuth2Scope}, - base::BindOnce(&SafeBrowsingTokenFetcherImpl::OnTokenFetched, - weak_ptr_factory_.GetWeakPtr(), request_id)); -} - -void SafeBrowsingTokenFetcherImpl::OnInvalidAccessToken( - const std::string& invalid_access_token) { - auto* delegate = delegate_getter_.Run(); - - if (!delegate) - return; - - delegate->OnAccessTokenIdentifiedAsInvalid( - {GaiaConstants::kChromeSafeBrowsingOAuth2Scope}, invalid_access_token); -} - -void SafeBrowsingTokenFetcherImpl::OnTokenFetched( - int request_id, - const std::string& access_token) { - if (!request_ids_.count(request_id)) { - // The request timed out before the delegate responded; nothing to do. - return; - } - - request_ids_.erase(request_id); - - token_fetch_tracker_.OnTokenFetchComplete(request_id, access_token); - - // NOTE: Calling SafeBrowsingTokenFetchTracker::OnTokenFetchComplete might - // have resulted in the synchronous destruction of this object, so there is - // nothing safe to do here but return. -} - -void SafeBrowsingTokenFetcherImpl::OnTokenTimeout(int request_id) { - DCHECK(request_ids_.count(request_id)); - request_ids_.erase(request_id); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h b/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h deleted file mode 100644 index 18ef05e..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TOKEN_FETCHER_IMPL_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TOKEN_FETCHER_IMPL_H_ - -#include <memory> -#include <set> - -#include "base/memory/weak_ptr.h" -#include "components/safe_browsing/core/browser/safe_browsing_token_fetch_tracker.h" -#include "components/safe_browsing/core/browser/safe_browsing_token_fetcher.h" - -namespace weblayer { - -class GoogleAccountAccessTokenFetchDelegate; - -// This class fetches access tokens for Safe Browsing via a -// GoogleAccountAccessTokenFetcherDelegate. -class SafeBrowsingTokenFetcherImpl - : public safe_browsing::SafeBrowsingTokenFetcher { - public: - using AccessTokenFetchDelegateGetter = - base::RepeatingCallback<GoogleAccountAccessTokenFetchDelegate*()>; - - // Create a SafeBrowsingTokenFetcherImpl that makes access token requests via - // the object returned by |delegate_getter|. |delegate_getter| may return - // null, in which case this object will return the empty string for access - // token requests. This object will not cache the pointer returned by - // |delegate_getter| but will instead invoke it on every access token request, - // as that object might change over time. - // NOTE: In production the getter is - // ProfileImpl::access_token_fetcher_delegate(); this level of indirection is - // present to support unittests. - explicit SafeBrowsingTokenFetcherImpl( - const AccessTokenFetchDelegateGetter& delegate_getter); - ~SafeBrowsingTokenFetcherImpl() override; - - // SafeBrowsingTokenFetcher: - void Start(Callback callback) override; - void OnInvalidAccessToken(const std::string& invalid_access_token) override; - - private: - void OnTokenFetched(int request_id, const std::string& access_token); - void OnTokenTimeout(int request_id); - - AccessTokenFetchDelegateGetter delegate_getter_; - - safe_browsing::SafeBrowsingTokenFetchTracker token_fetch_tracker_; - - // IDs of outstanding client access token requests being tracked by - // |token_fetch_tracker_|. - std::set<int> request_ids_; - - base::WeakPtrFactory<SafeBrowsingTokenFetcherImpl> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_SAFE_BROWSING_TOKEN_FETCHER_IMPL_H_
diff --git a/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl_unittest.cc b/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl_unittest.cc deleted file mode 100644 index f3e901b..0000000 --- a/weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl_unittest.cc +++ /dev/null
@@ -1,401 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h" - -#include "content/public/test/browser_task_environment.h" -#include "google_apis/gaia/gaia_constants.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "weblayer/public/google_account_access_token_fetch_delegate.h" - -namespace weblayer { -namespace { - -// Callback passed to SafeBrowsingTokenFetcherImpl to be invoked on -// access token fetch completion. -void OnAccessTokenFetched(base::OnceClosure quit_closure, - std::string* target_token, - const std::string& received_token) { - *target_token = received_token; - std::move(quit_closure).Run(); -} - -// Test implementation of GoogleAccountAccessTokenFetchDelegate. -class TestAccessTokenFetchDelegate - : public GoogleAccountAccessTokenFetchDelegate { - public: - TestAccessTokenFetchDelegate() {} - ~TestAccessTokenFetchDelegate() override {} - - TestAccessTokenFetchDelegate(const TestAccessTokenFetchDelegate&) = delete; - TestAccessTokenFetchDelegate& operator=(const TestAccessTokenFetchDelegate&) = - delete; - - // GoogleAccountAccessTokenFetchDelegate: - void FetchAccessToken(const std::set<std::string>& scopes, - OnTokenFetchedCallback callback) override { - most_recent_request_id_++; - - // All access token requests made by SafeBrowsingTokenFetcherImpl should be - // for the safe browsing scope. - std::set<std::string> expected_scopes = { - GaiaConstants::kChromeSafeBrowsingOAuth2Scope}; - EXPECT_EQ(expected_scopes, scopes); - - outstanding_callbacks_[most_recent_request_id_] = std::move(callback); - } - - void OnAccessTokenIdentifiedAsInvalid(const std::set<std::string>& scopes, - const std::string& token) override { - // All invalid token notifications originating from - // SafeBrowsingTokenFetcherImpl should be for the safe browsing scope. - std::set<std::string> expected_scopes = { - GaiaConstants::kChromeSafeBrowsingOAuth2Scope}; - EXPECT_EQ(expected_scopes, scopes); - - invalid_token_ = token; - } - - int get_num_outstanding_requests() { return outstanding_callbacks_.size(); } - - int get_most_recent_request_id() { return most_recent_request_id_; } - - const std::string& get_most_recent_invalid_token() { return invalid_token_; } - - void RespondWithTokenForRequest(int request_id, const std::string& token) { - ASSERT_TRUE(outstanding_callbacks_.count(request_id)); - - auto callback = std::move(outstanding_callbacks_[request_id]); - outstanding_callbacks_.erase(request_id); - - std::move(callback).Run(token); - } - - private: - int most_recent_request_id_ = 0; - std::map<int, OnTokenFetchedCallback> outstanding_callbacks_; - std::string invalid_token_; -}; - -} // namespace - -class SafeBrowsingTokenFetcherImplTest : public testing::Test { - public: - SafeBrowsingTokenFetcherImplTest() = default; - - SafeBrowsingTokenFetcherImplTest(const SafeBrowsingTokenFetcherImplTest&) = - delete; - SafeBrowsingTokenFetcherImplTest& operator=( - const SafeBrowsingTokenFetcherImplTest&) = delete; - - protected: - content::BrowserTaskEnvironment* task_environment() { - return &task_environment_; - } - - private: - content::BrowserTaskEnvironment task_environment_{ - content::BrowserTaskEnvironment::TimeSource::MOCK_TIME}; -}; - -// Tests that SafeBrowsingTokenFetcherImpl responds with an empty token when -// there is no delegate available to fetch tokens from. -TEST_F(SafeBrowsingTokenFetcherImplTest, NoDelegate) { - base::RunLoop run_loop; - std::string access_token = "dummy"; - - SafeBrowsingTokenFetcherImpl fetcher(base::BindRepeating( - []() -> GoogleAccountAccessTokenFetchDelegate* { return nullptr; })); - - fetcher.Start(base::BindOnce(&OnAccessTokenFetched, run_loop.QuitClosure(), - &access_token)); - - run_loop.Run(); - EXPECT_EQ("", access_token); -} - -TEST_F(SafeBrowsingTokenFetcherImplTest, SuccessfulTokenFetch) { - TestAccessTokenFetchDelegate delegate; - base::RunLoop run_loop; - std::string access_token = ""; - std::string kTokenFromResponse = "token"; - - SafeBrowsingTokenFetcherImpl fetcher(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - fetcher.Start(base::BindOnce(&OnAccessTokenFetched, run_loop.QuitClosure(), - &access_token)); - - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - EXPECT_EQ("", access_token); - - delegate.RespondWithTokenForRequest(delegate.get_most_recent_request_id(), - kTokenFromResponse); - - run_loop.Run(); - EXPECT_EQ(kTokenFromResponse, access_token); -} - -// Verifies that destruction of a SafeBrowsingTokenFetcherImpl instance from -// within the client callback that the token was fetched doesn't cause a crash. -TEST_F(SafeBrowsingTokenFetcherImplTest, - FetcherDestroyedFromWithinOnTokenFetchedCallback) { - TestAccessTokenFetchDelegate delegate; - base::RunLoop run_loop; - std::string access_token = ""; - std::string kTokenFromResponse = "token"; - - // Destroyed in the token fetch callback. - auto* fetcher = new SafeBrowsingTokenFetcherImpl(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - fetcher->Start(base::BindOnce( - [](base::OnceClosure quit_closure, std::string* target_token, - SafeBrowsingTokenFetcherImpl* fetcher, const std::string& token) { - *target_token = token; - delete fetcher; - - std::move(quit_closure).Run(); - }, - run_loop.QuitClosure(), &access_token, fetcher)); - - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - EXPECT_EQ("", access_token); - - delegate.RespondWithTokenForRequest(delegate.get_most_recent_request_id(), - kTokenFromResponse); - - run_loop.Run(); - EXPECT_EQ(kTokenFromResponse, access_token); -} - -// Tests correct operation in the case of concurrent requests to -// SafeBrowsingTokenFetcherImpl. -TEST_F(SafeBrowsingTokenFetcherImplTest, ConcurrentRequests) { - TestAccessTokenFetchDelegate delegate; - base::RunLoop run_loop1; - base::RunLoop run_loop2; - std::string access_token1 = ""; - std::string access_token2 = ""; - std::string kTokenFromResponse1 = "token1"; - std::string kTokenFromResponse2 = "token2"; - - SafeBrowsingTokenFetcherImpl fetcher(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - fetcher.Start(base::BindOnce(&OnAccessTokenFetched, run_loop1.QuitClosure(), - &access_token1)); - - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - int request_id1 = delegate.get_most_recent_request_id(); - - EXPECT_EQ("", access_token1); - EXPECT_EQ("", access_token2); - - fetcher.Start(base::BindOnce(&OnAccessTokenFetched, run_loop2.QuitClosure(), - &access_token2)); - EXPECT_EQ(2, delegate.get_num_outstanding_requests()); - int request_id2 = delegate.get_most_recent_request_id(); - - EXPECT_EQ("", access_token1); - EXPECT_EQ("", access_token2); - - delegate.RespondWithTokenForRequest(request_id2, kTokenFromResponse2); - - run_loop2.Run(); - EXPECT_EQ("", access_token1); - EXPECT_EQ(kTokenFromResponse2, access_token2); - - delegate.RespondWithTokenForRequest(request_id1, kTokenFromResponse1); - - run_loop1.Run(); - EXPECT_EQ(kTokenFromResponse1, access_token1); - EXPECT_EQ(kTokenFromResponse2, access_token2); -} - -TEST_F(SafeBrowsingTokenFetcherImplTest, TokenFetchTimeout) { - TestAccessTokenFetchDelegate delegate; - base::RunLoop run_loop; - std::string access_token = "dummy"; - std::string kTokenFromResponse = "token"; - - SafeBrowsingTokenFetcherImpl fetcher(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - fetcher.Start(base::BindOnce(&OnAccessTokenFetched, run_loop.QuitClosure(), - &access_token)); - - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - EXPECT_EQ("dummy", access_token); - - // Fast-forward to trigger the token fetch timeout. - task_environment()->FastForwardBy(base::Milliseconds( - safe_browsing::kTokenFetchTimeoutDelayFromMilliseconds)); - - // Even though the delegate has not yet responded, - // SafeBrowsingTokenFetcherImpl should have responded to its request with the - // empty token. - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - EXPECT_EQ("", access_token); - - // Check that the delegate responding at this point has no adverse effect. - delegate.RespondWithTokenForRequest(delegate.get_most_recent_request_id(), - kTokenFromResponse); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ("", access_token); -} - -// Verifies that destruction of a SafeBrowsingTokenFetcherImpl instance from -// within the client callback that the token was fetched doesn't cause a crash -// when invoked due to the token fetch timing out. -TEST_F(SafeBrowsingTokenFetcherImplTest, - FetcherDestroyedFromWithinOnTokenFetchedCallbackInvokedOnTimeout) { - TestAccessTokenFetchDelegate delegate; - std::string access_token; - bool callback_invoked = false; - - // Destroyed in the token fetch callback, which is invoked on timeout. - auto* fetcher = new SafeBrowsingTokenFetcherImpl(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - fetcher->Start(base::BindOnce( - [](bool* on_invoked_flag, std::string* target_token, - SafeBrowsingTokenFetcherImpl* fetcher, const std::string& token) { - *on_invoked_flag = true; - *target_token = token; - delete fetcher; - }, - &callback_invoked, &access_token, fetcher)); - - // Trigger a timeout of the fetch, which will invoke the client callback - // passed to the fetcher. - task_environment()->FastForwardBy(base::Milliseconds( - safe_browsing::kTokenFetchTimeoutDelayFromMilliseconds)); - ASSERT_TRUE(callback_invoked); - ASSERT_TRUE(access_token.empty()); -} - -TEST_F(SafeBrowsingTokenFetcherImplTest, FetcherDestroyedBeforeFetchReturns) { - TestAccessTokenFetchDelegate delegate; - base::RunLoop run_loop; - std::string access_token = "dummy"; - std::string kTokenFromResponse = "token"; - - auto fetcher = - std::make_unique<SafeBrowsingTokenFetcherImpl>(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - fetcher->Start(base::BindOnce(&OnAccessTokenFetched, run_loop.QuitClosure(), - &access_token)); - - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - EXPECT_EQ("dummy", access_token); - - fetcher.reset(); - - // The fetcher should have responded to the outstanding request with the empty - // token on its destruction. - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - EXPECT_EQ("", access_token); - - // Check that the delegate responding at this point has no adverse effect. - delegate.RespondWithTokenForRequest(delegate.get_most_recent_request_id(), - kTokenFromResponse); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ("", access_token); -} - -// Tests correct operation in the case of concurrent requests to -// SafeBrowsingTokenFetcherImpl made at different times, with an earlier one -// timing out and a later one being fulfilled. -TEST_F(SafeBrowsingTokenFetcherImplTest, ConcurrentRequestsAtDifferentTimes) { - TestAccessTokenFetchDelegate delegate; - base::RunLoop run_loop1; - base::RunLoop run_loop2; - std::string access_token1 = "dummy"; - std::string access_token2 = "dummy"; - std::string kTokenFromResponse1 = "token1"; - std::string kTokenFromResponse2 = "token2"; - int delay_before_second_request_from_ms = - safe_browsing::kTokenFetchTimeoutDelayFromMilliseconds / 2; - - SafeBrowsingTokenFetcherImpl fetcher(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - fetcher.Start(base::BindOnce(&OnAccessTokenFetched, run_loop1.QuitClosure(), - &access_token1)); - - EXPECT_EQ(1, delegate.get_num_outstanding_requests()); - int request_id1 = delegate.get_most_recent_request_id(); - - EXPECT_EQ("dummy", access_token1); - EXPECT_EQ("dummy", access_token2); - - task_environment()->FastForwardBy( - base::Milliseconds(delay_before_second_request_from_ms)); - fetcher.Start(base::BindOnce(&OnAccessTokenFetched, run_loop2.QuitClosure(), - &access_token2)); - EXPECT_EQ(2, delegate.get_num_outstanding_requests()); - int request_id2 = delegate.get_most_recent_request_id(); - - EXPECT_EQ("dummy", access_token1); - EXPECT_EQ("dummy", access_token2); - - // Fast-forward to trigger the first request's timeout threshold, but not the - // second. - int time_to_trigger_first_timeout_from_ms = - safe_browsing::kTokenFetchTimeoutDelayFromMilliseconds - - delay_before_second_request_from_ms; - task_environment()->FastForwardBy( - base::Milliseconds(time_to_trigger_first_timeout_from_ms)); - - // Verify that the first request's timeout was handled by - // SafeBrowsingTokenFetcherImpl. - EXPECT_EQ(2, delegate.get_num_outstanding_requests()); - EXPECT_EQ("", access_token1); - EXPECT_EQ("dummy", access_token2); - - // Verify that the second request can still be fulfilled and that there is no - // adverse effect from the delegate now responding to the first request. - delegate.RespondWithTokenForRequest(request_id1, kTokenFromResponse1); - delegate.RespondWithTokenForRequest(request_id2, kTokenFromResponse2); - - run_loop2.Run(); - EXPECT_EQ("", access_token1); - EXPECT_EQ(kTokenFromResponse2, access_token2); -} - -// Tests that the fetcher calls through to GoogleAccountAccessTokenFetchDelegate -// on being notified of an invalid token. -TEST_F(SafeBrowsingTokenFetcherImplTest, OnInvalidAccessToken) { - TestAccessTokenFetchDelegate delegate; - const std::string kInvalidToken = "dummy"; - - SafeBrowsingTokenFetcherImpl fetcher(base::BindRepeating( - [](TestAccessTokenFetchDelegate* delegate) - -> GoogleAccountAccessTokenFetchDelegate* { return delegate; }, - &delegate)); - - EXPECT_EQ("", delegate.get_most_recent_invalid_token()); - - fetcher.OnInvalidAccessToken(kInvalidToken); - - EXPECT_EQ(kInvalidToken, delegate.get_most_recent_invalid_token()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc b/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc deleted file mode 100644 index 2cf5e0b..0000000 --- a/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/url_checker_delegate_impl.h" - -#include "base/functional/bind.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" -#include "components/safe_browsing/content/browser/ui_manager.h" -#include "components/safe_browsing/core/browser/db/database_manager.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" -#include "components/security_interstitials/core/unsafe_resource.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_manager_factory.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h" - -namespace weblayer { - -namespace { - -// Destroys the NoStatePrefetch contents associated with the web_contents, if -// any. -void DestroyNoStatePrefetchContents( - content::WebContents::OnceGetter web_contents_getter) { - content::WebContents* web_contents = std::move(web_contents_getter).Run(); - - auto* no_state_prefetch_contents = - NoStatePrefetchContentsFromWebContents(web_contents); - if (no_state_prefetch_contents) - no_state_prefetch_contents->Destroy(prerender::FINAL_STATUS_SAFE_BROWSING); -} - -} // namespace - -UrlCheckerDelegateImpl::UrlCheckerDelegateImpl( - scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager, - scoped_refptr<safe_browsing::SafeBrowsingUIManager> ui_manager) - : database_manager_(std::move(database_manager)), - ui_manager_(std::move(ui_manager)), - threat_types_(safe_browsing::CreateSBThreatTypeSet( - {safe_browsing::SB_THREAT_TYPE_URL_MALWARE, - safe_browsing::SB_THREAT_TYPE_URL_PHISHING, - safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, - safe_browsing::SB_THREAT_TYPE_BILLING})) {} - -UrlCheckerDelegateImpl::~UrlCheckerDelegateImpl() = default; - -void UrlCheckerDelegateImpl::MaybeDestroyNoStatePrefetchContents( - content::WebContents::OnceGetter web_contents_getter) { - // Destroy the prefetch with FINAL_STATUS_SAFE_BROWSING. - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&DestroyNoStatePrefetchContents, - std::move(web_contents_getter))); -} - -void UrlCheckerDelegateImpl::StartDisplayingBlockingPageHelper( - const security_interstitials::UnsafeResource& resource, - const std::string& method, - const net::HttpRequestHeaders& headers, - bool is_main_frame, - bool has_user_gesture) { - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce( - &UrlCheckerDelegateImpl::StartDisplayingDefaultBlockingPage, - base::Unretained(this), resource)); -} - -void UrlCheckerDelegateImpl:: - StartObservingInteractionsForDelayedBlockingPageHelper( - const security_interstitials::UnsafeResource& resource, - bool is_main_frame) { - NOTREACHED() << "Delayed warnings aren't implemented for WebLayer"; -} - -void UrlCheckerDelegateImpl::StartDisplayingDefaultBlockingPage( - const security_interstitials::UnsafeResource& resource) { - content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); - if (web_contents) { - GetUIManager()->DisplayBlockingPage(resource); - return; - } - - // Report back that it is not ok to proceed with loading the URL. - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(resource.callback, false /* proceed */, - false /* showed_interstitial */)); -} - -bool UrlCheckerDelegateImpl::IsUrlAllowlisted(const GURL& url) { - // TODO(timvolodine): false for now, we may want allowlisting support later. - return false; -} - -void UrlCheckerDelegateImpl::SetPolicyAllowlistDomains( - const std::vector<std::string>& allowlist_domains) { - // The SafeBrowsingAllowlistDomains policy is not supported on WebLayer. - return; -} - -bool UrlCheckerDelegateImpl::ShouldSkipRequestCheck( - const GURL& original_url, - int frame_tree_node_id, - int render_process_id, - int render_frame_id, - bool originated_from_service_worker) { - return false; -} - -void UrlCheckerDelegateImpl::NotifySuspiciousSiteDetected( - const base::RepeatingCallback<content::WebContents*()>& - web_contents_getter) {} - -const safe_browsing::SBThreatTypeSet& UrlCheckerDelegateImpl::GetThreatTypes() { - return threat_types_; -} - -safe_browsing::SafeBrowsingDatabaseManager* -UrlCheckerDelegateImpl::GetDatabaseManager() { - return database_manager_.get(); -} - -safe_browsing::BaseUIManager* UrlCheckerDelegateImpl::GetUIManager() { - return ui_manager_.get(); -} - -void UrlCheckerDelegateImpl::CheckLookupMechanismExperimentEligibility( - const security_interstitials::UnsafeResource& resource, - base::OnceCallback<void(bool)> callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) { - // Amongst other constraints, this function is only eligible to be called if - // BrowserUrlLoaderThrottle's CheckerOnIO has is_mechanism_experiment_allowed - // = true, which is only the case for Desktop. - NOTREACHED(); -} -void UrlCheckerDelegateImpl::CheckExperimentEligibilityAndStartBlockingPage( - const security_interstitials::UnsafeResource& resource, - base::OnceCallback<void(bool)> callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) { - // Amongst other constraints, this function is only eligible to be called if - // BrowserUrlLoaderThrottle's CheckerOnIO has is_mechanism_experiment_allowed - // = true, which is only the case for Desktop. - NOTREACHED(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/url_checker_delegate_impl.h b/weblayer/browser/safe_browsing/url_checker_delegate_impl.h deleted file mode 100644 index e365ba91..0000000 --- a/weblayer/browser/safe_browsing/url_checker_delegate_impl.h +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_URL_CHECKER_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_URL_CHECKER_DELEGATE_IMPL_H_ - -#include "base/memory/ref_counted.h" -#include "components/safe_browsing/core/browser/url_checker_delegate.h" -#include "content/public/browser/web_contents.h" - -namespace security_interstitials { -struct UnsafeResource; -} - -namespace safe_browsing { -class SafeBrowsingUIManager; -} - -namespace weblayer { - -class UrlCheckerDelegateImpl : public safe_browsing::UrlCheckerDelegate { - public: - UrlCheckerDelegateImpl( - scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> - database_manager, - scoped_refptr<safe_browsing::SafeBrowsingUIManager> ui_manager); - - UrlCheckerDelegateImpl(const UrlCheckerDelegateImpl&) = delete; - UrlCheckerDelegateImpl& operator=(const UrlCheckerDelegateImpl&) = delete; - - void SetSafeBrowsingDisabled(bool disabled); - - private: - ~UrlCheckerDelegateImpl() override; - - // Implementation of UrlCheckerDelegate: - void MaybeDestroyNoStatePrefetchContents( - content::WebContents::OnceGetter web_contents_getter) override; - void StartDisplayingBlockingPageHelper( - const security_interstitials::UnsafeResource& resource, - const std::string& method, - const net::HttpRequestHeaders& headers, - bool is_main_frame, - bool has_user_gesture) override; - void StartObservingInteractionsForDelayedBlockingPageHelper( - const security_interstitials::UnsafeResource& resource, - bool is_main_frame) override; - void CheckLookupMechanismExperimentEligibility( - const security_interstitials::UnsafeResource& resource, - base::OnceCallback<void(bool)> callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override; - void CheckExperimentEligibilityAndStartBlockingPage( - const security_interstitials::UnsafeResource& resource, - base::OnceCallback<void(bool)> callback, - scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override; - bool IsUrlAllowlisted(const GURL& url) override; - void SetPolicyAllowlistDomains( - const std::vector<std::string>& allowlist_domains) override; - bool ShouldSkipRequestCheck(const GURL& original_url, - int frame_tree_node_id, - int render_process_id, - int render_frame_id, - bool originated_from_service_worker) override; - void NotifySuspiciousSiteDetected( - const base::RepeatingCallback<content::WebContents*()>& - web_contents_getter) override; - const safe_browsing::SBThreatTypeSet& GetThreatTypes() override; - safe_browsing::SafeBrowsingDatabaseManager* GetDatabaseManager() override; - safe_browsing::BaseUIManager* GetUIManager() override; - - void StartDisplayingDefaultBlockingPage( - const security_interstitials::UnsafeResource& resource); - - scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_; - scoped_refptr<safe_browsing::SafeBrowsingUIManager> ui_manager_; - safe_browsing::SBThreatTypeSet threat_types_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_URL_CHECKER_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc b/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc deleted file mode 100644 index cb3cb3455..0000000 --- a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h" - -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/android/remote_database_manager.h" -#include "components/safe_browsing/content/browser/client_side_detection_service.h" -#include "content/public/browser/global_routing_id.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" -#include "weblayer/browser/verdict_cache_manager_factory.h" - -namespace weblayer { - -WebLayerClientSideDetectionHostDelegate:: - WebLayerClientSideDetectionHostDelegate(content::WebContents* web_contents) - : web_contents_(web_contents) {} - -WebLayerClientSideDetectionHostDelegate:: - ~WebLayerClientSideDetectionHostDelegate() = default; - -bool WebLayerClientSideDetectionHostDelegate:: - HasSafeBrowsingUserInteractionObserver() { - return false; -} - -PrefService* WebLayerClientSideDetectionHostDelegate::GetPrefs() { - BrowserContextImpl* browser_context_impl = - static_cast<BrowserContextImpl*>(web_contents_->GetBrowserContext()); - DCHECK(browser_context_impl); - return browser_context_impl->pref_service(); -} - -scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> -WebLayerClientSideDetectionHostDelegate::GetSafeBrowsingDBManager() { - SafeBrowsingService* sb_service = - BrowserProcess::GetInstance()->GetSafeBrowsingService(); - return sb_service->GetSafeBrowsingDBManager(); -} - -scoped_refptr<safe_browsing::BaseUIManager> -WebLayerClientSideDetectionHostDelegate::GetSafeBrowsingUIManager() { - SafeBrowsingService* sb_service = - BrowserProcess::GetInstance()->GetSafeBrowsingService(); - return sb_service->GetSafeBrowsingUIManager(); -} - -base::WeakPtr<safe_browsing::ClientSideDetectionService> -WebLayerClientSideDetectionHostDelegate::GetClientSideDetectionService() { - return ClientSideDetectionServiceFactory::GetForBrowserContext( - web_contents_->GetBrowserContext()) - ->GetWeakPtr(); -} - -void WebLayerClientSideDetectionHostDelegate::AddReferrerChain( - safe_browsing::ClientPhishingRequest* verdict, - GURL current_url, - const content::GlobalRenderFrameHostId& current_outermost_main_frame_id) {} - -safe_browsing::VerdictCacheManager* -WebLayerClientSideDetectionHostDelegate::GetCacheManager() { - return VerdictCacheManagerFactory::GetForBrowserContext( - web_contents_->GetBrowserContext()); -} - -safe_browsing::ChromeUserPopulation -WebLayerClientSideDetectionHostDelegate::GetUserPopulation() { - return GetUserPopulationForBrowserContext(web_contents_->GetBrowserContext()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h b/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h deleted file mode 100644 index 661e585..0000000 --- a/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_ - -#include "base/memory/raw_ptr.h" -#include "components/safe_browsing/content/browser/client_side_detection_host.h" -#include "components/safe_browsing/core/common/proto/csd.pb.h" -#include "url/gurl.h" - -namespace content { -struct GlobalRenderFrameHostId; -} // namespace content - -namespace weblayer { - -class WebLayerClientSideDetectionHostDelegate - : public safe_browsing::ClientSideDetectionHost::Delegate { - public: - explicit WebLayerClientSideDetectionHostDelegate( - content::WebContents* web_contents); - - WebLayerClientSideDetectionHostDelegate( - const WebLayerClientSideDetectionHostDelegate&) = delete; - WebLayerClientSideDetectionHostDelegate& operator=( - const WebLayerClientSideDetectionHostDelegate&) = delete; - - ~WebLayerClientSideDetectionHostDelegate() override; - - // ClientSideDetectionHost::Delegate implementation. - bool HasSafeBrowsingUserInteractionObserver() override; - PrefService* GetPrefs() override; - scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> - GetSafeBrowsingDBManager() override; - scoped_refptr<safe_browsing::BaseUIManager> GetSafeBrowsingUIManager() - override; - base::WeakPtr<safe_browsing::ClientSideDetectionService> - GetClientSideDetectionService() override; - void AddReferrerChain(safe_browsing::ClientPhishingRequest* verdict, - GURL current_url, - const content::GlobalRenderFrameHostId& - current_outermost_main_frame_id) override; - safe_browsing::VerdictCacheManager* GetCacheManager() override; - safe_browsing::ChromeUserPopulation GetUserPopulation() override; - - private: - raw_ptr<content::WebContents> web_contents_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_
diff --git a/weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.cc b/weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.cc deleted file mode 100644 index 2dfb4b0..0000000 --- a/weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.h" - -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/core/common/proto/csd.pb.h" -#include "components/safe_browsing/core/common/utils.h" -#include "components/unified_consent/pref_names.h" -#include "content/public/browser/storage_partition.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" - -namespace weblayer { - -WebLayerClientSideDetectionServiceDelegate:: - WebLayerClientSideDetectionServiceDelegate( - BrowserContextImpl* browser_context) - : browser_context_(browser_context) {} - -WebLayerClientSideDetectionServiceDelegate:: - ~WebLayerClientSideDetectionServiceDelegate() = default; - -PrefService* WebLayerClientSideDetectionServiceDelegate::GetPrefs() { - DCHECK(browser_context_); - return browser_context_->pref_service(); -} - -scoped_refptr<network::SharedURLLoaderFactory> -WebLayerClientSideDetectionServiceDelegate::GetURLLoaderFactory() { - return browser_context_->GetDefaultStoragePartition() - ->GetURLLoaderFactoryForBrowserProcess(); -} - -scoped_refptr<network::SharedURLLoaderFactory> -WebLayerClientSideDetectionServiceDelegate::GetSafeBrowsingURLLoaderFactory() { - SafeBrowsingService* sb_service = - BrowserProcess::GetInstance()->GetSafeBrowsingService(); - return sb_service->GetURLLoaderFactory(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.h b/weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.h deleted file mode 100644 index 30f78b0f..0000000 --- a/weblayer/browser/safe_browsing/weblayer_client_side_detection_service_delegate.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_ - -#include "base/memory/raw_ptr.h" -#include "components/safe_browsing/content/browser/client_side_detection_service.h" -#include "weblayer/browser/browser_context_impl.h" - -namespace weblayer { - -class WebLayerClientSideDetectionServiceDelegate - : public safe_browsing::ClientSideDetectionService::Delegate { - public: - explicit WebLayerClientSideDetectionServiceDelegate( - BrowserContextImpl* browser_context); - - WebLayerClientSideDetectionServiceDelegate( - const WebLayerClientSideDetectionServiceDelegate&) = delete; - WebLayerClientSideDetectionServiceDelegate& operator=( - const WebLayerClientSideDetectionServiceDelegate&) = delete; - - ~WebLayerClientSideDetectionServiceDelegate() override; - - // ClientSideDetectionService::Delegate implementation. - PrefService* GetPrefs() override; - scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; - scoped_refptr<network::SharedURLLoaderFactory> - GetSafeBrowsingURLLoaderFactory() override; - - private: - raw_ptr<BrowserContextImpl> browser_context_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_CLIENT_SIDE_DETECTION_SERVICE_DELEGATE_H_
diff --git a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.cc b/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.cc deleted file mode 100644 index a49038a..0000000 --- a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/weblayer_ping_manager_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" -#include "components/safe_browsing/core/browser/ping_manager.h" -#include "content/public/browser/browser_thread.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#include "weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h" -#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" - -namespace weblayer { - -// static -WebLayerPingManagerFactory* WebLayerPingManagerFactory::GetInstance() { - static base::NoDestructor<WebLayerPingManagerFactory> instance; - return instance.get(); -} - -// static -safe_browsing::PingManager* WebLayerPingManagerFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<safe_browsing::PingManager*>( - GetInstance()->GetServiceForBrowserContext(context, /*create=*/true)); -} - -WebLayerPingManagerFactory::WebLayerPingManagerFactory() - : BrowserContextKeyedServiceFactory( - "WeblayerSafeBrowsingPingManager", - BrowserContextDependencyManager::GetInstance()) {} - -WebLayerPingManagerFactory::~WebLayerPingManagerFactory() = default; - -KeyedService* WebLayerPingManagerFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return safe_browsing::PingManager::Create( - safe_browsing::GetV4ProtocolConfig(GetProtocolConfigClientName(), - /*disable_auto_update=*/false), - // TODO(crbug.com/1233532): Should WebLayer support the - // kSafeBrowsingSeparateNetworkContexts feature? - BrowserProcess::GetInstance() - ->GetSafeBrowsingService() - ->GetURLLoaderFactory(), - std::make_unique<SafeBrowsingTokenFetcherImpl>(base::BindRepeating( - &ProfileImpl::access_token_fetch_delegate, - base::Unretained(ProfileImpl::FromBrowserContext(context)))), - base::BindRepeating( - &WebLayerPingManagerFactory::ShouldFetchAccessTokenForReport, - base::Unretained(this), context), - safe_browsing::WebUIInfoSingleton::GetInstance(), - content::GetUIThreadTaskRunner({}), - base::BindRepeating(&GetUserPopulationForBrowserContext, context), - base::BindRepeating(&GetPageLoadTokenForURL, context), - /*hats_delegate=*/nullptr); -} - -bool WebLayerPingManagerFactory::ShouldFetchAccessTokenForReport( - content::BrowserContext* context) const { - PrefService* pref_service = - static_cast<BrowserContextImpl*>(context)->pref_service(); - return safe_browsing::IsEnhancedProtectionEnabled(*pref_service) && - // TODO(crbug.com/1171215): Change this to production mechanism for - // enabling Gaia-keyed client reports once that mechanism is - // determined. - is_account_signed_in_for_testing_; -} - -std::string WebLayerPingManagerFactory::GetProtocolConfigClientName() const { - // Return a weblayer specific client name. - return "weblayer"; -} - -// TODO(crbug.com/1171215): Remove this once browsertests can enable this -// functionality via the production mechanism for doing so. -void WebLayerPingManagerFactory::SignInAccountForTesting() { - is_account_signed_in_for_testing_ = true; -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.h b/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.h deleted file mode 100644 index 13f28345..0000000 --- a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_PING_MANAGER_FACTORY_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_PING_MANAGER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" -#include "components/safe_browsing/core/browser/ping_manager.h" - -namespace weblayer { - -// Factory for creating the KeyedService PingManager for WebLayer. It returns -// null for incognito mode. -class WebLayerPingManagerFactory : public BrowserContextKeyedServiceFactory { - public: - static WebLayerPingManagerFactory* GetInstance(); - static safe_browsing::PingManager* GetForBrowserContext( - content::BrowserContext* context); - - // TODO(crbug.com/1171215): Remove this once browsertests can enable this - // functionality via the production mechanism for doing so. - void SignInAccountForTesting(); - - private: - friend class base::NoDestructor<WebLayerPingManagerFactory>; - friend class WeblayerPingManagerFactoryTest; - - WebLayerPingManagerFactory(); - ~WebLayerPingManagerFactory() override; - - // BrowserContextKeyedServiceFactory override: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - - bool ShouldFetchAccessTokenForReport(content::BrowserContext* context) const; - std::string GetProtocolConfigClientName() const; - - // TODO(crbug.com/1171215): Remove this once browsertests can enable this - // functionality via the production mechanism for doing so. - bool is_account_signed_in_for_testing_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_PING_MANAGER_FACTORY_H_
diff --git a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc b/weblayer/browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc deleted file mode 100644 index 616f5c9..0000000 --- a/weblayer/browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc +++ /dev/null
@@ -1,115 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/functional/bind.h" -#include "base/functional/callback.h" -#include "base/test/bind.h" -#include "base/time/time.h" -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" -#include "services/network/test/test_utils.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/safe_browsing/weblayer_ping_manager_factory.h" -#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" -#include "weblayer/test/weblayer_browser_test.h" - -using safe_browsing::ClientSafeBrowsingReportRequest; -using ReportThreatDetailsResult = - safe_browsing::PingManager::ReportThreatDetailsResult; - -namespace weblayer { - -class WeblayerPingManagerFactoryTest : public WebLayerBrowserTest { - protected: - void RunShouldFetchAccessTokenForReportTest(bool is_enhanced_protection, - bool is_signed_in, - bool expect_should_fetch); -}; -class IncognitoModeWeblayerPingManagerFactoryTest - : public WeblayerPingManagerFactoryTest { - public: - IncognitoModeWeblayerPingManagerFactoryTest() { - SetShellStartsInIncognitoMode(); - } -}; - -void WeblayerPingManagerFactoryTest::RunShouldFetchAccessTokenForReportTest( - bool is_enhanced_protection, - bool is_signed_in, - bool expect_should_fetch) { - SetSafeBrowsingState( - GetProfile()->GetBrowserContext()->pref_service(), - is_enhanced_protection - ? safe_browsing::SafeBrowsingState::ENHANCED_PROTECTION - : safe_browsing::SafeBrowsingState::STANDARD_PROTECTION); - if (is_signed_in) { - WebLayerPingManagerFactory::GetInstance()->SignInAccountForTesting(); - } - EXPECT_EQ( - WebLayerPingManagerFactory::GetInstance() - ->ShouldFetchAccessTokenForReport(GetProfile()->GetBrowserContext()), - expect_should_fetch); -} - -// TODO(crbug.com/1448686) -IN_PROC_BROWSER_TEST_F(WeblayerPingManagerFactoryTest, - DISABLED_ReportThreatDetails) { - auto* ping_manager = WebLayerPingManagerFactory::GetForBrowserContext( - GetProfile()->GetBrowserContext()); - - std::string input_report_content; - std::unique_ptr<ClientSafeBrowsingReportRequest> report = - std::make_unique<ClientSafeBrowsingReportRequest>(); - // The report must be non-empty. The selected property to set is arbitrary. - report->set_type(ClientSafeBrowsingReportRequest::URL_PHISHING); - EXPECT_TRUE(report->SerializeToString(&input_report_content)); - ClientSafeBrowsingReportRequest expected_report; - expected_report.ParseFromString(input_report_content); - *expected_report.mutable_population() = - GetUserPopulationForBrowserContext(GetProfile()->GetBrowserContext()); - std::string expected_report_content; - EXPECT_TRUE(expected_report.SerializeToString(&expected_report_content)); - - network::TestURLLoaderFactory test_url_loader_factory; - test_url_loader_factory.SetInterceptor( - base::BindLambdaForTesting([&](const network::ResourceRequest& request) { - EXPECT_EQ(GetUploadData(request), expected_report_content); - })); - ping_manager->SetURLLoaderFactoryForTesting( - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - &test_url_loader_factory)); - - EXPECT_EQ(ping_manager->ReportThreatDetails(std::move(report)), - ReportThreatDetailsResult::SUCCESS); -} -IN_PROC_BROWSER_TEST_F(IncognitoModeWeblayerPingManagerFactoryTest, - DISABLED_NoPingManagerForIncognito) { - EXPECT_EQ(WebLayerPingManagerFactory::GetForBrowserContext( - GetProfile()->GetBrowserContext()), - nullptr); -} -IN_PROC_BROWSER_TEST_F(WeblayerPingManagerFactoryTest, - ShouldFetchAccessTokenForReport_Yes) { - RunShouldFetchAccessTokenForReportTest(/*is_enhanced_protection=*/true, - /*is_signed_in=*/true, - /*expect_should_fetch=*/true); -} -IN_PROC_BROWSER_TEST_F(WeblayerPingManagerFactoryTest, - ShouldFetchAccessTokenForReport_NotEnhancedProtection) { - RunShouldFetchAccessTokenForReportTest(/*is_enhanced_protection=*/false, - /*is_signed_in=*/true, - /*expect_should_fetch=*/false); -} -IN_PROC_BROWSER_TEST_F(WeblayerPingManagerFactoryTest, - ShouldFetchAccessTokenForReport_NotSignedIn) { - RunShouldFetchAccessTokenForReportTest(/*is_enhanced_protection=*/true, - /*is_signed_in=*/false, - /*expect_should_fetch=*/false); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc b/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc deleted file mode 100644 index c6730353..0000000 --- a/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.h" - -#include "components/security_interstitials/content/security_interstitial_controller_client.h" -#include "components/security_interstitials/content/settings_page_helper.h" -#include "components/security_interstitials/core/base_safe_browsing_error_ui.h" -#include "content/public/browser/navigation_entry.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" - -namespace weblayer { - -safe_browsing::SafeBrowsingBlockingPage* -WebLayerSafeBrowsingBlockingPageFactory::CreateSafeBrowsingPage( - safe_browsing::BaseUIManager* ui_manager, - content::WebContents* web_contents, - const GURL& main_frame_url, - const safe_browsing::SafeBrowsingBlockingPage::UnsafeResourceList& - unsafe_resources, - bool should_trigger_reporting) { - BrowserContextImpl* browser_context = - static_cast<BrowserContextImpl*>(web_contents->GetBrowserContext()); - security_interstitials::BaseSafeBrowsingErrorUI::SBErrorDisplayOptions - display_options = - safe_browsing::BaseBlockingPage::CreateDefaultDisplayOptions( - unsafe_resources); - display_options.is_extended_reporting_opt_in_allowed = - safe_browsing::IsExtendedReportingOptInAllowed( - *(browser_context->pref_service())); - display_options.is_extended_reporting_enabled = - safe_browsing::IsExtendedReportingEnabled( - *(browser_context->pref_service())); - // TODO(crbug.com/1080748): Set settings_page_helper once enhanced protection - // is supported on weblayer. - return new safe_browsing::SafeBrowsingBlockingPage( - ui_manager, web_contents, main_frame_url, unsafe_resources, - safe_browsing::BaseBlockingPage::CreateControllerClient( - web_contents, unsafe_resources, ui_manager, - browser_context->pref_service(), - /*settings_page_helper*/ nullptr), - display_options, should_trigger_reporting, - // WebLayer doesn't integrate //components/history. - /*history_service=*/nullptr, - SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( - browser_context), - SafeBrowsingMetricsCollectorFactory::GetForBrowserContext( - browser_context), - BrowserProcess::GetInstance() - ->GetSafeBrowsingService() - ->GetTriggerManager(), - safe_browsing::IsSafeBrowsingProceedAnywayDisabled( - *(browser_context->pref_service())), - // HaTS surveys are not supported for Weblayer. - /*is_safe_browsing_surveys_enabled=*/false, - /*url_loader_for_testing=*/nullptr); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.h b/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.h deleted file mode 100644 index 0fbb2b2a..0000000 --- a/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_SAFE_BROWSING_BLOCKING_PAGE_FACTORY_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_SAFE_BROWSING_BLOCKING_PAGE_FACTORY_H_ - -#include "components/safe_browsing/content/browser/safe_browsing_blocking_page_factory.h" - -namespace weblayer { - -// Factory for creating SafeBrowsingBlockingPage. -class WebLayerSafeBrowsingBlockingPageFactory - : public safe_browsing::SafeBrowsingBlockingPageFactory { - public: - WebLayerSafeBrowsingBlockingPageFactory() = default; - ~WebLayerSafeBrowsingBlockingPageFactory() override = default; - - // safe_browsing::SafeBrowsingBlockingPageFactory: - safe_browsing::SafeBrowsingBlockingPage* CreateSafeBrowsingPage( - safe_browsing::BaseUIManager* ui_manager, - content::WebContents* web_contents, - const GURL& main_frame_url, - const safe_browsing::SafeBrowsingBlockingPage::UnsafeResourceList& - unsafe_resources, - bool should_trigger_reporting) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_SAFE_BROWSING_BLOCKING_PAGE_FACTORY_H_
diff --git a/weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.cc b/weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.cc deleted file mode 100644 index 7607ca2..0000000 --- a/weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.h" - -#include "base/functional/bind.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/content/browser/client_side_detection_host.h" -#include "components/safe_browsing/content/browser/client_side_detection_service.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#include "weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h" -#include "weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h" - -namespace weblayer { - -namespace { -std::unique_ptr<safe_browsing::ClientSideDetectionHost> -CreateClientSideDetectionHost(content::WebContents* web_contents, - PrefService* prefs, - BrowserContextImpl* browser_context) { - return safe_browsing::ClientSideDetectionHost::Create( - web_contents, - std::make_unique<WebLayerClientSideDetectionHostDelegate>(web_contents), - prefs, - std::make_unique<SafeBrowsingTokenFetcherImpl>(base::BindRepeating( - &ProfileImpl::access_token_fetch_delegate, - base::Unretained(ProfileImpl::FromBrowserContext(browser_context)))), - static_cast<BrowserContextImpl*>(browser_context)->IsOffTheRecord(), - // TODO(crbug.com/1171215): Change this to production mechanism for - // enabling Gaia-keyed CSD once that mechanism is determined. See also - // crbug.com/1190615. - /* account_signed_in_callback= */ base::BindRepeating([]() { - return false; - })); -} - -} // namespace - -WebLayerSafeBrowsingTabObserverDelegate:: - WebLayerSafeBrowsingTabObserverDelegate() = default; -WebLayerSafeBrowsingTabObserverDelegate:: - ~WebLayerSafeBrowsingTabObserverDelegate() = default; - -PrefService* WebLayerSafeBrowsingTabObserverDelegate::GetPrefs( - content::BrowserContext* browser_context) { - return static_cast<BrowserContextImpl*>(browser_context)->pref_service(); -} - -safe_browsing::ClientSideDetectionService* -WebLayerSafeBrowsingTabObserverDelegate::GetClientSideDetectionServiceIfExists( - content::BrowserContext* browser_context) { - return ClientSideDetectionServiceFactory::GetForBrowserContext( - browser_context); -} - -bool WebLayerSafeBrowsingTabObserverDelegate::DoesSafeBrowsingServiceExist() { - return BrowserProcess::GetInstance()->GetSafeBrowsingService(); -} - -std::unique_ptr<safe_browsing::ClientSideDetectionHost> -WebLayerSafeBrowsingTabObserverDelegate::CreateClientSideDetectionHost( - content::WebContents* web_contents) { - BrowserContextImpl* browser_context = - static_cast<BrowserContextImpl*>(web_contents->GetBrowserContext()); - return ::weblayer::CreateClientSideDetectionHost( - web_contents, GetPrefs(browser_context), browser_context); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.h b/weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.h deleted file mode 100644 index bf9058d..0000000 --- a/weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_SAFE_BROWSING_TAB_OBSERVER_DELEGATE_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_SAFE_BROWSING_TAB_OBSERVER_DELEGATE_H_ - -#include "components/safe_browsing/content/browser/safe_browsing_tab_observer.h" - -namespace weblayer { - -// Provides embedder-specific logic for SafeBrowsingTabObserver. -class WebLayerSafeBrowsingTabObserverDelegate - : public safe_browsing::SafeBrowsingTabObserver::Delegate { - public: - WebLayerSafeBrowsingTabObserverDelegate(); - ~WebLayerSafeBrowsingTabObserverDelegate() override; - - WebLayerSafeBrowsingTabObserverDelegate( - const WebLayerSafeBrowsingTabObserverDelegate&) = delete; - WebLayerSafeBrowsingTabObserverDelegate& operator=( - const WebLayerSafeBrowsingTabObserverDelegate&) = delete; - - // SafeBrowsingTabObserver::Delegate: - PrefService* GetPrefs(content::BrowserContext* browser_context) override; - safe_browsing::ClientSideDetectionService* - GetClientSideDetectionServiceIfExists( - content::BrowserContext* browser_context) override; - bool DoesSafeBrowsingServiceExist() override; - std::unique_ptr<safe_browsing::ClientSideDetectionHost> - CreateClientSideDetectionHost(content::WebContents* web_contents) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_SAFE_BROWSING_TAB_OBSERVER_DELEGATE_H_
diff --git a/weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.cc b/weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.cc deleted file mode 100644 index afbac93..0000000 --- a/weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.cc +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.h" - -#include "components/safe_browsing/core/browser/ping_manager.h" -#include "content/public/browser/web_contents.h" -#include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h" -#include "weblayer/browser/safe_browsing/weblayer_ping_manager_factory.h" -#include "weblayer/browser/weblayer_metrics_service_accessor.h" - -namespace weblayer { - -WebLayerSafeBrowsingUIManagerDelegate::WebLayerSafeBrowsingUIManagerDelegate() = - default; -WebLayerSafeBrowsingUIManagerDelegate:: - ~WebLayerSafeBrowsingUIManagerDelegate() = default; - -std::string WebLayerSafeBrowsingUIManagerDelegate::GetApplicationLocale() { - return i18n::GetApplicationLocale(); -} - -void WebLayerSafeBrowsingUIManagerDelegate:: - TriggerSecurityInterstitialShownExtensionEventIfDesired( - content::WebContents* web_contents, - const GURL& page_url, - const std::string& reason, - int net_error_code) {} - -void WebLayerSafeBrowsingUIManagerDelegate:: - TriggerSecurityInterstitialProceededExtensionEventIfDesired( - content::WebContents* web_contents, - const GURL& page_url, - const std::string& reason, - int net_error_code) {} - -prerender::NoStatePrefetchContents* -WebLayerSafeBrowsingUIManagerDelegate::GetNoStatePrefetchContentsIfExists( - content::WebContents* web_contents) { - return NoStatePrefetchContentsFromWebContents(web_contents); -} - -bool WebLayerSafeBrowsingUIManagerDelegate::IsHostingExtension( - content::WebContents* web_contents) { - return false; -} - -PrefService* WebLayerSafeBrowsingUIManagerDelegate::GetPrefs( - content::BrowserContext* browser_context) { - return static_cast<BrowserContextImpl*>(browser_context)->pref_service(); -} - -history::HistoryService* -WebLayerSafeBrowsingUIManagerDelegate::GetHistoryService( - content::BrowserContext* browser_context) { - return nullptr; -} - -safe_browsing::PingManager* -WebLayerSafeBrowsingUIManagerDelegate::GetPingManager( - content::BrowserContext* browser_context) { - return WebLayerPingManagerFactory::GetForBrowserContext(browser_context); -} - -bool WebLayerSafeBrowsingUIManagerDelegate:: - IsMetricsAndCrashReportingEnabled() { - return WebLayerMetricsServiceAccessor::IsMetricsReportingEnabled( - BrowserProcess::GetInstance()->GetLocalState()); -} - -bool WebLayerSafeBrowsingUIManagerDelegate::IsSendingOfHitReportsEnabled() { - // TODO(crbug.com/1232315): Determine whether to enable sending of hit reports - // in WebLayer. - return false; -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.h b/weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.h deleted file mode 100644 index 50543ff..0000000 --- a/weblayer/browser/safe_browsing/weblayer_ui_manager_delegate.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_UI_MANAGER_DELEGATE_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_UI_MANAGER_DELEGATE_H_ - -#include "components/safe_browsing/content/browser/ui_manager.h" - -namespace weblayer { - -// Provides embedder-specific logic for SafeBrowsingUIManager. -class WebLayerSafeBrowsingUIManagerDelegate - : public safe_browsing::SafeBrowsingUIManager::Delegate { - public: - WebLayerSafeBrowsingUIManagerDelegate(); - ~WebLayerSafeBrowsingUIManagerDelegate() override; - - WebLayerSafeBrowsingUIManagerDelegate( - const WebLayerSafeBrowsingUIManagerDelegate&) = delete; - WebLayerSafeBrowsingUIManagerDelegate& operator=( - const WebLayerSafeBrowsingUIManagerDelegate&) = delete; - - // safe_browsing::SafeBrowsingUIManager::Delegate: - std::string GetApplicationLocale() override; - void TriggerSecurityInterstitialShownExtensionEventIfDesired( - content::WebContents* web_contents, - const GURL& page_url, - const std::string& reason, - int net_error_code) override; - void TriggerSecurityInterstitialProceededExtensionEventIfDesired( - content::WebContents* web_contents, - const GURL& page_url, - const std::string& reason, - int net_error_code) override; - prerender::NoStatePrefetchContents* GetNoStatePrefetchContentsIfExists( - content::WebContents* web_contents) override; - bool IsHostingExtension(content::WebContents* web_contents) override; - PrefService* GetPrefs(content::BrowserContext* browser_context) override; - history::HistoryService* GetHistoryService( - content::BrowserContext* browser_context) override; - safe_browsing::PingManager* GetPingManager( - content::BrowserContext* browser_context) override; - bool IsMetricsAndCrashReportingEnabled() override; - bool IsSendingOfHitReportsEnabled() override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_UI_MANAGER_DELEGATE_H_
diff --git a/weblayer/browser/safe_browsing/weblayer_user_population_helper.cc b/weblayer/browser/safe_browsing/weblayer_user_population_helper.cc deleted file mode 100644 index fc30b92..0000000 --- a/weblayer/browser/safe_browsing/weblayer_user_population_helper.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" - -#include "components/safe_browsing/core/browser/user_population.h" -#include "components/safe_browsing/core/browser/verdict_cache_manager.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/verdict_cache_manager_factory.h" - -namespace weblayer { - -safe_browsing::ChromeUserPopulation GetUserPopulationForBrowserContext( - content::BrowserContext* browser_context) { - auto* browser_context_impl = - static_cast<BrowserContextImpl*>(browser_context); - - return safe_browsing::GetUserPopulation( - browser_context_impl->pref_service(), - browser_context_impl->IsOffTheRecord(), - /*is_history_sync_active=*/false, - /*is_signed_in=*/false, - /*is_under_advanced_protection=*/false, - /*browser_policy_connector=*/nullptr, - /*num_profiles=*/absl::optional<size_t>(), - /*num_loaded_profiles=*/absl::optional<size_t>(), - /*num_open_profiles=*/absl::optional<size_t>()); -} - -safe_browsing::ChromeUserPopulation::PageLoadToken GetPageLoadTokenForURL( - content::BrowserContext* browser_context, - GURL url) { - safe_browsing::VerdictCacheManager* cache_manager = - VerdictCacheManagerFactory::GetForBrowserContext(browser_context); - if (!cache_manager) { - return safe_browsing::ChromeUserPopulation::PageLoadToken(); - } - return cache_manager->GetPageLoadToken(url); -} - -} // namespace weblayer
diff --git a/weblayer/browser/safe_browsing/weblayer_user_population_helper.h b/weblayer/browser/safe_browsing/weblayer_user_population_helper.h deleted file mode 100644 index 349abc49..0000000 --- a/weblayer/browser/safe_browsing/weblayer_user_population_helper.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_USER_POPULATION_HELPER_H_ -#define WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_USER_POPULATION_HELPER_H_ - -#include "components/safe_browsing/core/common/proto/csd.pb.h" -#include "url/gurl.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { - -// A convenience function that creates a ChromeUserPopulation proto for the -// given |browser_context| and populates it appropriately for WebLayer. -safe_browsing::ChromeUserPopulation GetUserPopulationForBrowserContext( - content::BrowserContext* browser_context); - -// A function that returns tha page load token for the provided URL -safe_browsing::ChromeUserPopulation::PageLoadToken GetPageLoadTokenForURL( - content::BrowserContext* browser_context, - GURL url); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SAFE_BROWSING_WEBLAYER_USER_POPULATION_HELPER_H_
diff --git a/weblayer/browser/signin_url_loader_throttle.cc b/weblayer/browser/signin_url_loader_throttle.cc deleted file mode 100644 index a51de55b..0000000 --- a/weblayer/browser/signin_url_loader_throttle.cc +++ /dev/null
@@ -1,198 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/signin_url_loader_throttle.h" - -#include "components/content_settings/core/browser/cookie_settings.h" -#include "components/signin/core/browser/signin_header_helper.h" -#include "components/signin/public/base/account_consistency_method.h" -#include "components/signin/public/identity_manager/tribool.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "google_apis/gaia/gaia_auth_util.h" -#include "net/base/url_util.h" -#include "services/network/public/cpp/resource_request.h" -#include "services/network/public/mojom/url_response_head.mojom.h" -#include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" -#include "weblayer/browser/cookie_settings_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/google_accounts_delegate.h" - -namespace weblayer { - -const char kSignOutPath[] = "/SignOutOptions"; - -namespace { -constexpr char kWebLayerMirrorHeaderSource[] = "WebLayer"; - -GoogleAccountsDelegate* GetDelegate( - const content::WebContents::Getter& web_contents_getter) { - auto* web_contents = web_contents_getter.Run(); - if (!web_contents) - return nullptr; - - auto* tab = TabImpl::FromWebContents(web_contents); - if (!tab) - return nullptr; - - return tab->google_accounts_delegate(); -} - -void ProcessMirrorHeader(content::WebContents::Getter web_contents_getter, - const signin::ManageAccountsParams& params) { - auto* delegate = GetDelegate(web_contents_getter); - if (delegate) - delegate->OnGoogleAccountsRequest(params); -} - -void MaybeAddQueryParams(GURL* url) { - // Add manage=true to query parameters for sign out URLs to make sure we - // receive the Mirror response headers instead of the normal sign out page. - if (gaia::HasGaiaSchemeHostPort(*url) && url->path_piece() == kSignOutPath) { - *url = net::AppendOrReplaceQueryParameter(*url, "manage", "true"); - } -} -} // namespace - -SigninURLLoaderThrottle::~SigninURLLoaderThrottle() = default; - -// static -std::unique_ptr<SigninURLLoaderThrottle> SigninURLLoaderThrottle::Create( - content::BrowserContext* browser_context, - content::WebContents::Getter web_contents_getter) { - if (!GetDelegate(web_contents_getter)) - return nullptr; - - // Use base::WrapUnique + new because of the constructor is private. - return base::WrapUnique(new SigninURLLoaderThrottle( - browser_context, std::move(web_contents_getter))); -} - -void SigninURLLoaderThrottle::WillStartRequest( - network::ResourceRequest* request, - bool* defer) { - GoogleAccountsDelegate* delegate = GetDelegate(web_contents_getter_); - if (!delegate) - return; - - MaybeAddQueryParams(&request->url); - - request_url_ = request->url; - is_main_frame_ = - static_cast<blink::mojom::ResourceType>(request->resource_type) == - blink::mojom::ResourceType::kMainFrame; - - net::HttpRequestHeaders modified_request_headers; - std::vector<std::string> to_be_removed_request_headers; - ProcessRequest(GURL(), &request->headers, &to_be_removed_request_headers, - &modified_request_headers); - signin::RequestAdapter adapter(request_url_, request->headers, - &modified_request_headers, - &to_be_removed_request_headers); - request_headers_.CopyFrom(request->headers); -} - -void SigninURLLoaderThrottle::WillRedirectRequest( - net::RedirectInfo* redirect_info, - const network::mojom::URLResponseHead& response_head, - bool* defer, - std::vector<std::string>* headers_to_remove, - net::HttpRequestHeaders* modified_headers, - net::HttpRequestHeaders* modified_cors_exempt_request_headers) { - if (!GetDelegate(web_contents_getter_)) - return; - - MaybeAddQueryParams(&redirect_info->new_url); - - ProcessRequest(redirect_info->new_url, &request_headers_, headers_to_remove, - modified_headers); - ProcessResponse(response_head.headers.get()); - - request_url_ = redirect_info->new_url; -} - -void SigninURLLoaderThrottle::WillProcessResponse( - const GURL& response_url, - network::mojom::URLResponseHead* response_head, - bool* defer) { - if (!GetDelegate(web_contents_getter_)) - return; - - ProcessResponse(response_head->headers.get()); -} - -SigninURLLoaderThrottle::SigninURLLoaderThrottle( - content::BrowserContext* browser_context, - content::WebContents::Getter web_contents_getter) - : browser_context_(browser_context), - web_contents_getter_(std::move(web_contents_getter)) {} - -void SigninURLLoaderThrottle::ProcessRequest( - const GURL& new_url, - net::HttpRequestHeaders* original_headers, - std::vector<std::string>* headers_to_remove, - net::HttpRequestHeaders* modified_headers) { - GoogleAccountsDelegate* delegate = GetDelegate(web_contents_getter_); - if (!delegate) - return; - - signin::RequestAdapter request_adapter(request_url_, *original_headers, - modified_headers, headers_to_remove); - // Disable incognito and adding accounts for now. This shouldn't matter in - // practice though since we are skipping the /SignOutOptions page completely - // with the manage=true param. - // - // TODO(crbug.com/1134042): Check whether the child account status should also - // be sent in the Mirror request header from WebLayer. - signin::AppendOrRemoveMirrorRequestHeader( - &request_adapter, new_url, delegate->GetGaiaId(), - /*is_child_account=*/signin::Tribool::kUnknown, - signin::AccountConsistencyMethod::kMirror, - CookieSettingsFactory::GetForBrowserContext(browser_context_).get(), - signin::PROFILE_MODE_INCOGNITO_DISABLED | - signin::PROFILE_MODE_ADD_ACCOUNT_DISABLED, - kWebLayerMirrorHeaderSource, /*force_account_consistency=*/true); - - original_headers->MergeFrom(*modified_headers); - for (const std::string& name : *headers_to_remove) - original_headers->RemoveHeader(name); -} - -void SigninURLLoaderThrottle::ProcessResponse( - const net::HttpResponseHeaders* headers) { - if (!gaia::HasGaiaSchemeHostPort(request_url_) || !is_main_frame_ || - !headers) { - return; - } - - std::string header_value; - if (!headers->GetNormalizedHeader(signin::kChromeManageAccountsHeader, - &header_value)) { - return; - } - - signin::ManageAccountsParams params = - signin::BuildManageAccountsParams(header_value); - if (params.service_type == signin::GAIA_SERVICE_TYPE_NONE) - return; - - // Only process one mirror header per request (multiple headers on the same - // redirect chain are ignored). - if (response_header_processed_) { - LOG(ERROR) << "Multiple X-Chrome-Manage-Accounts headers on a redirect " - << "chain, ignoring"; - return; - } - - response_header_processed_ = true; - - // Post a task even if we are already on the UI thread to avoid making any - // requests while processing a throttle event. - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&ProcessMirrorHeader, web_contents_getter_, params)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/signin_url_loader_throttle.h b/weblayer/browser/signin_url_loader_throttle.h deleted file mode 100644 index 2a3d50b..0000000 --- a/weblayer/browser/signin_url_loader_throttle.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SIGNIN_URL_LOADER_THROTTLE_H_ -#define WEBLAYER_BROWSER_SIGNIN_URL_LOADER_THROTTLE_H_ - -#include "base/memory/raw_ptr.h" -#include "components/signin/core/browser/signin_header_helper.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/web_contents.h" -#include "net/http/http_request_headers.h" -#include "third_party/blink/public/common/loader/url_loader_throttle.h" - -namespace net { -class HttpResponseHeaders; -} - -namespace weblayer { - -// Exposed for testing. -extern const char kSignOutPath[]; - -class SigninURLLoaderThrottle : public blink::URLLoaderThrottle { - public: - ~SigninURLLoaderThrottle() override; - - static std::unique_ptr<SigninURLLoaderThrottle> Create( - content::BrowserContext* browser_context, - content::WebContents::Getter web_contents_getter); - - // blink::URLLoaderThrottle - void WillStartRequest(network::ResourceRequest* request, - bool* defer) override; - void WillRedirectRequest( - net::RedirectInfo* redirect_info, - const network::mojom::URLResponseHead& response_head, - bool* defer, - std::vector<std::string>* headers_to_remove, - net::HttpRequestHeaders* modified_headers, - net::HttpRequestHeaders* modified_cors_exempt_request_headers) override; - void WillProcessResponse(const GURL& response_url, - network::mojom::URLResponseHead* response_head, - bool* defer) override; - - private: - SigninURLLoaderThrottle(content::BrowserContext* browser_context, - content::WebContents::Getter web_contents_getter); - - void ProcessRequest(const GURL& url, - net::HttpRequestHeaders* original_headers, - std::vector<std::string>* headers_to_remove, - net::HttpRequestHeaders* modified_headers); - void ProcessResponse(const net::HttpResponseHeaders* headers); - - raw_ptr<content::BrowserContext> browser_context_; - content::WebContents::Getter web_contents_getter_; - net::HttpRequestHeaders request_headers_; - GURL request_url_; - bool is_main_frame_ = false; - bool response_header_processed_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SIGNIN_URL_LOADER_THROTTLE_H_
diff --git a/weblayer/browser/site_engagement/site_engagement_service_factory.cc b/weblayer/browser/site_engagement/site_engagement_service_factory.cc deleted file mode 100644 index a5a2232..0000000 --- a/weblayer/browser/site_engagement/site_engagement_service_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/site_engagement/site_engagement_service_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" - -using site_engagement::SiteEngagementService; - -namespace weblayer { - -// static -SiteEngagementService* SiteEngagementServiceFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<SiteEngagementService*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - /*create=*/true)); -} - -// static -SiteEngagementServiceFactory* SiteEngagementServiceFactory::GetInstance() { - static base::NoDestructor<SiteEngagementServiceFactory> factory; - return factory.get(); -} - -SiteEngagementServiceFactory::SiteEngagementServiceFactory() - : BrowserContextKeyedServiceFactory( - "SiteEngagementService", - BrowserContextDependencyManager::GetInstance()) { - SiteEngagementService::SetServiceProvider(this); -} - -SiteEngagementServiceFactory::~SiteEngagementServiceFactory() { - SiteEngagementService::ClearServiceProvider(this); -} - -std::unique_ptr<KeyedService> -SiteEngagementServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser_context) const { - return std::make_unique<SiteEngagementService>(browser_context); -} - -content::BrowserContext* SiteEngagementServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -SiteEngagementService* SiteEngagementServiceFactory::GetSiteEngagementService( - content::BrowserContext* browser_context) { - return GetForBrowserContext(browser_context); -} - -} // namespace weblayer
diff --git a/weblayer/browser/site_engagement/site_engagement_service_factory.h b/weblayer/browser/site_engagement/site_engagement_service_factory.h deleted file mode 100644 index 4c34a67..0000000 --- a/weblayer/browser/site_engagement/site_engagement_service_factory.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SITE_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_SITE_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" -#include "components/site_engagement/content/site_engagement_service.h" - -namespace weblayer { - -// Singleton that owns all SiteEngagementServices and associates them with -// BrowserContexts. -class SiteEngagementServiceFactory - : public BrowserContextKeyedServiceFactory, - public site_engagement::SiteEngagementService::ServiceProvider { - public: - SiteEngagementServiceFactory(const SiteEngagementServiceFactory&) = delete; - SiteEngagementServiceFactory& operator=(const SiteEngagementServiceFactory&) = - delete; - - // Creates the service if it doesn't already exist for the given - // |browser_context|. If the service already exists, return it. - static site_engagement::SiteEngagementService* GetForBrowserContext( - content::BrowserContext* browser_context); - - static SiteEngagementServiceFactory* GetInstance(); - - // SiteEngagementService::ServiceProvider: - site_engagement::SiteEngagementService* GetSiteEngagementService( - content::BrowserContext* browser_context) override; - - private: - friend class base::NoDestructor<SiteEngagementServiceFactory>; - - SiteEngagementServiceFactory(); - ~SiteEngagementServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser_context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SITE_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/site_isolation_browsertest.cc b/weblayer/browser/site_isolation_browsertest.cc deleted file mode 100644 index bf4334c..0000000 --- a/weblayer/browser/site_isolation_browsertest.cc +++ /dev/null
@@ -1,274 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/memory/raw_ptr.h" -#include "base/system/sys_info.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/prefs/pref_service.h" -#include "components/site_isolation/features.h" -#include "components/site_isolation/pref_names.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/site_isolation_policy.h" -#include "content/public/common/content_client.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_navigation_observer.h" -#include "net/dns/mock_host_resolver.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/content_browser_client_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { -using testing::IsEmpty; -using testing::UnorderedElementsAre; - -class SiteIsolationBrowserTest : public WebLayerBrowserTest { - public: - SiteIsolationBrowserTest() { - feature_list_.InitWithFeaturesAndParameters( - {{site_isolation::features::kSiteIsolationMemoryThresholds, - {{site_isolation::features:: - kPartialSiteIsolationMemoryThresholdParamName, - "128"}}}, - {site_isolation::features::kSiteIsolationForPasswordSites, {}}}, - {}); - } - - std::vector<std::string> GetSavedIsolatedSites() { - PrefService* prefs = - user_prefs::UserPrefs::Get(GetProfile()->GetBrowserContext()); - const auto& list = - prefs->GetList(site_isolation::prefs::kUserTriggeredIsolatedOrigins); - std::vector<std::string> sites; - for (const base::Value& value : list) - sites.push_back(value.GetString()); - return sites; - } - - // WebLayerBrowserTest: - void SetUpOnMainThread() override { - original_client_ = content::SetBrowserClientForTesting(&browser_client_); - host_resolver()->AddRule("*", "127.0.0.1"); - embedded_test_server()->ServeFilesFromSourceDirectory("weblayer/test/data"); - ASSERT_TRUE(embedded_test_server()->Start()); - - ASSERT_FALSE( - content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites()); - ASSERT_TRUE( - content::SiteIsolationPolicy::AreDynamicIsolatedOriginsEnabled()); - } - - void TearDownOnMainThread() override { - content::SetBrowserClientForTesting(original_client_); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch("ignore-certificate-errors"); - - // This way the test always sees the same amount of physical memory - // (kLowMemoryDeviceThresholdMB = 512MB), regardless of how much memory is - // available in the testing environment. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableLowEndDeviceMode); - EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB()); - } - - content::WebContents* GetWebContents() { - return static_cast<TabImpl*>(shell()->tab())->web_contents(); - } - - void StartIsolatingSite(const GURL& url) { - content::SiteInstance::StartIsolatingSite( - GetProfile()->GetBrowserContext(), url, - content::ChildProcessSecurityPolicy::IsolatedOriginSource:: - USER_TRIGGERED); - } - - private: - // A browser client which forces off strict site isolation, so the test can - // assume password isolation is enabled. - class SiteIsolationContentBrowserClient : public ContentBrowserClientImpl { - public: - SiteIsolationContentBrowserClient() : ContentBrowserClientImpl(nullptr) {} - - bool ShouldEnableStrictSiteIsolation() override { return false; } - }; - - SiteIsolationContentBrowserClient browser_client_; - raw_ptr<content::ContentBrowserClient> original_client_ = nullptr; - base::test::ScopedFeatureList feature_list_; -}; - -IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, - SiteIsIsolatedAfterEnteringPassword) { - GURL url = embedded_test_server()->GetURL("sub.foo.com", - "/simple_password_form.html"); - NavigateAndWaitForCompletion(url, shell()); - content::WebContents* contents = GetWebContents(); - - // foo.com should not be isolated to start with. Verify that a cross-site - // iframe does not become an OOPIF. - EXPECT_FALSE(contents->GetPrimaryMainFrame() - ->GetSiteInstance() - ->RequiresDedicatedProcess()); - std::string kAppendIframe = R"( - var i = document.createElement('iframe'); - i.id = 'child'; - document.body.appendChild(i);)"; - EXPECT_TRUE(content::ExecJs(contents, kAppendIframe)); - GURL bar_url(embedded_test_server()->GetURL("bar.com", "/simple_page.html")); - EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url)); - content::RenderFrameHost* child = - ChildFrameAt(contents->GetPrimaryMainFrame(), 0); - EXPECT_FALSE(child->IsCrossProcessSubframe()); - - // Fill a form and submit through a <input type="submit"> button. - content::TestNavigationObserver observer(contents); - std::string kFillAndSubmit = - "document.getElementById('username_field').value = 'temp';" - "document.getElementById('password_field').value = 'random';" - "document.getElementById('input_submit_button').click()"; - EXPECT_TRUE(content::ExecJs(contents, kFillAndSubmit)); - observer.Wait(); - - // Since there were no script references from other windows, we should've - // swapped BrowsingInstances and put the result of the form submission into a - // dedicated process, locked to foo.com. Check that a cross-site iframe now - // becomes an OOPIF. - EXPECT_TRUE(contents->GetPrimaryMainFrame() - ->GetSiteInstance() - ->RequiresDedicatedProcess()); - EXPECT_TRUE(ExecJs(contents, kAppendIframe)); - EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url)); - child = ChildFrameAt(contents->GetPrimaryMainFrame(), 0); - EXPECT_TRUE(child->IsCrossProcessSubframe()); -} - -// TODO(crbug.com/654704): Android does not support PRE_ tests. -#if !BUILDFLAG(IS_ANDROID) -IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, - PRE_IsolatedSitesPersistAcrossRestarts) { - // There shouldn't be any saved isolated origins to start with. - EXPECT_THAT(GetSavedIsolatedSites(), IsEmpty()); - - // Isolate saved.com and saved2.com persistently. - GURL saved_url = - embedded_test_server()->GetURL("saved.com", "/simple_page.html"); - StartIsolatingSite(saved_url); - GURL saved2_url = - embedded_test_server()->GetURL("saved2.com", "/simple_page.html"); - StartIsolatingSite(saved2_url); - - NavigateAndWaitForCompletion(saved_url, shell()); - EXPECT_TRUE(GetWebContents() - ->GetPrimaryMainFrame() - ->GetSiteInstance() - ->RequiresDedicatedProcess()); - - // Check that saved.com and saved2.com were saved to disk. - EXPECT_THAT(GetSavedIsolatedSites(), - UnorderedElementsAre("http://saved.com", "http://saved2.com")); -} - -IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, - IsolatedSitesPersistAcrossRestarts) { - // Check that saved.com and saved2.com are still saved to disk. - EXPECT_THAT(GetSavedIsolatedSites(), - UnorderedElementsAre("http://saved.com", "http://saved2.com")); - - // Check that these sites utilize a dedicated process after restarting, but a - // non-isolated foo.com URL does not. - GURL saved_url = - embedded_test_server()->GetURL("saved.com", "/simple_page.html"); - GURL saved2_url = - embedded_test_server()->GetURL("saved2.com", "/simple_page2.html"); - GURL foo_url = - embedded_test_server()->GetURL("foo.com", "/simple_page3.html"); - NavigateAndWaitForCompletion(saved_url, shell()); - content::WebContents* contents = GetWebContents(); - EXPECT_TRUE(contents->GetPrimaryMainFrame() - ->GetSiteInstance() - ->RequiresDedicatedProcess()); - NavigateAndWaitForCompletion(saved2_url, shell()); - EXPECT_TRUE(contents->GetPrimaryMainFrame() - ->GetSiteInstance() - ->RequiresDedicatedProcess()); - NavigateAndWaitForCompletion(foo_url, shell()); - EXPECT_FALSE(contents->GetPrimaryMainFrame() - ->GetSiteInstance() - ->RequiresDedicatedProcess()); -} -#endif - -IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, IsolatedSiteIsSavedOnlyOnce) { - GURL saved_url = - embedded_test_server()->GetURL("saved.com", "/simple_page.html"); - StartIsolatingSite(saved_url); - StartIsolatingSite(saved_url); - StartIsolatingSite(saved_url); - EXPECT_THAT(GetSavedIsolatedSites(), - UnorderedElementsAre("http://saved.com")); -} - -// Failing on Android, see https://crbug.com/1254509. -#if defined(ANDROID) -#define MAYBE_ClearSiteDataHeaderDoesNotClearSavedIsolatedSites \ - ClearSiteDataHeaderDoesNotClearSavedIsolatedSites -#else -#define MAYBE_ClearSiteDataHeaderDoesNotClearSavedIsolatedSites \ - ClearSiteDataHeaderDoesNotClearSavedIsolatedSites -#endif -// Verify that serving a Clear-Site-Data header does not clear saved isolated -// sites. Saved isolated sites should only be cleared by user-initiated actions. -IN_PROC_BROWSER_TEST_F( - SiteIsolationBrowserTest, - MAYBE_ClearSiteDataHeaderDoesNotClearSavedIsolatedSites) { - // Start an HTTPS server, as Clear-Site-Data is only available on HTTPS URLs. - net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); - https_server.AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - ASSERT_TRUE(https_server.Start()); - - // Isolate saved.com and verify it's been saved to disk. - GURL saved_url = https_server.GetURL("saved.com", "/clear_site_data.html"); - StartIsolatingSite(saved_url); - EXPECT_THAT(GetSavedIsolatedSites(), - UnorderedElementsAre("https://saved.com")); - - // Navigate to a URL that serves a Clear-Site-Data header for cache, cookies, - // and DOM storage. This is the most that a Clear-Site-Data header could - // clear, and this should not clear saved isolated sites. - NavigateAndWaitForCompletion(saved_url, shell()); - EXPECT_THAT(GetSavedIsolatedSites(), - UnorderedElementsAre("https://saved.com")); -} - -IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, - ExplicitClearBrowsingDataClearsSavedIsolatedSites) { - GURL saved_url = - embedded_test_server()->GetURL("saved.com", "/simple_page.html"); - StartIsolatingSite(saved_url); - EXPECT_THAT(GetSavedIsolatedSites(), - UnorderedElementsAre("http://saved.com")); - - base::RunLoop run_loop; - base::Time now = base::Time::Now(); - GetProfile()->ClearBrowsingData({BrowsingDataType::COOKIES_AND_SITE_DATA}, - now - base::Days(1), now, - run_loop.QuitClosure()); - run_loop.Run(); - - EXPECT_THAT(GetSavedIsolatedSites(), IsEmpty()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/site_isolation_policy_unittest.cc b/weblayer/browser/site_isolation_policy_unittest.cc deleted file mode 100644 index a5934c253..0000000 --- a/weblayer/browser/site_isolation_policy_unittest.cc +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/site_isolation/site_isolation_policy.h" - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/system/sys_info.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/site_isolation/features.h" -#include "components/site_isolation/preloaded_isolated_origins.h" -#include "content/public/browser/child_process_security_policy.h" -#include "content/public/browser/site_isolation_policy.h" -#include "content/public/common/content_features.h" -#include "content/public/common/content_switches.h" -#include "content/public/test/browser_task_environment.h" -#include "content/public/test/test_utils.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace weblayer { -namespace { -using testing::UnorderedElementsAreArray; - -// Some command-line switches override field trials - the tests need to be -// skipped in this case. -bool ShouldSkipBecauseOfConflictingCommandLineSwitches() { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSitePerProcess)) - return true; - - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableSiteIsolation)) - return true; - - return false; -} - -} // namespace - -class SiteIsolationPolicyTest : public testing::Test { - public: - SiteIsolationPolicyTest() = default; - - SiteIsolationPolicyTest(const SiteIsolationPolicyTest&) = delete; - SiteIsolationPolicyTest& operator=(const SiteIsolationPolicyTest&) = delete; - - void SetUp() override { - // This way the test always sees the same amount of physical memory - // (kLowMemoryDeviceThresholdMB = 512MB), regardless of how much memory is - // available in the testing environment. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableLowEndDeviceMode); - EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB()); - } - - // Sets the same memory threshold for both strict site isolation and partial - // site isolation modes, since these tests care about both. For example, - // UseDedicatedProcessesForAllSites() depends on the former, while preloaded - // isolated origins use the latter. - void SetMemoryThreshold(const std::string& threshold) { - threshold_feature_.InitAndEnableFeatureWithParameters( - site_isolation::features::kSiteIsolationMemoryThresholds, - {{site_isolation::features:: - kStrictSiteIsolationMemoryThresholdParamName, - threshold}, - {site_isolation::features:: - kPartialSiteIsolationMemoryThresholdParamName, - threshold}}); - } - - private: - content::BrowserTaskEnvironment task_environment_; - base::test::ScopedFeatureList threshold_feature_; -}; - -TEST_F(SiteIsolationPolicyTest, NoIsolationBelowMemoryThreshold) { - if (ShouldSkipBecauseOfConflictingCommandLineSwitches()) - return; - - SetMemoryThreshold("768"); - EXPECT_FALSE( - content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites()); - EXPECT_FALSE( - content::SiteIsolationPolicy::ArePreloadedIsolatedOriginsEnabled()); -} - -TEST_F(SiteIsolationPolicyTest, IsolationAboveMemoryThreshold) { - if (ShouldSkipBecauseOfConflictingCommandLineSwitches()) - return; - - SetMemoryThreshold("128"); - // Android should only use the preloaded origin list, while desktop should - // isolate all sites. -#if BUILDFLAG(IS_ANDROID) - EXPECT_FALSE( - content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites()); - EXPECT_TRUE( - content::SiteIsolationPolicy::ArePreloadedIsolatedOriginsEnabled()); -#else - EXPECT_TRUE(content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites()); - EXPECT_FALSE( - content::SiteIsolationPolicy::ArePreloadedIsolatedOriginsEnabled()); -#endif -} - -TEST_F(SiteIsolationPolicyTest, IsolatedOriginsContainPreloadedOrigins) { - if (ShouldSkipBecauseOfConflictingCommandLineSwitches()) - return; - - content::SiteIsolationPolicy::ApplyGlobalIsolatedOrigins(); - - std::vector<url::Origin> expected_embedder_origins = - site_isolation::GetBrowserSpecificBuiltInIsolatedOrigins(); - auto* cpsp = content::ChildProcessSecurityPolicy::GetInstance(); - std::vector<url::Origin> isolated_origins = cpsp->GetIsolatedOrigins(); - EXPECT_THAT(expected_embedder_origins, - UnorderedElementsAreArray(isolated_origins)); -} -} // namespace weblayer
diff --git a/weblayer/browser/ssl_browsertest.cc b/weblayer/browser/ssl_browsertest.cc deleted file mode 100644 index 31caa04..0000000 --- a/weblayer/browser/ssl_browsertest.cc +++ /dev/null
@@ -1,430 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/files/file_path.h" -#include "base/scoped_observation.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/network_time/network_time_tracker.h" -#include "components/security_interstitials/content/insecure_form_blocking_page.h" -#include "components/security_interstitials/content/ssl_error_assistant.h" -#include "components/security_interstitials/content/ssl_error_handler.h" -#include "net/ssl/ssl_info.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/weblayer_security_blocking_page_factory.h" -#include "weblayer/public/browser.h" -#include "weblayer/public/browser_observer.h" -#include "weblayer/public/error_page.h" -#include "weblayer/public/error_page_delegate.h" -#include "weblayer/public/new_tab_delegate.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/interstitial_utils.h" -#include "weblayer/test/load_completion_observer.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { -namespace { - -#if BUILDFLAG(IS_ANDROID) -// Waits for a new tab to be created, and then load |url|. -class NewTabWaiter : public NewTabDelegate { - public: - explicit NewTabWaiter(const GURL& url) : url_(url) {} - - void OnNewTab(Tab* new_tab, NewTabType type) override { - navigation_observer_ = std::make_unique<TestNavigationObserver>( - url_, TestNavigationObserver::NavigationEvent::kStart, new_tab); - run_loop_.Quit(); - } - - void Wait() { - if (!navigation_observer_) - run_loop_.Run(); - navigation_observer_->Wait(); - } - - private: - GURL url_; - std::unique_ptr<TestNavigationObserver> navigation_observer_; - base::RunLoop run_loop_; -}; -#endif - -class TestErrorPageDelegate : public ErrorPageDelegate { - public: - bool was_get_error_page_content_called() const { - return was_get_error_page_content_called_; - } - - // ErrorPageDelegate: - bool OnBackToSafety() override { return false; } - std::unique_ptr<ErrorPage> GetErrorPageContent( - Navigation* navigation) override { - was_get_error_page_content_called_ = true; - return std::make_unique<ErrorPage>(); - } - - private: - bool was_get_error_page_content_called_ = false; -}; - -} // namespace - -class SSLBrowserTest : public WebLayerBrowserTest { - public: - SSLBrowserTest() = default; - - SSLBrowserTest(const SSLBrowserTest&) = delete; - SSLBrowserTest& operator=(const SSLBrowserTest&) = delete; - - ~SSLBrowserTest() override = default; - - // WebLayerBrowserTest: - void SetUpOnMainThread() override { - https_server_ = std::make_unique<net::EmbeddedTestServer>( - net::EmbeddedTestServer::TYPE_HTTPS); - https_server_->AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - - https_server_mismatched_ = std::make_unique<net::EmbeddedTestServer>( - net::EmbeddedTestServer::TYPE_HTTPS); - https_server_mismatched_->SetSSLConfig( - net::EmbeddedTestServer::CERT_MISMATCHED_NAME); - https_server_mismatched_->AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - - https_server_expired_ = std::make_unique<net::EmbeddedTestServer>( - net::EmbeddedTestServer::TYPE_HTTPS); - https_server_expired_->SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); - https_server_expired_->AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); - - ASSERT_TRUE(https_server_->Start()); - ASSERT_TRUE(https_server_mismatched_->Start()); - ASSERT_TRUE(https_server_expired_->Start()); - } - - void PostRunTestOnMainThread() override { - https_server_.reset(); - https_server_mismatched_.reset(); - WebLayerBrowserTest::PostRunTestOnMainThread(); - } - - void NavigateToOkPage() { - ASSERT_EQ("127.0.0.1", ok_url().host()); - NavigateAndWaitForCompletion(ok_url(), shell()); - EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); - } - - void NavigateToPageWithMismatchedCertExpectSSLInterstitial() { - // Do a navigation that should result in an SSL error. - NavigateAndWaitForFailure(mismatched_cert_url(), shell()); - // First check that there *is* an interstitial. - ASSERT_TRUE(IsShowingSecurityInterstitial(shell()->tab())); - - // Now verify that the interstitial is in fact an SSL interstitial. - EXPECT_TRUE(IsShowingSSLInterstitial(shell()->tab())); - - // TODO(blundell): Check the security state once security state is available - // via the public WebLayer API, following the example of //chrome's - // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. - } - - void NavigateToPageWithMismatchedCertExpectCaptivePortalInterstitial() { - // Do a navigation that should result in an SSL error. - NavigateAndWaitForFailure(mismatched_cert_url(), shell()); - // First check that there *is* an interstitial. - ASSERT_TRUE(IsShowingSecurityInterstitial(shell()->tab())); - - // Now verify that the interstitial is in fact a captive portal - // interstitial. - EXPECT_TRUE(IsShowingCaptivePortalInterstitial(shell()->tab())); - - // TODO(blundell): Check the security state once security state is available - // via the public WebLayer API, following the example of //chrome's - // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. - } - - void NavigateToPageWithExpiredCertExpectSSLInterstitial() { - // Do a navigation that should result in an SSL error. - NavigateAndWaitForFailure(expired_cert_url(), shell()); - // First check that there *is* an interstitial. - ASSERT_TRUE(IsShowingSecurityInterstitial(shell()->tab())); - - // Now verify that the interstitial is in fact an SSL interstitial. - EXPECT_TRUE(IsShowingSSLInterstitial(shell()->tab())); - - // TODO(blundell): Check the security state once security state is available - // via the public WebLayer API, following the example of //chrome's - // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. - } - - void NavigateToPageWithExpiredCertExpectBadClockInterstitial() { - // Do a navigation that should result in an SSL error. - NavigateAndWaitForFailure(expired_cert_url(), shell()); - // First check that there *is* an interstitial. - ASSERT_TRUE(IsShowingSecurityInterstitial(shell()->tab())); - - // Now verify that the interstitial is in fact a bad clock interstitial. - EXPECT_TRUE(IsShowingBadClockInterstitial(shell()->tab())); - - // TODO(blundell): Check the security state once security state is available - // via the public WebLayer API, following the example of //chrome's - // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. - } - - void NavigateToPageWithMismatchedCertExpectNotBlocked() { - NavigateAndWaitForCompletion(mismatched_cert_url(), shell()); - EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); - - // TODO(blundell): Check the security state once security state is available - // via the public WebLayer API, following the example of //chrome's - // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. - } - - void SendInterstitialNavigationCommandAndWait( - bool proceed, - absl::optional<GURL> previous_url = absl::nullopt) { - GURL expected_url = - proceed ? mismatched_cert_url() : previous_url.value_or(ok_url()); - ASSERT_TRUE(IsShowingSSLInterstitial(shell()->tab())); - - TestNavigationObserver navigation_observer( - expected_url, TestNavigationObserver::NavigationEvent::kCompletion, - shell()); - ExecuteScript(shell(), - "window.certificateErrorPageController." + - std::string(proceed ? "proceed" : "dontProceed") + "();", - false /*use_separate_isolate*/); - navigation_observer.Wait(); - EXPECT_FALSE(IsShowingSSLInterstitial(shell()->tab())); - } - - void SendInterstitialReloadCommandAndWait() { - ASSERT_TRUE(IsShowingSSLInterstitial(shell()->tab())); - - LoadCompletionObserver load_observer(shell()); - ExecuteScript(shell(), "window.certificateErrorPageController.reload();", - false /*use_separate_isolate*/); - load_observer.Wait(); - - // Should still be showing the SSL interstitial after the reload command is - // processed. - EXPECT_TRUE(IsShowingSSLInterstitial(shell()->tab())); - } - -#if BUILDFLAG(IS_ANDROID) - void SendInterstitialOpenLoginCommandAndWait() { - ASSERT_TRUE(IsShowingCaptivePortalInterstitial(shell()->tab())); - - // Note: The embedded test server cannot actually load the captive portal - // login URL, so simply detect the start of the navigation to the page. - NewTabWaiter waiter(WebLayerSecurityBlockingPageFactory:: - GetCaptivePortalLoginPageUrlForTesting()); - shell()->tab()->SetNewTabDelegate(&waiter); - ExecuteScript(shell(), "window.certificateErrorPageController.openLogin();", - false /*use_separate_isolate*/); - waiter.Wait(); - } -#endif - - void NavigateToOtherOkPage() { - NavigateAndWaitForCompletion(https_server_->GetURL("/simple_page2.html"), - shell()); - EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); - } - - GURL ok_url() { return https_server_->GetURL("/simple_page.html"); } - GURL mismatched_cert_url() { - return https_server_mismatched_->GetURL("/simple_page.html"); - } - - GURL expired_cert_url() { - return https_server_expired_->GetURL("/simple_page.html"); - } - - protected: - std::unique_ptr<net::EmbeddedTestServer> https_server_; - std::unique_ptr<net::EmbeddedTestServer> https_server_mismatched_; - std::unique_ptr<net::EmbeddedTestServer> https_server_expired_; -}; - -// Tests clicking "take me back" on the interstitial page. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBack) { - NavigateToOkPage(); - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); - - // Click "Take me back". - SendInterstitialNavigationCommandAndWait(false /*proceed*/); - - // Check that it's possible to navigate to a new page. - NavigateToOtherOkPage(); - - // Navigate to the bad SSL page again, an interstitial shows again (in - // contrast to what would happen had the user chosen to proceed). - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); -} - -// Tests clicking "take me back" on the interstitial page when there's no -// navigation history. The user should be taken to a safe page (about:blank). -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBackEmptyNavigationHistory) { - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); - - // Click "Take me back". - SendInterstitialNavigationCommandAndWait(false /*proceed*/, - GURL("about:blank")); -} - -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, Reload) { - NavigateToOkPage(); - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); - - SendInterstitialReloadCommandAndWait(); - - // TODO(blundell): Ideally we would fix the SSL error, reload, and verify - // that the SSL interstitial isn't showing. However, currently this doesn't - // work: Calling ResetSSLConfig() on |http_server_mismatched_| passing - // CERT_OK does not cause future reloads or navigations to - // mismatched_cert_url() to succeed; they still fail and pop an interstitial. - // I verified that the LoadCompletionObserver is in fact waiting for a new - // load, i.e., there is actually a *new* SSL interstitial popped up. From - // looking at the ResetSSLConfig() impl there shouldn't be any waiting or - // anything needed within the client. -} - -// Tests clicking proceed link on the interstitial page. This is a PRE_ test -// because it also acts as setup for the test below which verifies the behavior -// across restarts. -// TODO(crbug.com/654704): Android does not support PRE_ tests. For Android just -// run only the PRE_ version of this test. -#if BUILDFLAG(IS_ANDROID) -#define PRE_Proceed Proceed -#endif -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, PRE_Proceed) { - NavigateToOkPage(); - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); - SendInterstitialNavigationCommandAndWait(true /*proceed*/); - - // Go back to an OK page, then try to navigate again. The "Proceed" decision - // should be saved, so no interstitial is shown this time. - NavigateToOkPage(); - NavigateToPageWithMismatchedCertExpectNotBlocked(); -} - -#if !BUILDFLAG(IS_ANDROID) -// The proceed decision is perpetuated across WebLayer sessions, i.e. WebLayer -// will not block again when navigating to the same bad page that was previously -// proceeded through. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, Proceed) { - NavigateToPageWithMismatchedCertExpectNotBlocked(); -} -#endif - -// Tests navigating away from the interstitial page. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, NavigateAway) { - NavigateToOkPage(); - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); - NavigateToOtherOkPage(); -} - -// Tests the scenario where the OS reports that an SSL error is due to a -// captive portal. A captive portal interstitial should be displayed. The test -// then switches OS captive portal status to false and reloads the page. This -// time, a normal SSL interstitial should be displayed. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, OSReportsCaptivePortal) { - SSLErrorHandler::SetOSReportsCaptivePortalForTesting(true); - - NavigateToPageWithMismatchedCertExpectCaptivePortalInterstitial(); - - // Check that clearing the test setting causes behavior to revert to normal. - SSLErrorHandler::SetOSReportsCaptivePortalForTesting(false); - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); -} - -#if BUILDFLAG(IS_ANDROID) -// Tests that after reaching a captive portal interstitial, clicking on the -// connect link will cause a navigation to the login page. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, CaptivePortalConnectToLoginPage) { - SSLErrorHandler::SetOSReportsCaptivePortalForTesting(true); - - NavigateToPageWithMismatchedCertExpectCaptivePortalInterstitial(); - - SendInterstitialOpenLoginCommandAndWait(); -} -#endif - -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, BadClockInterstitial) { - // Without the NetworkTimeTracker reporting that the clock is ahead or - // behind, navigating to a page with an expired cert should result in the - // default SSL interstitial appearing. - NavigateToPageWithExpiredCertExpectSSLInterstitial(); - - // Set network time back ten minutes. - BrowserProcess::GetInstance()->GetNetworkTimeTracker()->UpdateNetworkTime( - base::Time::Now() - base::Minutes(10), - base::Milliseconds(1), /* resolution */ - base::Milliseconds(500), /* latency */ - base::TimeTicks::Now() /* posting time of this update */); - - // Now navigating to a page with an expired cert should cause the bad clock - // interstitial to appear. - NavigateToPageWithExpiredCertExpectBadClockInterstitial(); -} - -// This test verifies that a certificate in the list of known captive portal -// certificates in ssl_error_assistant.asciipb is detected as such. This serves -// to verify that the ssl_error_assistant proto was correctly loaded. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, - CertificateInKnownCaptivePortalsListDetected) { - net::SSLInfo ssl_info_with_known_captive_portal_cert; - net::HashValue captive_portal_public_key; - - // Set up the SSSLInfo with the certificate of captive-portal.badssl.com - // (taken from ssl_error_assistant.asciipb). - ASSERT_TRUE(captive_portal_public_key.FromString( - "sha256/fjZPHewEHTrMDX3I1ecEIeoy3WFxHyGplOLv28kIbtI=")); - net::HashValueVector public_keys; - public_keys.push_back(captive_portal_public_key); - ssl_info_with_known_captive_portal_cert.public_key_hashes = public_keys; - - EXPECT_TRUE(SSLErrorAssistant().IsKnownCaptivePortalCertificate( - ssl_info_with_known_captive_portal_cert)); -} - -// Verifies an error page is not requested for an ssl error. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, ErrorPageNotCalledForMismatch) { - TestErrorPageDelegate error_page_delegate; - shell()->tab()->SetErrorPageDelegate(&error_page_delegate); - NavigateToOkPage(); - EXPECT_FALSE(error_page_delegate.was_get_error_page_content_called()); - NavigateToPageWithMismatchedCertExpectSSLInterstitial(); - EXPECT_FALSE(error_page_delegate.was_get_error_page_content_called()); -} - -// Visits a page that displays an insecure form, submits the form, and checks an -// interstitial is shown. -IN_PROC_BROWSER_TEST_F(SSLBrowserTest, - TestDisplaysInsecureFormSubmissionWarning) { - GURL insecure_form_url = https_server_->GetURL("/insecure_form.html"); - GURL form_target_url = GURL("http://does-not-exist.test/form_target.html?"); - NavigateAndWaitForCompletion(insecure_form_url, shell()); - - // Submit the form and wait for the interstitial to load. - TestNavigationObserver navigation_observer( - form_target_url, TestNavigationObserver::NavigationEvent::kFailure, - shell()); - ExecuteScript(shell(), "submitForm();", false /*use_separate_isolate*/); - navigation_observer.Wait(); - - // Check the correct interstitial loaded. - EXPECT_TRUE(IsShowingInsecureFormInterstitial(shell()->tab())); -} - -} // namespace weblayer
diff --git a/weblayer/browser/ssl_error_controller_client.cc b/weblayer/browser/ssl_error_controller_client.cc deleted file mode 100644 index db1cb6c..0000000 --- a/weblayer/browser/ssl_error_controller_client.cc +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/ssl_error_controller_client.h" - -#include "base/task/thread_pool.h" -#include "build/build_config.h" -#include "components/security_interstitials/content/settings_page_helper.h" -#include "components/security_interstitials/content/utils.h" -#include "components/security_interstitials/core/metrics_helper.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/ssl_host_state_delegate.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/error_page_delegate.h" - -namespace weblayer { - -SSLErrorControllerClient::SSLErrorControllerClient( - content::WebContents* web_contents, - int cert_error, - const net::SSLInfo& ssl_info, - const GURL& request_url, - std::unique_ptr<security_interstitials::MetricsHelper> metrics_helper, - std::unique_ptr<security_interstitials::SettingsPageHelper> - settings_page_helper) - : security_interstitials::SecurityInterstitialControllerClient( - web_contents, - std::move(metrics_helper), - nullptr /*prefs*/, - i18n::GetApplicationLocale(), - GURL("about:blank") /*default_safe_page*/, - std::move(settings_page_helper)), - cert_error_(cert_error), - ssl_info_(ssl_info), - request_url_(request_url) {} - -void SSLErrorControllerClient::GoBack() { - ErrorPageDelegate* delegate = - TabImpl::FromWebContents(web_contents_)->error_page_delegate(); - if (delegate && delegate->OnBackToSafety()) - return; - - SecurityInterstitialControllerClient::GoBackAfterNavigationCommitted(); -} - -void SSLErrorControllerClient::Proceed() { - // Notifies the browser process when a certificate exception is allowed. - web_contents_->SetAlwaysSendSubresourceNotifications(); - - web_contents_->GetBrowserContext()->GetSSLHostStateDelegate()->AllowCert( - request_url_.host(), *ssl_info_.cert.get(), cert_error_, - web_contents_->GetPrimaryMainFrame()->GetStoragePartition()); - Reload(); -} - -void SSLErrorControllerClient::OpenUrlInNewForegroundTab(const GURL& url) { - // For now WebLayer doesn't support multiple tabs, so just open the Learn - // More link in the current tab. - OpenUrlInCurrentTab(url); -} - -bool SSLErrorControllerClient::CanLaunchDateAndTimeSettings() { - return true; -} - -void SSLErrorControllerClient::LaunchDateAndTimeSettings() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - base::ThreadPool::PostTask( - FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, - base::BindOnce(&security_interstitials::LaunchDateAndTimeSettings)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/ssl_error_controller_client.h b/weblayer/browser/ssl_error_controller_client.h deleted file mode 100644 index 352a7cf..0000000 --- a/weblayer/browser/ssl_error_controller_client.h +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SSL_ERROR_CONTROLLER_CLIENT_H_ -#define WEBLAYER_BROWSER_SSL_ERROR_CONTROLLER_CLIENT_H_ - -#include "components/security_interstitials/content/security_interstitial_controller_client.h" -#include "net/ssl/ssl_info.h" -#include "url/gurl.h" - -namespace content { -class WebContents; -} - -namespace security_interstitials { -class MetricsHelper; -class SettingsPageHelper; -} // namespace security_interstitials - -namespace weblayer { - -// A stripped-down version of the class by the same name in -// //chrome/browser/ssl, which provides basic functionality for interacting with -// the SSL interstitial. -class SSLErrorControllerClient - : public security_interstitials::SecurityInterstitialControllerClient { - public: - SSLErrorControllerClient( - content::WebContents* web_contents, - int cert_error, - const net::SSLInfo& ssl_info, - const GURL& request_url, - std::unique_ptr<security_interstitials::MetricsHelper> metrics_helper, - std::unique_ptr<security_interstitials::SettingsPageHelper> - settings_page_helper); - - SSLErrorControllerClient(const SSLErrorControllerClient&) = delete; - SSLErrorControllerClient& operator=(const SSLErrorControllerClient&) = delete; - - ~SSLErrorControllerClient() override = default; - - // security_interstitials::SecurityInterstitialControllerClient: - void GoBack() override; - void Proceed() override; - void OpenUrlInNewForegroundTab(const GURL& url) override; - bool CanLaunchDateAndTimeSettings() override; - void LaunchDateAndTimeSettings() override; - - private: - const int cert_error_; - const net::SSLInfo ssl_info_; - const GURL request_url_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SSL_ERROR_CONTROLLER_CLIENT_H_
diff --git a/weblayer/browser/stateful_ssl_host_state_delegate_factory.cc b/weblayer/browser/stateful_ssl_host_state_delegate_factory.cc deleted file mode 100644 index 5f905a220..0000000 --- a/weblayer/browser/stateful_ssl_host_state_delegate_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h" - -#include <memory> - -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -StatefulSSLHostStateDelegate* -StatefulSSLHostStateDelegateFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<StatefulSSLHostStateDelegate*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -StatefulSSLHostStateDelegateFactory* -StatefulSSLHostStateDelegateFactory::GetInstance() { - return base::Singleton<StatefulSSLHostStateDelegateFactory>::get(); -} - -StatefulSSLHostStateDelegateFactory::StatefulSSLHostStateDelegateFactory() - : BrowserContextKeyedServiceFactory( - "StatefulSSLHostStateDelegate", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -StatefulSSLHostStateDelegateFactory::~StatefulSSLHostStateDelegateFactory() = - default; - -std::unique_ptr<KeyedService> -StatefulSSLHostStateDelegateFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<StatefulSSLHostStateDelegate>( - context, user_prefs::UserPrefs::Get(context), - HostContentSettingsMapFactory::GetForBrowserContext(context)); -} - -content::BrowserContext* -StatefulSSLHostStateDelegateFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/stateful_ssl_host_state_delegate_factory.h b/weblayer/browser/stateful_ssl_host_state_delegate_factory.h deleted file mode 100644 index 37b7bba..0000000 --- a/weblayer/browser/stateful_ssl_host_state_delegate_factory.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_STATEFUL_SSL_HOST_STATE_DELEGATE_FACTORY_H_ -#define WEBLAYER_BROWSER_STATEFUL_SSL_HOST_STATE_DELEGATE_FACTORY_H_ - -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" -#include "components/prefs/pref_service.h" - -class StatefulSSLHostStateDelegate; - -namespace weblayer { - -// Singleton that associates all StatefulSSLHostStateDelegates with -// BrowserContexts. -class StatefulSSLHostStateDelegateFactory - : public BrowserContextKeyedServiceFactory { - public: - static StatefulSSLHostStateDelegate* GetForBrowserContext( - content::BrowserContext* browser_context); - - static StatefulSSLHostStateDelegateFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits< - StatefulSSLHostStateDelegateFactory>; - - StatefulSSLHostStateDelegateFactory(); - ~StatefulSSLHostStateDelegateFactory() override; - StatefulSSLHostStateDelegateFactory( - const StatefulSSLHostStateDelegateFactory&) = delete; - StatefulSSLHostStateDelegateFactory& operator=( - const StatefulSSLHostStateDelegateFactory&) = delete; - - // BrowserContextKeyedServiceFactory methods: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_STATEFUL_SSL_HOST_STATE_DELEGATE_FACTORY_H_
diff --git a/weblayer/browser/subresource_filter_browsertest.cc b/weblayer/browser/subresource_filter_browsertest.cc deleted file mode 100644 index 7b87e9a..0000000 --- a/weblayer/browser/subresource_filter_browsertest.cc +++ /dev/null
@@ -1,766 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/json/json_reader.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/simple_test_clock.h" -#include "build/build_config.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/subresource_filter/content/browser/ads_intervention_manager.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" -#include "components/subresource_filter/content/browser/ruleset_service.h" -#include "components/subresource_filter/content/browser/subresource_filter_observer_test_utils.h" -#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h" -#include "components/subresource_filter/core/browser/subresource_filter_constants.h" -#include "components/subresource_filter/core/browser/subresource_filter_features.h" -#include "components/ukm/test_ukm_recorder.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_navigation_observer.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/resource/resource_bundle.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/subresource_filter_profile_context_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/grit/weblayer_resources.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/subresource_filter_browser_test_harness.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/infobars/android/infobar_android.h" // nogncheck -#include "components/infobars/content/content_infobar_manager.h" -#include "components/infobars/core/infobar_manager.h" // nogncheck -#endif - -namespace weblayer { - -namespace { - -const char kAdsInterventionRecordedHistogram[] = - "SubresourceFilter.PageLoad.AdsInterventionTriggered"; -const char kTimeSinceAdsInterventionTriggeredHistogram[] = - "SubresourceFilter.PageLoad." - "TimeSinceLastActiveAdsIntervention"; -const char kSubresourceFilterActionsHistogram[] = "SubresourceFilter.Actions2"; - -#if BUILDFLAG(IS_ANDROID) -class TestInfoBarManagerObserver : public infobars::InfoBarManager::Observer { - public: - TestInfoBarManagerObserver() = default; - ~TestInfoBarManagerObserver() override = default; - void OnInfoBarAdded(infobars::InfoBar* infobar) override { - if (on_infobar_added_callback_) - std::move(on_infobar_added_callback_).Run(); - } - - void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override { - if (on_infobar_removed_callback_) - std::move(on_infobar_removed_callback_).Run(); - } - - void set_on_infobar_added_callback(base::OnceClosure callback) { - on_infobar_added_callback_ = std::move(callback); - } - - void set_on_infobar_removed_callback(base::OnceClosure callback) { - on_infobar_removed_callback_ = std::move(callback); - } - - private: - base::OnceClosure on_infobar_added_callback_; - base::OnceClosure on_infobar_removed_callback_; -}; -#endif // if BUILDFLAG(IS_ANDROID) - -} // namespace - -// Tests that the ruleset service is available. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, RulesetService) { - EXPECT_NE(BrowserProcess::GetInstance()->subresource_filter_ruleset_service(), - nullptr); -} - -// Tests that the expected ruleset data was published as part of startup. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, RulesArePublished) { - auto* ruleset_service = - BrowserProcess::GetInstance()->subresource_filter_ruleset_service(); - - auto ruleset_version = ruleset_service->GetMostRecentlyIndexedVersion(); - EXPECT_TRUE(ruleset_version.IsValid()); - - std::string most_recently_indexed_content_version = - ruleset_version.content_version; - - std::string packaged_ruleset_manifest_string = - ui::ResourceBundle::GetSharedInstance().LoadDataResourceString( - IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON); - auto packaged_ruleset_manifest = - base::JSONReader::Read(packaged_ruleset_manifest_string); - std::string* packaged_content_version = - packaged_ruleset_manifest->GetDict().FindString("version"); - - EXPECT_EQ(most_recently_indexed_content_version, *packaged_content_version); -} - -// The below test is restricted to Android as it tests activation of the -// subresource filter in its default production configuration and WebLayer -// currently has a safe browsing database available in production only on -// Android; the safe browsing database being non-null is a prerequisite for -// subresource filter operation. -#if BUILDFLAG(IS_ANDROID) - -// Tests that page activation state is computed as part of a pageload. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - PageActivationStateComputed) { - // Set up prereqs. - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - content::WebContentsConsoleObserver console_observer(web_contents); - console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); - - GURL test_url(embedded_test_server()->GetURL("/simple_page.html")); - - subresource_filter::TestSubresourceFilterObserver observer(web_contents); - absl::optional<subresource_filter::mojom::ActivationLevel> page_activation = - observer.GetPageActivation(test_url); - EXPECT_FALSE(page_activation); - - // Verify that a navigation results in both (a) the page activation level - // being computed, and (b) the result of that computation being the default - // level of "dry run" due to AdTagging. - NavigateAndWaitForCompletion(test_url, shell()); - - page_activation = observer.GetPageActivation(test_url); - - EXPECT_TRUE(page_activation); - EXPECT_EQ(subresource_filter::mojom::ActivationLevel::kDryRun, - page_activation.value()); - - EXPECT_TRUE(console_observer.messages().empty()); -} - -#endif // (OS_ANDROID) - -// Verifies that subframes that are flagged by the subresource filter ruleset -// are blocked from loading on activated URLs. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - DisallowedSubframeURLBlockedOnActivatedURL) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - content::WebContentsConsoleObserver console_observer(web_contents); - console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); - - GURL test_url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - - subresource_filter::TestSubresourceFilterObserver observer(web_contents); - absl::optional<subresource_filter::mojom::ActivationLevel> page_activation = - observer.GetPageActivation(test_url); - EXPECT_FALSE(page_activation); - - ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); - - // Verify that the "ad" subframe is loaded if it is not flagged by the - // ruleset. - ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix( - "suffix-that-does-not-match-anything")); - - NavigateAndWaitForCompletion(test_url, shell()); - - // The subresource filter should have been activated on this navigation... - page_activation = observer.GetPageActivation(test_url); - EXPECT_TRUE(page_activation); - EXPECT_EQ(subresource_filter::mojom::ActivationLevel::kEnabled, - page_activation.value()); - - EXPECT_TRUE(console_observer.Wait()); - - // ... but it should not have blocked the subframe from being loaded. - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // Do a different-document navigation to ensure that that the next navigation - // to |test_url| executes as desired (e.g., to avoid any optimizations from - // being made due to it being a same-document navigation that would interfere - // with the logic of the test). Without this intervening navigation, we have - // seen flake on the Windows trybot that indicates that such optimizations are - // occurring. - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // Verify that the "ad" subframe is blocked if it is flagged by the - // ruleset. - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // Do a different-document navigation to ensure that that the next navigation - // to |test_url| executes as desired (e.g., to avoid any optimizations from - // being made due to it being a same-document navigation that would interfere - // with the logic of the test). Without this intervening navigation, we have - // seen flake on the Windows trybot that indicates that such optimizations are - // occurring. - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // The main frame document should never be filtered. - SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html"); - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); -} - -// Verifies that subframes are not blocked on non-activated URLs. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - DisallowedSubframeURLNotBlockedOnNonActivatedURL) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - GURL test_url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - - // Verify that the "ad" subframe is loaded if it is not flagged by the - // ruleset. - ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix( - "suffix-that-does-not-match-anything")); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // Verify that the "ad" subframe is loaded if even it is flagged by the - // ruleset as the URL is not activated. - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsAllowlist_DoNotActivate) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - GURL test_url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - content::WebContentsConsoleObserver console_observer(web_contents); - console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); - - // Simulate explicitly allowlisting via content settings. - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForBrowserContext( - web_contents->GetBrowserContext()); - settings_map->SetContentSettingDefaultScope( - test_url, test_url, ContentSettingsType::ADS, CONTENT_SETTING_ALLOW); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // No message for allowlisted url. - EXPECT_TRUE(console_observer.messages().empty()); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsAllowlistGlobal_DoNotActivate) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - GURL test_url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - content::WebContentsConsoleObserver console_observer(web_contents); - console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); - - // Simulate globally allowing ads via content settings. - HostContentSettingsMap* settings_map = - HostContentSettingsMapFactory::GetForBrowserContext( - web_contents->GetBrowserContext()); - settings_map->SetDefaultContentSetting(ContentSettingsType::ADS, - CONTENT_SETTING_ALLOW); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // No message for loads that are not activated. - EXPECT_TRUE(console_observer.messages().empty()); -} - -#if BUILDFLAG(IS_ANDROID) -// Test that the ads blocked infobar is presented when visiting a page where the -// subresource filter blocks resources from being loaded and is removed when -// navigating away. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, InfoBarPresentation) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - // Configure the subresource filter to activate on the test URL and to block - // its script from loading. - GURL test_url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - EXPECT_EQ(0u, infobar_manager->infobar_count()); - - // Navigate such that the script is blocked and verify that the ads blocked - // infobar is presented. - NavigateAndWaitForCompletion(test_url, shell()); - run_loop.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - auto* infobar = - static_cast<infobars::InfoBarAndroid*>(infobar_manager->infobar_at(0)); - EXPECT_TRUE(infobar->HasSetJavaInfoBar()); - EXPECT_EQ(infobar->delegate()->GetIdentifier(), - infobars::InfoBarDelegate::ADS_BLOCKED_INFOBAR_DELEGATE_ANDROID); - - // Navigate away and verify that the infobar is removed. - base::RunLoop run_loop2; - infobar_observer.set_on_infobar_removed_callback(run_loop2.QuitClosure()); - - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - run_loop2.Run(); - - EXPECT_EQ(0u, infobar_manager->infobar_count()); - infobar_manager->RemoveObserver(&infobar_observer); -} -#endif - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsAllowlistViaReload_DoNotActivate) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL test_url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // Allowlist via a reload. - content::TestNavigationObserver navigation_observer(web_contents, 1); - GetPrimaryPageThrottleManager()->OnReloadRequested(); - navigation_observer.Wait(); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - ContentSettingsAllowlistViaReload_AllowlistIsByDomain) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL test_url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); - - NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // Allowlist via a reload. - content::TestNavigationObserver navigation_observer(web_contents, 1); - GetPrimaryPageThrottleManager()->OnReloadRequested(); - navigation_observer.Wait(); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // Another navigation to the same domain should be allowed too. - NavigateAndWaitForCompletion( - embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html?query"), - shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - // A cross site blocklisted navigation should stay activated, however. - GURL a_url(embedded_test_server()->GetURL( - "a.com", "/subresource_filter/frame_with_included_script.html")); - ActivateSubresourceFilterInWebContentsForURL(web_contents, a_url); - NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); -} - -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - AdsInterventionEnforced_PageActivated) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto* ads_intervention_manager = - SubresourceFilterProfileContextFactory::GetForBrowserContext( - web_contents->GetBrowserContext()) - ->ads_intervention_manager(); - auto test_clock = std::make_unique<base::SimpleTestClock>(); - ads_intervention_manager->set_clock_for_testing(test_clock.get()); - - const GURL url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - - // Should not trigger activation as the URL is not on the blocklist and - // has no active ads interventions. - NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectTotalCount(kTimeSinceAdsInterventionTriggeredHistogram, - 0); - auto entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(0u, entries.size()); - - // Trigger an ads violation and renavigate the page. Should trigger - // subresource filter activation. - GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetPrimaryMainFrame(), - subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); - NavigateAndWaitForCompletion(url, shell()); - - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30), - 1); - histogram_tester.ExpectBucketCount( - kTimeSinceAdsInterventionTriggeredHistogram, 0, 1); - entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), - ukm::builders::AdsIntervention_LastIntervention::kInterventionTypeName, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30)); - ukm_recorder.ExpectEntryMetric( - entries.front(), - ukm::builders::AdsIntervention_LastIntervention::kInterventionStatusName, - static_cast<int>(AdsInterventionStatus::kBlocking)); - - // Advance the clock to clear the intervention. - test_clock->Advance(subresource_filter::kAdsInterventionDuration.Get()); - NavigateAndWaitForCompletion(url, shell()); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30), - 1); - histogram_tester.ExpectBucketCount( - kTimeSinceAdsInterventionTriggeredHistogram, - subresource_filter::kAdsInterventionDuration.Get().InHours(), 1); - entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(2u, entries.size()); - - // One of the entries is kBlocking, verify that the other is kExpired after - // the intervention is cleared. - EXPECT_TRUE( - (*ukm_recorder.GetEntryMetric( - entries.front(), ukm::builders::AdsIntervention_LastIntervention:: - kInterventionStatusName) == - static_cast<int>(AdsInterventionStatus::kExpired)) || - (*ukm_recorder.GetEntryMetric( - entries.back(), ukm::builders::AdsIntervention_LastIntervention:: - kInterventionStatusName) == - static_cast<int>(AdsInterventionStatus::kExpired))); -} - -IN_PROC_BROWSER_TEST_F( - SubresourceFilterBrowserTest, - MultipleAdsInterventions_PageActivationClearedAfterFirst) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto* ads_intervention_manager = - SubresourceFilterProfileContextFactory::GetForBrowserContext( - web_contents->GetBrowserContext()) - ->ads_intervention_manager(); - auto test_clock = std::make_unique<base::SimpleTestClock>(); - ads_intervention_manager->set_clock_for_testing(test_clock.get()); - - const GURL url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - - // Should not trigger activation as the URL is not on the blocklist and - // has no active ads interventions. - NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); - histogram_tester.ExpectTotalCount(kTimeSinceAdsInterventionTriggeredHistogram, - 0); - auto entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(0u, entries.size()); - - // Trigger an ads violation and renavigate the page. Should trigger - // subresource filter activation. - GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetPrimaryMainFrame(), - subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); - NavigateAndWaitForCompletion(url, shell()); - - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30), - 1); - histogram_tester.ExpectBucketCount( - kTimeSinceAdsInterventionTriggeredHistogram, 0, 1); - entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), - ukm::builders::AdsIntervention_LastIntervention::kInterventionTypeName, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30)); - ukm_recorder.ExpectEntryMetric( - entries.front(), - ukm::builders::AdsIntervention_LastIntervention::kInterventionStatusName, - static_cast<int>(AdsInterventionStatus::kBlocking)); - - // Advance the clock by less than kAdsInterventionDuration and trigger another - // intervention. This intervention is a no-op. - test_clock->Advance(subresource_filter::kAdsInterventionDuration.Get() - - base::Minutes(30)); - GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetPrimaryMainFrame(), - subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); - - // Advance the clock to to kAdsInterventionDuration from the first - // intervention, this clear the intervention. - test_clock->Advance(base::Minutes(30)); - NavigateAndWaitForCompletion(url, shell()); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30), - 1); - histogram_tester.ExpectBucketCount( - kTimeSinceAdsInterventionTriggeredHistogram, - subresource_filter::kAdsInterventionDuration.Get().InHours(), 1); - entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(2u, entries.size()); - - // One of the entries is kBlocking, verify that the other is kExpired after - // the intervention is cleared. - EXPECT_TRUE( - (*ukm_recorder.GetEntryMetric( - entries.front(), ukm::builders::AdsIntervention_LastIntervention:: - kInterventionStatusName) == - static_cast<int>(AdsInterventionStatus::kExpired)) || - (*ukm_recorder.GetEntryMetric( - entries.back(), ukm::builders::AdsIntervention_LastIntervention:: - kInterventionStatusName) == - static_cast<int>(AdsInterventionStatus::kExpired))); -} - -class SubresourceFilterBrowserTestWithoutAdsInterventionEnforcement - : public SubresourceFilterBrowserTest { - public: - SubresourceFilterBrowserTestWithoutAdsInterventionEnforcement() { - feature_list_.InitAndDisableFeature( - subresource_filter::kAdsInterventionsEnforced); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - -IN_PROC_BROWSER_TEST_F( - SubresourceFilterBrowserTestWithoutAdsInterventionEnforcement, - AdsInterventionNotEnforced_NoPageActivation) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto* ads_intervention_manager = - SubresourceFilterProfileContextFactory::GetForBrowserContext( - web_contents->GetBrowserContext()) - ->ads_intervention_manager(); - auto test_clock = std::make_unique<base::SimpleTestClock>(); - ads_intervention_manager->set_clock_for_testing(test_clock.get()); - - const GURL url(embedded_test_server()->GetURL( - "/subresource_filter/frame_with_included_script.html")); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - - // Should not trigger activation as the URL is not on the blocklist and - // has no active ads interventions. - NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - auto entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(0u, entries.size()); - - // Trigger an ads violation and renavigate to the page. Interventions are not - // enforced so no activation should occur. - GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetPrimaryMainFrame(), - subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); - - const base::TimeDelta kRenavigationDelay = base::Hours(2); - test_clock->Advance(kRenavigationDelay); - NavigateAndWaitForCompletion(url, shell()); - - EXPECT_TRUE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - histogram_tester.ExpectBucketCount( - kAdsInterventionRecordedHistogram, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30), - 1); - histogram_tester.ExpectBucketCount( - kTimeSinceAdsInterventionTriggeredHistogram, kRenavigationDelay.InHours(), - 1); - entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdsIntervention_LastIntervention::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), - ukm::builders::AdsIntervention_LastIntervention::kInterventionTypeName, - static_cast<int>(subresource_filter::mojom::AdsViolation:: - kMobileAdDensityByHeightAbove30)); - ukm_recorder.ExpectEntryMetric( - entries.front(), - ukm::builders::AdsIntervention_LastIntervention::kInterventionStatusName, - static_cast<int>(AdsInterventionStatus::kWouldBlock)); -} - -// Test the "smart" UI, aka the logic to hide the UI on subsequent same-domain -// navigations, until a certain time threshold has been reached. This is an -// android-only feature. -IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, - DoNotShowUIUntilThresholdReached) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* settings_manager = - SubresourceFilterProfileContextFactory::GetForBrowserContext( - web_contents->GetBrowserContext()) - ->settings_manager(); - settings_manager->set_should_use_smart_ui_for_testing(true); - ASSERT_NO_FATAL_FAILURE( - SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); - GURL a_url(embedded_test_server()->GetURL( - "a.com", "/subresource_filter/frame_with_included_script.html")); - GURL b_url(embedded_test_server()->GetURL( - "b.com", "/subresource_filter/frame_with_included_script.html")); - // Test utils only support one blocklisted site at a time. - // TODO(csharrison): Add support for more than one URL. - ActivateSubresourceFilterInWebContentsForURL(web_contents, a_url); - - auto test_clock = std::make_unique<base::SimpleTestClock>(); - base::SimpleTestClock* raw_clock = test_clock.get(); - settings_manager->set_clock_for_testing(std::move(test_clock)); - - base::HistogramTester histogram_tester; - - // First load should trigger the UI. - NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - histogram_tester.ExpectBucketCount( - kSubresourceFilterActionsHistogram, - subresource_filter::SubresourceFilterAction::kUIShown, 1); - histogram_tester.ExpectBucketCount( - kSubresourceFilterActionsHistogram, - subresource_filter::SubresourceFilterAction::kUISuppressed, 0); - - // Second load should not trigger the UI, but should still filter content. - NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - histogram_tester.ExpectBucketCount( - kSubresourceFilterActionsHistogram, - subresource_filter::SubresourceFilterAction::kUIShown, 1); - histogram_tester.ExpectBucketCount( - kSubresourceFilterActionsHistogram, - subresource_filter::SubresourceFilterAction::kUISuppressed, 1); - - ActivateSubresourceFilterInWebContentsForURL(web_contents, b_url); - - // Load to another domain should trigger the UI. - NavigateAndWaitForCompletion(b_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - histogram_tester.ExpectBucketCount( - kSubresourceFilterActionsHistogram, - subresource_filter::SubresourceFilterAction::kUIShown, 2); - - ActivateSubresourceFilterInWebContentsForURL(web_contents, a_url); - - // Fast forward the clock, and a_url should trigger the UI again. - raw_clock->Advance( - subresource_filter::SubresourceFilterContentSettingsManager:: - kDelayBeforeShowingInfobarAgain); - NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE( - WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); - - histogram_tester.ExpectBucketCount( - kSubresourceFilterActionsHistogram, - subresource_filter::SubresourceFilterAction::kUIShown, 3); - histogram_tester.ExpectBucketCount( - kSubresourceFilterActionsHistogram, - subresource_filter::SubresourceFilterAction::kUISuppressed, 1); -} - -} // namespace weblayer
diff --git a/weblayer/browser/subresource_filter_profile_context_factory.cc b/weblayer/browser/subresource_filter_profile_context_factory.cc deleted file mode 100644 index 01b06f8..0000000 --- a/weblayer/browser/subresource_filter_profile_context_factory.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/subresource_filter_profile_context_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/keyed_service/core/keyed_service.h" -#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -subresource_filter::SubresourceFilterProfileContext* -SubresourceFilterProfileContextFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<subresource_filter::SubresourceFilterProfileContext*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - true /* create */)); -} - -// static -SubresourceFilterProfileContextFactory* -SubresourceFilterProfileContextFactory::GetInstance() { - static base::NoDestructor<SubresourceFilterProfileContextFactory> factory; - return factory.get(); -} - -SubresourceFilterProfileContextFactory::SubresourceFilterProfileContextFactory() - : BrowserContextKeyedServiceFactory( - "SubresourceFilterProfileContext", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -std::unique_ptr<KeyedService> -SubresourceFilterProfileContextFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<subresource_filter::SubresourceFilterProfileContext>( - HostContentSettingsMapFactory::GetForBrowserContext(context)); -} - -content::BrowserContext* -SubresourceFilterProfileContextFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/subresource_filter_profile_context_factory.h b/weblayer/browser/subresource_filter_profile_context_factory.h deleted file mode 100644 index 80361c4..0000000 --- a/weblayer/browser/subresource_filter_profile_context_factory.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SUBRESOURCE_FILTER_PROFILE_CONTEXT_FACTORY_H_ -#define WEBLAYER_BROWSER_SUBRESOURCE_FILTER_PROFILE_CONTEXT_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace content { -class BrowserContext; -} - -namespace subresource_filter { -class SubresourceFilterProfileContext; -} - -namespace weblayer { - -// This class is responsible for instantiating a profile-scoped context for -// subresource filtering. -class SubresourceFilterProfileContextFactory - : public BrowserContextKeyedServiceFactory { - public: - static SubresourceFilterProfileContextFactory* GetInstance(); - static subresource_filter::SubresourceFilterProfileContext* - GetForBrowserContext(content::BrowserContext* browser_context); - - SubresourceFilterProfileContextFactory( - const SubresourceFilterProfileContextFactory&) = delete; - SubresourceFilterProfileContextFactory& operator=( - const SubresourceFilterProfileContextFactory&) = delete; - - private: - friend class base::NoDestructor<SubresourceFilterProfileContextFactory>; - - SubresourceFilterProfileContextFactory(); - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SUBRESOURCE_FILTER_PROFILE_CONTEXT_FACTORY_H_
diff --git a/weblayer/browser/system_network_context_manager.cc b/weblayer/browser/system_network_context_manager.cc deleted file mode 100644 index 223c30db..0000000 --- a/weblayer/browser/system_network_context_manager.cc +++ /dev/null
@@ -1,141 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/system_network_context_manager.h" - -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "components/net_log/net_export_file_writer.h" -#include "components/variations/net/variations_http_headers.h" -#include "content/public/browser/network_service_instance.h" -#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" - -namespace weblayer { - -namespace { - -// The global instance of the SystemNetworkContextmanager. -SystemNetworkContextManager* g_system_network_context_manager = nullptr; - -} // namespace - -// static -SystemNetworkContextManager* SystemNetworkContextManager::CreateInstance( - const std::string& user_agent) { - DCHECK(!g_system_network_context_manager); - g_system_network_context_manager = - new SystemNetworkContextManager(user_agent); - return g_system_network_context_manager; -} - -// static -bool SystemNetworkContextManager::HasInstance() { - return !!g_system_network_context_manager; -} - -// static -SystemNetworkContextManager* SystemNetworkContextManager::GetInstance() { - DCHECK(g_system_network_context_manager); - return g_system_network_context_manager; -} - -// static -void SystemNetworkContextManager::DeleteInstance() { - DCHECK(g_system_network_context_manager); - delete g_system_network_context_manager; - g_system_network_context_manager = nullptr; -} - -// static -network::mojom::NetworkContextParamsPtr -SystemNetworkContextManager::CreateDefaultNetworkContextParams( - const std::string& user_agent) { - network::mojom::NetworkContextParamsPtr network_context_params = - network::mojom::NetworkContextParams::New(); - network_context_params->cert_verifier_params = content::GetCertVerifierParams( - cert_verifier::mojom::CertVerifierCreationParams::New()); - ConfigureDefaultNetworkContextParams(network_context_params.get(), - user_agent); - variations::UpdateCorsExemptHeaderForVariations(network_context_params.get()); - return network_context_params; -} - -// static -void SystemNetworkContextManager::ConfigureDefaultNetworkContextParams( - network::mojom::NetworkContextParams* network_context_params, - const std::string& user_agent) { - network_context_params->user_agent = user_agent; -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_WIN) - // We're not configuring the cookie encryption on these platforms yet. - network_context_params->enable_encrypted_cookies = false; -#endif // (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) || - // BUILDFLAG(IS_WIN) -} - -SystemNetworkContextManager::SystemNetworkContextManager( - const std::string& user_agent) - : user_agent_(user_agent) {} - -SystemNetworkContextManager::~SystemNetworkContextManager() = default; - -network::mojom::NetworkContext* -SystemNetworkContextManager::GetSystemNetworkContext() { - if (!system_network_context_ || !system_network_context_.is_connected()) { - // This should call into OnNetworkServiceCreated(), which will re-create - // the network service, if needed. There's a chance that it won't be - // invoked, if the NetworkContext has encountered an error but the - // NetworkService has not yet noticed its pipe was closed. In that case, - // trying to create a new NetworkContext would fail, anyways, and hopefully - // a new NetworkContext will be created on the next GetContext() call. - content::GetNetworkService(); - DCHECK(system_network_context_); - } - - return system_network_context_.get(); -} - -void SystemNetworkContextManager::OnNetworkServiceCreated( - network::mojom::NetworkService* network_service) { - system_network_context_.reset(); - network_service->CreateNetworkContext( - system_network_context_.BindNewPipeAndPassReceiver(), - CreateSystemNetworkContextManagerParams()); -} - -network::mojom::NetworkContextParamsPtr -SystemNetworkContextManager::CreateSystemNetworkContextManagerParams() { - network::mojom::NetworkContextParamsPtr network_context_params = - CreateDefaultNetworkContextParams(user_agent_); - return network_context_params; -} - -scoped_refptr<network::SharedURLLoaderFactory> -SystemNetworkContextManager::GetSharedURLLoaderFactory() { - if (!url_loader_factory_) { - auto url_loader_factory_params = - network::mojom::URLLoaderFactoryParams::New(); - url_loader_factory_params->process_id = network::mojom::kBrowserProcessId; - url_loader_factory_params->is_corb_enabled = false; - GetSystemNetworkContext()->CreateURLLoaderFactory( - url_loader_factory_.BindNewPipeAndPassReceiver(), - std::move(url_loader_factory_params)); - shared_url_loader_factory_ = - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - url_loader_factory_.get()); - } - return shared_url_loader_factory_; -} - -net_log::NetExportFileWriter* -SystemNetworkContextManager::GetNetExportFileWriter() { - if (!net_export_file_writer_) { - net_export_file_writer_ = std::make_unique<net_log::NetExportFileWriter>(); - } - return net_export_file_writer_.get(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/system_network_context_manager.h b/weblayer/browser/system_network_context_manager.h deleted file mode 100644 index d5384b2adb..0000000 --- a/weblayer/browser/system_network_context_manager.h +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_SYSTEM_NETWORK_CONTEXT_MANAGER_H_ -#define WEBLAYER_BROWSER_SYSTEM_NETWORK_CONTEXT_MANAGER_H_ - -#include "base/memory/scoped_refptr.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/public/mojom/network_context.mojom.h" -#include "services/network/public/mojom/network_service.mojom.h" - -namespace network { -class SharedURLLoaderFactory; -} // namespace network - -namespace net_log { -class NetExportFileWriter; -} - -namespace weblayer { - -// Manages a system-wide network context that's not tied to a profile. -class SystemNetworkContextManager { - public: - // Creates the global instance of SystemNetworkContextManager. - static SystemNetworkContextManager* CreateInstance( - const std::string& user_agent); - - // Checks if the global SystemNetworkContextManager has been created. - static bool HasInstance(); - - // Gets the global SystemNetworkContextManager instance or DCHECKs if there - // isn't one.. - static SystemNetworkContextManager* GetInstance(); - - // Destroys the global SystemNetworkContextManager instance. - static void DeleteInstance(); - - static network::mojom::NetworkContextParamsPtr - CreateDefaultNetworkContextParams(const std::string& user_agent); - - static void ConfigureDefaultNetworkContextParams( - network::mojom::NetworkContextParams* network_context_params, - const std::string& user_agent); - - SystemNetworkContextManager(const SystemNetworkContextManager&) = delete; - SystemNetworkContextManager& operator=(const SystemNetworkContextManager&) = - delete; - - ~SystemNetworkContextManager(); - - // Returns the System NetworkContext. Does any initialization of the - // NetworkService that may be needed when first called. - network::mojom::NetworkContext* GetSystemNetworkContext(); - - // Called when content creates a NetworkService. Creates the - // system NetworkContext, if the network service is enabled. - void OnNetworkServiceCreated(network::mojom::NetworkService* network_service); - - // Returns a SharedURLLoaderFactory owned by the SystemNetworkContextManager - // that is backed by the SystemNetworkContext. - // NOTE: This factory assumes that the network service is running in the - // browser process, which is a valid assumption for Android. If WebLayer is - // productionized beyond Android, it will need to be extended to handle - // network service crashes. - scoped_refptr<network::SharedURLLoaderFactory> GetSharedURLLoaderFactory(); - - // Returns a shared global NetExportFileWriter instance, used by net-export. - // It lives here so it can outlive chrome://net-export/ if the tab is closed - // or destroyed, and so that it's destroyed before Mojo is shut down. - net_log::NetExportFileWriter* GetNetExportFileWriter(); - - private: - explicit SystemNetworkContextManager(const std::string& user_agent); - - network::mojom::NetworkContextParamsPtr - CreateSystemNetworkContextManagerParams(); - - std::string user_agent_; - - mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_; - scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> - shared_url_loader_factory_; - - mojo::Remote<network::mojom::NetworkContext> system_network_context_; - - // Initialized on first access. - std::unique_ptr<net_log::NetExportFileWriter> net_export_file_writer_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_SYSTEM_NETWORK_CONTEXT_MANAGER_H_
diff --git a/weblayer/browser/tab_callback_proxy.cc b/weblayer/browser/tab_callback_proxy.cc deleted file mode 100644 index b8f20d7..0000000 --- a/weblayer/browser/tab_callback_proxy.cc +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/tab_callback_proxy.h" - -#include "base/android/jni_string.h" -#include "base/trace_event/trace_event.h" -#include "url/gurl.h" -#include "weblayer/browser/java/jni/TabCallbackProxy_jni.h" -#include "weblayer/browser/tab_impl.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertUTF8ToJavaString; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -TabCallbackProxy::TabCallbackProxy(JNIEnv* env, jobject obj, Tab* tab) - : tab_(tab), java_observer_(env, obj) { - tab_->AddObserver(this); -} - -TabCallbackProxy::~TabCallbackProxy() { - tab_->RemoveObserver(this); -} - -void TabCallbackProxy::DisplayedUrlChanged(const GURL& url) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> jstring_uri_string( - ConvertUTF8ToJavaString(env, url.spec())); - TRACE_EVENT0("weblayer", "Java_TabCallbackProxy_visibleUriChanged"); - Java_TabCallbackProxy_visibleUriChanged(env, java_observer_, - jstring_uri_string); -} - -void TabCallbackProxy::OnRenderProcessGone() { - TRACE_EVENT0("weblayer", "Java_TabCallbackProxy_onRenderProcessGone"); - Java_TabCallbackProxy_onRenderProcessGone(AttachCurrentThread(), - java_observer_); -} - -void TabCallbackProxy::OnTitleUpdated(const std::u16string& title) { - JNIEnv* env = AttachCurrentThread(); - Java_TabCallbackProxy_onTitleUpdated( - env, java_observer_, base::android::ConvertUTF16ToJavaString(env, title)); -} - -static jlong JNI_TabCallbackProxy_CreateTabCallbackProxy( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& proxy, - jlong tab) { - return reinterpret_cast<jlong>( - new TabCallbackProxy(env, proxy, reinterpret_cast<TabImpl*>(tab))); -} - -static void JNI_TabCallbackProxy_DeleteTabCallbackProxy(JNIEnv* env, - jlong proxy) { - delete reinterpret_cast<TabCallbackProxy*>(proxy); -} - -} // namespace weblayer
diff --git a/weblayer/browser/tab_callback_proxy.h b/weblayer/browser/tab_callback_proxy.h deleted file mode 100644 index 4aaa7f1..0000000 --- a/weblayer/browser/tab_callback_proxy.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TAB_CALLBACK_PROXY_H_ -#define WEBLAYER_BROWSER_TAB_CALLBACK_PROXY_H_ - -#include <jni.h> - -#include "base/android/scoped_java_ref.h" -#include "base/memory/raw_ptr.h" -#include "weblayer/public/tab_observer.h" - -namespace weblayer { - -class Tab; - -// TabCallbackProxy forwards all TabObserver functions to the Java side. There -// is one TabCallbackProxy per Tab. -class TabCallbackProxy : public TabObserver { - public: - TabCallbackProxy(JNIEnv* env, jobject obj, Tab* tab); - - TabCallbackProxy(const TabCallbackProxy&) = delete; - TabCallbackProxy& operator=(const TabCallbackProxy&) = delete; - - ~TabCallbackProxy() override; - - // TabObserver: - void DisplayedUrlChanged(const GURL& url) override; - void OnRenderProcessGone() override; - void OnTitleUpdated(const std::u16string& title) override; - - private: - raw_ptr<Tab> tab_; - base::android::ScopedJavaGlobalRef<jobject> java_observer_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TAB_CALLBACK_PROXY_H_
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc deleted file mode 100644 index a054855..0000000 --- a/weblayer/browser/tab_impl.cc +++ /dev/null
@@ -1,1208 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/tab_impl.h" - -#include <cmath> - -#include "base/auto_reset.h" -#include "base/feature_list.h" -#include "base/functional/bind.h" -#include "base/functional/callback_helpers.h" -#include "base/logging.h" -#include "base/memory/raw_ptr.h" -#include "base/no_destructor.h" -#include "base/task/thread_pool.h" -#include "base/time/default_tick_clock.h" -#include "base/uuid.h" -#include "build/build_config.h" -#include "cc/layers/layer.h" -#include "components/autofill/content/browser/content_autofill_driver_factory.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/blocked_content/popup_blocker.h" -#include "components/blocked_content/popup_blocker_tab_helper.h" -#include "components/blocked_content/popup_opener_tab_helper.h" -#include "components/blocked_content/popup_tracker.h" -#include "components/captive_portal/core/buildflags.h" -#include "components/content_settings/browser/page_specific_content_settings.h" -#include "components/embedder_support/user_agent_utils.h" -#include "components/find_in_page/find_tab_helper.h" -#include "components/find_in_page/find_types.h" -#include "components/infobars/content/content_infobar_manager.h" -#include "components/permissions/permission_manager.h" -#include "components/permissions/permission_request_manager.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/core/browser/db/database_manager.h" -#include "components/sessions/content/session_tab_helper.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_web_contents_helper.h" -#include "components/subresource_filter/content/browser/ruleset_service.h" -#include "components/translate/core/browser/translate_manager.h" -#include "components/ukm/content/source_url_recorder.h" -#include "components/webapps/browser/installable/installable_manager.h" -#include "components/webapps/browser/installable/ml_installability_promoter.h" -#include "components/webrtc/media_stream_devices_controller.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/context_menu_params.h" -#include "content/public/browser/file_select_listener.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/permission_controller.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/renderer_preferences_util.h" -#include "content/public/browser/web_contents.h" -#include "third_party/blink/public/common/permissions/permission_utils.h" -#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" -#include "third_party/blink/public/common/web_preferences/web_preferences.h" -#include "third_party/blink/public/mojom/context_menu/context_menu.mojom.h" -#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" -#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h" -#include "third_party/blink/public/mojom/window_features/window_features.mojom.h" -#include "ui/base/window_open_disposition.h" -#include "weblayer/browser/autofill_client_impl.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/content_browser_client_impl.h" -#include "weblayer/browser/favicon/favicon_fetcher_impl.h" -#include "weblayer/browser/favicon/favicon_tab_helper.h" -#include "weblayer/browser/file_select_helper.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/browser/navigation_controller_impl.h" -#include "weblayer/browser/navigation_entry_data.h" -#include "weblayer/browser/no_state_prefetch/prerender_tab_helper.h" -#include "weblayer/browser/page_load_metrics_initialize.h" -#include "weblayer/browser/page_specific_content_settings_delegate.h" -#include "weblayer/browser/password_manager_driver_factory.h" -#include "weblayer/browser/persistence/browser_persister.h" -#include "weblayer/browser/popup_navigation_delegate_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#include "weblayer/browser/subresource_filter_profile_context_factory.h" -#include "weblayer/browser/translate_client_impl.h" -#include "weblayer/browser/weblayer_features.h" -#include "weblayer/common/isolated_world_ids.h" -#include "weblayer/public/fullscreen_delegate.h" -#include "weblayer/public/new_tab_delegate.h" -#include "weblayer/public/tab_observer.h" - -#if !BUILDFLAG(IS_ANDROID) -#include "ui/views/controls/webview/webview.h" -#endif - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/callback_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/json/json_writer.h" -#include "base/trace_event/trace_event.h" -#include "components/android_autofill/browser/android_autofill_manager.h" -#include "components/android_autofill/browser/autofill_provider.h" -#include "components/android_autofill/browser/autofill_provider_android.h" -#include "components/browser_ui/sms/android/sms_infobar.h" -#include "components/download/content/public/context_menu_download.h" -#include "components/embedder_support/android/contextmenu/context_menu_builder.h" -#include "components/embedder_support/android/delegate/color_chooser_android.h" -#include "components/javascript_dialogs/tab_modal_dialog_manager.h" // nogncheck -#include "components/safe_browsing/android/remote_database_manager.h" -#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h" -#include "components/safe_browsing/content/browser/safe_browsing_tab_observer.h" -#include "components/site_engagement/content/site_engagement_helper.h" -#include "components/site_engagement/content/site_engagement_service.h" -#include "components/translate/core/browser/translate_manager.h" -#include "ui/android/view_android.h" -#include "ui/gfx/android/java_bitmap.h" -#include "weblayer/browser/java/jni/TabImpl_jni.h" -#include "weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h" -#include "weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" -#include "weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.h" -#include "weblayer/browser/translate_client_impl.h" -#include "weblayer/browser/webapps/weblayer_app_banner_manager_android.h" -#include "weblayer/browser/weblayer_factory_impl_android.h" -#include "weblayer/browser/webrtc/media_stream_manager.h" -#include "weblayer/common/features.h" -#endif - -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) -#include "components/captive_portal/content/captive_portal_tab_helper.h" -#include "weblayer/browser/captive_portal_service_factory.h" -#endif - -#if BUILDFLAG(IS_ANDROID) -using base::android::AttachCurrentThread; -using base::android::JavaParamRef; -using base::android::ScopedJavaGlobalRef; -using base::android::ScopedJavaLocalRef; -#endif - -namespace weblayer { - -namespace { - -// Maximum size of data when calling SetData(). -constexpr int kMaxDataSize = 4096; - -#if BUILDFLAG(IS_ANDROID) -bool g_system_autofill_disabled_for_testing = false; - -#endif - -NewTabType NewTabTypeFromWindowDisposition(WindowOpenDisposition disposition) { - // WindowOpenDisposition has a *ton* of types, but the following are really - // the only ones that should be hit for this code path. - switch (disposition) { - case WindowOpenDisposition::NEW_FOREGROUND_TAB: - return NewTabType::kForeground; - case WindowOpenDisposition::NEW_BACKGROUND_TAB: - return NewTabType::kBackground; - case WindowOpenDisposition::NEW_POPUP: - return NewTabType::kNewPopup; - case WindowOpenDisposition::NEW_WINDOW: - return NewTabType::kNewWindow; - default: - // The set of allowed types are in - // ContentTabClientImpl::CanCreateWindow(). - NOTREACHED(); - return NewTabType::kForeground; - } -} - -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) -// Opens a captive portal login page in |web_contents|. -void OpenCaptivePortalLoginTabInWebContents( - content::WebContents* web_contents) { - content::OpenURLParams params( - CaptivePortalServiceFactory::GetForBrowserContext( - web_contents->GetBrowserContext()) - ->test_url(), - content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_LINK, false); - web_contents->OpenURL(params); -} -#endif - -// Pointer value of this is used as a key in base::SupportsUserData for -// WebContents. Value of the key is an instance of |UserData|. -constexpr int kWebContentsUserDataKey = 0; - -struct UserData : public base::SupportsUserData::Data { - raw_ptr<TabImpl> tab = nullptr; -}; - -#if BUILDFLAG(IS_ANDROID) -void HandleJavaScriptResult(const ScopedJavaGlobalRef<jobject>& callback, - base::Value result) { - std::string json; - base::JSONWriter::Write(result, &json); - base::android::RunStringCallbackAndroid(callback, json); -} - -void OnConvertedToJavaBitmap(const ScopedJavaGlobalRef<jobject>& value_callback, - const ScopedJavaGlobalRef<jobject>& java_bitmap) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - TabImpl::ScreenShotErrors error = - java_bitmap ? TabImpl::ScreenShotErrors::kNone - : TabImpl::ScreenShotErrors::kBitmapAllocationFailed; - Java_TabImpl_runCaptureScreenShotCallback(AttachCurrentThread(), - value_callback, java_bitmap, - static_cast<int>(error)); -} - -// Convert SkBitmap to java Bitmap on a background thread since it involves a -// memcpy. -void ConvertToJavaBitmapBackgroundThread( - const SkBitmap& bitmap, - base::OnceCallback<void(const ScopedJavaGlobalRef<jobject>&)> callback) { - // Make sure to only pass ScopedJavaGlobalRef between threads. - ScopedJavaGlobalRef<jobject> java_bitmap = ScopedJavaGlobalRef<jobject>( - gfx::ConvertToJavaBitmap(bitmap, gfx::OomBehavior::kReturnNullOnOom)); - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), std::move(java_bitmap))); -} - -void OnScreenShotCaptured(const ScopedJavaGlobalRef<jobject>& value_callback, - const SkBitmap& bitmap) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (bitmap.isNull() || bitmap.drawsNothing()) { - Java_TabImpl_runCaptureScreenShotCallback( - AttachCurrentThread(), value_callback, nullptr, - static_cast<int>(TabImpl::ScreenShotErrors::kCaptureFailed)); - return; - } - // Not using PostTaskAndReplyWithResult to ensure ScopedJavaLocalRef is not - // passed between threads. - base::ThreadPool::PostTask( - FROM_HERE, - {base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&ConvertToJavaBitmapBackgroundThread, bitmap, - base::BindOnce(&OnConvertedToJavaBitmap, value_callback))); -} - -#endif // BUILDFLAG(IS_ANDROID) - -std::set<TabImpl*>& GetTabs() { - static base::NoDestructor<std::set<TabImpl*>> s_all_tab_impl; - return *s_all_tab_impl; -} - -// Returns a scoped refptr to the SafeBrowsingService's database manager, if -// available. Otherwise returns nullptr. -const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> -GetDatabaseManagerFromSafeBrowsingService() { -#if BUILDFLAG(IS_ANDROID) - SafeBrowsingService* safe_browsing_service = - BrowserProcess::GetInstance()->GetSafeBrowsingService(); - return scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>( - safe_browsing_service->GetSafeBrowsingDBManager()); -#else - return nullptr; -#endif -} - -// Creates a ContentSubresourceFilterWebContentsHelper for |web_contents|, -// passing it the needed embedder-level state. -void CreateContentSubresourceFilterWebContentsHelper( - content::WebContents* web_contents) { - subresource_filter::RulesetService* ruleset_service = - BrowserProcess::GetInstance()->subresource_filter_ruleset_service(); - subresource_filter::VerifiedRulesetDealer::Handle* dealer = - ruleset_service ? ruleset_service->GetRulesetDealer() : nullptr; - subresource_filter::ContentSubresourceFilterWebContentsHelper:: - CreateForWebContents( - web_contents, - SubresourceFilterProfileContextFactory::GetForBrowserContext( - web_contents->GetBrowserContext()), - GetDatabaseManagerFromSafeBrowsingService(), dealer); -} - -} // namespace - -#if BUILDFLAG(IS_ANDROID) - -static ScopedJavaLocalRef<jobject> JNI_TabImpl_FromWebContents( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& j_web_contents) { - content::WebContents* web_contents = - content::WebContents::FromJavaWebContents(j_web_contents); - TabImpl* tab = TabImpl::FromWebContents(web_contents); - if (tab) - return ScopedJavaLocalRef<jobject>(tab->GetJavaTab()); - return nullptr; -} - -static void JNI_TabImpl_DestroyContextMenuParams( - JNIEnv* env, - jlong native_context_menu_params) { - // Note: this runs on the finalizer thread which isn't the UI thread. - auto* context_menu_params = - reinterpret_cast<content::ContextMenuParams*>(native_context_menu_params); - delete context_menu_params; -} - -TabImpl::TabImpl(ProfileImpl* profile, - const JavaParamRef<jobject>& java_impl, - std::unique_ptr<content::WebContents> web_contents) - : TabImpl(profile, std::move(web_contents)) { - java_impl_ = java_impl; -} -#endif - -TabImpl::TabImpl(ProfileImpl* profile, - std::unique_ptr<content::WebContents> web_contents, - const std::string& guid) - : profile_(profile), - web_contents_(std::move(web_contents)), - guid_(guid.empty() ? base::Uuid::GenerateRandomV4().AsLowercaseString() - : guid) { - GetTabs().insert(this); - DCHECK(web_contents_); - // This code path is hit when the page requests a new tab, which should - // only be possible from the same profile. - DCHECK_EQ(profile_->GetBrowserContext(), web_contents_->GetBrowserContext()); - - // FaviconTabHelper adds a WebContentsObserver. Create FaviconTabHelper - // before |this| observes the WebContents to ensure favicons are reset before - // notifying weblayer observers of changes. - FaviconTabHelper::CreateForWebContents(web_contents_.get()); - - UpdateRendererPrefs(false); - locale_change_subscription_ = - i18n::RegisterLocaleChangeCallback(base::BindRepeating( - &TabImpl::UpdateRendererPrefs, base::Unretained(this), true)); - - std::unique_ptr<UserData> user_data = std::make_unique<UserData>(); - user_data->tab = this; - web_contents_->SetUserData(&kWebContentsUserDataKey, std::move(user_data)); - - web_contents_->SetDelegate(this); - Observe(web_contents_.get()); - - navigation_controller_ = std::make_unique<NavigationControllerImpl>(this); - - find_in_page::FindTabHelper::CreateForWebContents(web_contents_.get()); - GetFindTabHelper()->AddObserver(this); - - TranslateClientImpl::CreateForWebContents(web_contents_.get()); - -#if BUILDFLAG(IS_ANDROID) - // infobars::ContentInfoBarManager must be created before - // SubresourceFilterClientImpl as the latter depends on it. - infobars::ContentInfoBarManager::CreateForWebContents(web_contents_.get()); -#endif - - CreateContentSubresourceFilterWebContentsHelper(web_contents_.get()); - - sessions::SessionTabHelper::CreateForWebContents( - web_contents_.get(), - base::BindRepeating(&TabImpl::GetSessionServiceTabHelperDelegate)); - - permissions::PermissionRequestManager::CreateForWebContents( - web_contents_.get()); - content_settings::PageSpecificContentSettings::CreateForWebContents( - web_contents_.get(), - std::make_unique<PageSpecificContentSettingsDelegate>( - web_contents_.get())); - blocked_content::PopupBlockerTabHelper::CreateForWebContents( - web_contents_.get()); - blocked_content::PopupOpenerTabHelper::CreateForWebContents( - web_contents_.get(), base::DefaultTickClock::GetInstance(), - HostContentSettingsMapFactory::GetForBrowserContext( - web_contents_->GetBrowserContext())); - PasswordManagerDriverFactory::CreateForWebContents(web_contents_.get()); - - InitializePageLoadMetricsForWebContents(web_contents_.get()); - ukm::InitializeSourceUrlRecorderForWebContents(web_contents_.get()); - -#if BUILDFLAG(IS_ANDROID) - javascript_dialogs::TabModalDialogManager::CreateForWebContents( - web_contents_.get(), - std::make_unique<JavaScriptTabModalDialogManagerDelegateAndroid>( - web_contents_.get())); - - if (base::FeatureList::IsEnabled( - features::kWebLayerClientSidePhishingDetection)) { - safe_browsing::SafeBrowsingTabObserver::CreateForWebContents( - web_contents_.get(), - std::make_unique<WebLayerSafeBrowsingTabObserverDelegate>()); - } - - if (site_engagement::SiteEngagementService::IsEnabled()) { - site_engagement::SiteEngagementService::Helper::CreateForWebContents( - web_contents_.get()); - } - - auto* browser_context = - static_cast<BrowserContextImpl*>(web_contents_->GetBrowserContext()); - safe_browsing::SafeBrowsingNavigationObserver::MaybeCreateForWebContents( - web_contents_.get(), - HostContentSettingsMapFactory::GetForBrowserContext(browser_context), - SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( - browser_context), - browser_context->pref_service(), - BrowserProcess::GetInstance()->GetSafeBrowsingService()); -#endif - -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) - captive_portal::CaptivePortalTabHelper::CreateForWebContents( - web_contents_.get(), - CaptivePortalServiceFactory::GetForBrowserContext( - web_contents_->GetBrowserContext()), - base::BindRepeating(&OpenCaptivePortalLoginTabInWebContents, - web_contents_.get())); -#endif - - // PrerenderTabHelper adds a WebContentsObserver. - PrerenderTabHelper::CreateForWebContents(web_contents_.get()); - - webapps::InstallableManager::CreateForWebContents(web_contents_.get()); - -#if BUILDFLAG(IS_ANDROID) - // Must be created after InstallableManager and MLInstallabilityPromoter. - WebLayerAppBannerManagerAndroid::CreateForWebContents(web_contents_.get()); -#endif -} - -TabImpl::~TabImpl() { - DCHECK(!browser_); - - GetFindTabHelper()->RemoveObserver(this); - - Observe(nullptr); - web_contents_->SetDelegate(nullptr); - if (navigation_controller_->should_delay_web_contents_deletion()) { - // Some user-data on WebContents directly or indirectly references this. - // Remove that linkage to avoid use-after-free. - web_contents_->RemoveUserData(&kWebContentsUserDataKey); - // Have Profile handle the task posting to ensure the WebContents is - // deleted before Profile. To do otherwise means it would be possible for - // the Profile to outlive the WebContents, which is problematic (crash). - profile_->DeleteWebContentsSoon(std::move(web_contents_)); - } - web_contents_.reset(); - GetTabs().erase(this); -} - -// static -TabImpl* TabImpl::FromWebContents(content::WebContents* web_contents) { - if (!web_contents) - return nullptr; - - UserData* user_data = reinterpret_cast<UserData*>( - web_contents->GetUserData(&kWebContentsUserDataKey)); - return user_data ? user_data->tab.get() : nullptr; -} - -// static -std::set<TabImpl*> TabImpl::GetAllTabImpl() { - return GetTabs(); -} - -void TabImpl::AddDataObserver(DataObserver* observer) { - data_observers_.AddObserver(observer); -} - -void TabImpl::RemoveDataObserver(DataObserver* observer) { - data_observers_.RemoveObserver(observer); -} - -Browser* TabImpl::GetBrowser() { - return browser_; -} - -void TabImpl::SetErrorPageDelegate(ErrorPageDelegate* delegate) { - error_page_delegate_ = delegate; -} - -void TabImpl::SetFullscreenDelegate(FullscreenDelegate* delegate) { - if (delegate == fullscreen_delegate_) - return; - - const bool had_delegate = (fullscreen_delegate_ != nullptr); - const bool has_delegate = (delegate != nullptr); - - // If currently fullscreen, and the delegate is being set to null, force an - // exit now (otherwise the delegate can't take us out of fullscreen). - if (is_fullscreen_ && fullscreen_delegate_ && had_delegate != has_delegate) - OnExitFullscreen(); - - fullscreen_delegate_ = delegate; - // Whether fullscreen is enabled depends upon whether there is a delegate. If - // having a delegate changed, then update the renderer (which is where - // fullscreen enabled is tracked). - if (had_delegate != has_delegate) - web_contents_->OnWebPreferencesChanged(); -} - -void TabImpl::SetNewTabDelegate(NewTabDelegate* delegate) { - new_tab_delegate_ = delegate; -} - -void TabImpl::SetGoogleAccountsDelegate(GoogleAccountsDelegate* delegate) { - google_accounts_delegate_ = delegate; -} - -void TabImpl::AddObserver(TabObserver* observer) { - observers_.AddObserver(observer); -} - -void TabImpl::RemoveObserver(TabObserver* observer) { - observers_.RemoveObserver(observer); -} - -NavigationController* TabImpl::GetNavigationController() { - return navigation_controller_.get(); -} - -void TabImpl::ExecuteScript(const std::u16string& script, - bool use_separate_isolate, - JavaScriptResultCallback callback) { - if (use_separate_isolate) { - web_contents_->GetPrimaryMainFrame()->ExecuteJavaScriptInIsolatedWorld( - script, std::move(callback), ISOLATED_WORLD_ID_WEBLAYER); - } else { - content::RenderFrameHost::AllowInjectingJavaScript(); - web_contents_->GetPrimaryMainFrame()->ExecuteJavaScript( - script, std::move(callback)); - } -} - -const std::string& TabImpl::GetGuid() { - return guid_; -} - -void TabImpl::SetData(const std::map<std::string, std::string>& data) { - bool result = SetDataInternal(data); - DCHECK(result) << "Data given to SetData() was too large."; -} - -const std::map<std::string, std::string>& TabImpl::GetData() { - return data_; -} - -void TabImpl::ExecuteScriptWithUserGestureForTests( - const std::u16string& script) { - web_contents_->GetPrimaryMainFrame() - ->ExecuteJavaScriptWithUserGestureForTests(script, base::NullCallback()); -} - -std::unique_ptr<FaviconFetcher> TabImpl::CreateFaviconFetcher( - FaviconFetcherDelegate* delegate) { - return std::make_unique<FaviconFetcherImpl>(web_contents_.get(), delegate); -} - -void TabImpl::SetTranslateTargetLanguage( - const std::string& translate_target_lang) { - translate::TranslateManager* translate_manager = - TranslateClientImpl::FromWebContents(web_contents()) - ->GetTranslateManager(); - translate_manager->SetPredefinedTargetLanguage( - translate_target_lang, - /*should_auto_translate=*/true); -} - -#if !BUILDFLAG(IS_ANDROID) -void TabImpl::AttachToView(views::WebView* web_view) { - web_view->SetWebContents(web_contents_.get()); - web_contents_->Focus(); -} -#endif - -void TabImpl::WebPreferencesChanged() { - web_contents_->OnWebPreferencesChanged(); -} - -void TabImpl::SetWebPreferences(blink::web_pref::WebPreferences* prefs) { - prefs->fullscreen_supported = !!fullscreen_delegate_; - - if (!browser_) - return; - browser_->SetWebPreferences(prefs); -} - -void TabImpl::OnGainedActive() { - web_contents()->GetController().LoadIfNecessary(); - if (enter_fullscreen_on_gained_active_) - EnterFullscreenImpl(); -} - -void TabImpl::OnLosingActive() { - if (is_fullscreen_) - web_contents_->ExitFullscreen(/* will_cause_resize */ false); -} - -bool TabImpl::IsActive() { - return browser_->GetActiveTab() == this; -} - -void TabImpl::ShowContextMenu(const content::ContextMenuParams& params) { -#if BUILDFLAG(IS_ANDROID) - Java_TabImpl_showContextMenu( - base::android::AttachCurrentThread(), java_impl_, - context_menu::BuildJavaContextMenuParams(params), - reinterpret_cast<jlong>(new content::ContextMenuParams(params))); -#endif -} - -#if BUILDFLAG(IS_ANDROID) -// static -void TabImpl::DisableAutofillSystemIntegrationForTesting() { - g_system_autofill_disabled_for_testing = true; -} - -static jlong JNI_TabImpl_CreateTab(JNIEnv* env, - jlong profile, - const JavaParamRef<jobject>& java_impl) { - ProfileImpl* profile_impl = reinterpret_cast<ProfileImpl*>(profile); - content::WebContents::CreateParams create_params( - profile_impl->GetBrowserContext()); - create_params.initially_hidden = true; - return reinterpret_cast<intptr_t>(new TabImpl( - profile_impl, java_impl, content::WebContents::Create(create_params))); -} - -static void JNI_TabImpl_DeleteTab(JNIEnv* env, jlong tab) { - TabImpl* tab_impl = reinterpret_cast<TabImpl*>(tab); - DCHECK(tab_impl); - // RemoveTabBeforeDestroyingFromJava() should have been called before this, - // which sets browser to null. - DCHECK(!tab_impl->browser()); - delete tab_impl; -} - -ScopedJavaLocalRef<jobject> TabImpl::GetWebContents(JNIEnv* env) { - return web_contents_->GetJavaWebContents(); -} - -void TabImpl::SetJavaImpl(JNIEnv* env, const JavaParamRef<jobject>& impl) { - // This should only be called early on and only once. - DCHECK(!java_impl_); - java_impl_ = impl; -} - -void TabImpl::ExecuteScript(JNIEnv* env, - const JavaParamRef<jstring>& script, - bool use_separate_isolate, - const JavaParamRef<jobject>& callback) { - ScopedJavaGlobalRef<jobject> jcallback(env, callback); - ExecuteScript(base::android::ConvertJavaStringToUTF16(script), - use_separate_isolate, - base::BindOnce(&HandleJavaScriptResult, jcallback)); -} - -void TabImpl::InitializeAutofillIfNecessary(JNIEnv* env) { - if (g_system_autofill_disabled_for_testing) - return; - if (!autofill::ContentAutofillDriverFactory::FromWebContents( - web_contents_.get())) { - InitializeAutofillDriver(); - } -} - -ScopedJavaLocalRef<jstring> TabImpl::GetGuid(JNIEnv* env) { - return base::android::ConvertUTF8ToJavaString(AttachCurrentThread(), - GetGuid()); -} - -TabImpl::ScreenShotErrors TabImpl::PrepareForCaptureScreenShot( - float scale, - content::RenderWidgetHostView** rwhv, - gfx::Rect* src_rect, - gfx::Size* output_size) { - if (scale <= 0.f || scale > 1.f) - return ScreenShotErrors::kScaleOutOfRange; - - if (!IsActive()) - return ScreenShotErrors::kTabNotActive; - - if (web_contents_->GetVisibility() != content::Visibility::VISIBLE) - return ScreenShotErrors::kWebContentsNotVisible; - - if (!browser_ || !browser_->CompositorHasSurface()) - return ScreenShotErrors::kNoSurface; - - *rwhv = web_contents_->GetTopLevelRenderWidgetHostView(); - if (!*rwhv) - return ScreenShotErrors::kNoRenderWidgetHostView; - - if (!(*rwhv)->GetNativeView()->GetWindowAndroid()) - return ScreenShotErrors::kNoWindowAndroid; - - *src_rect = - gfx::Rect(web_contents_->GetNativeView()->GetPhysicalBackingSize()); - if (src_rect->IsEmpty()) - return ScreenShotErrors::kEmptyViewport; - - *output_size = gfx::ScaleToCeiledSize(src_rect->size(), scale, scale); - if (output_size->IsEmpty()) - return ScreenShotErrors::kScaledToEmpty; - return ScreenShotErrors::kNone; -} - -void TabImpl::CaptureScreenShot( - JNIEnv* env, - jfloat scale, - const base::android::JavaParamRef<jobject>& value_callback) { - content::RenderWidgetHostView* rwhv = nullptr; - gfx::Rect src_rect; - gfx::Size output_size; - ScreenShotErrors error = - PrepareForCaptureScreenShot(scale, &rwhv, &src_rect, &output_size); - if (error != ScreenShotErrors::kNone) { - Java_TabImpl_runCaptureScreenShotCallback( - env, ScopedJavaLocalRef<jobject>(value_callback), - ScopedJavaLocalRef<jobject>(), static_cast<int>(error)); - return; - } - - rwhv->CopyFromSurface( - src_rect, output_size, - base::BindOnce(&OnScreenShotCaptured, - ScopedJavaGlobalRef<jobject>(value_callback))); -} - -jboolean TabImpl::SetData( - JNIEnv* env, - const base::android::JavaParamRef<jobjectArray>& data) { - std::vector<std::string> flattened_map; - base::android::AppendJavaStringArrayToStringVector(env, data, &flattened_map); - std::map<std::string, std::string> data_map; - for (size_t i = 0; i < flattened_map.size(); i += 2) { - data_map.insert({flattened_map[i], flattened_map[i + 1]}); - } - return SetDataInternal(data_map); -} - -base::android::ScopedJavaLocalRef<jobjectArray> TabImpl::GetData(JNIEnv* env) { - std::vector<std::string> flattened_map; - for (const auto& kv : data_) { - flattened_map.push_back(kv.first); - flattened_map.push_back(kv.second); - } - return base::android::ToJavaArrayOfStrings(env, flattened_map); -} - -jboolean TabImpl::CanTranslate(JNIEnv* env) { - return TranslateClientImpl::FromWebContents(web_contents()) - ->GetTranslateManager() - ->CanManuallyTranslate(); -} - -void TabImpl::ShowTranslateUi(JNIEnv* env) { - TranslateClientImpl::FromWebContents(web_contents()) - ->ShowTranslateUiWhenReady(); -} - -void TabImpl::RemoveTabFromBrowserBeforeDestroying(JNIEnv* env) { - DCHECK(browser_); - browser_->RemoveTabBeforeDestroyingFromJava(this); -} - -void TabImpl::SetTranslateTargetLanguage( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& translate_target_lang) { - SetTranslateTargetLanguage( - base::android::ConvertJavaStringToUTF8(env, translate_target_lang)); -} - -void TabImpl::SetDesktopUserAgentEnabled(JNIEnv* env, jboolean enable) { - if (desktop_user_agent_enabled_ == enable) - return; - - desktop_user_agent_enabled_ = enable; - - // Reset state that an earlier call to Navigation::SetUserAgentString() - // could have modified. - embedder_support::SetDesktopUserAgentOverride( - web_contents_.get(), embedder_support::GetUserAgentMetadata(), - /* override_in_new_tabs= */ false); - web_contents_->SetRendererInitiatedUserAgentOverrideOption( - content::NavigationController::UA_OVERRIDE_INHERIT); - - content::NavigationEntry* entry = - web_contents_->GetController().GetLastCommittedEntry(); - if (!entry) - return; - - entry->SetIsOverridingUserAgent(enable); - web_contents_->NotifyPreferencesChanged(); - web_contents_->GetController().LoadOriginalRequestURL(); -} - -jboolean TabImpl::IsDesktopUserAgentEnabled(JNIEnv* env) { - auto* entry = web_contents_->GetController().GetLastCommittedEntry(); - if (!entry) - return false; - - // The same user agent override mechanism is used for per-navigation user - // agent and desktop mode. Make sure not to return desktop mode for - // navigation entries which used a per-navigation user agent. - auto* entry_data = NavigationEntryData::Get(entry); - if (entry_data && entry_data->per_navigation_user_agent_override()) - return false; - - return entry->GetIsOverridingUserAgent(); -} - -void TabImpl::Download(JNIEnv* env, jlong native_context_menu_params) { - auto* context_menu_params = - reinterpret_cast<content::ContextMenuParams*>(native_context_menu_params); - - bool is_link = context_menu_params->media_type != - blink::mojom::ContextMenuDataMediaType::kImage && - context_menu_params->media_type != - blink::mojom::ContextMenuDataMediaType::kVideo; - - download::CreateContextMenuDownload(web_contents_.get(), *context_menu_params, - std::string(), is_link); -} -#endif // BUILDFLAG(IS_ANDROID) - -content::WebContents* TabImpl::OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) { - if (blocked_content::ConsiderForPopupBlocking(params.disposition)) { - bool blocked = blocked_content::MaybeBlockPopup( - source, nullptr, - std::make_unique<PopupNavigationDelegateImpl>( - params, source, nullptr), - ¶ms, blink::mojom::WindowFeatures(), - HostContentSettingsMapFactory::GetForBrowserContext( - source->GetBrowserContext())) == nullptr; - if (blocked) - return nullptr; - } - - if (params.disposition == WindowOpenDisposition::CURRENT_TAB) { - source->GetController().LoadURLWithParams( - content::NavigationController::LoadURLParams(params)); - return source; - } - - // All URLs not opening in the current tab will get a new tab. - std::unique_ptr<content::WebContents> new_tab_contents = - content::WebContents::Create(content::WebContents::CreateParams( - web_contents()->GetBrowserContext())); - base::WeakPtr<content::WebContents> new_tab_contents_weak_ptr( - new_tab_contents->GetWeakPtr()); - bool was_blocked = false; - AddNewContents(web_contents(), std::move(new_tab_contents), params.url, - params.disposition, {}, params.user_gesture, &was_blocked); - if (was_blocked || !new_tab_contents_weak_ptr) - return nullptr; - new_tab_contents_weak_ptr->GetController().LoadURLWithParams( - content::NavigationController::LoadURLParams(params)); - return new_tab_contents_weak_ptr.get(); -} - -void TabImpl::ShowRepostFormWarningDialog(content::WebContents* source) { -#if BUILDFLAG(IS_ANDROID) - Java_TabImpl_showRepostFormWarningDialog(base::android::AttachCurrentThread(), - java_impl_); -#else - source->GetController().CancelPendingReload(); -#endif -} - -void TabImpl::NavigationStateChanged(content::WebContents* source, - content::InvalidateTypes changed_flags) { - DCHECK_EQ(web_contents_.get(), source); - if (changed_flags & content::INVALIDATE_TYPE_URL) { - for (auto& observer : observers_) - observer.DisplayedUrlChanged(source->GetVisibleURL()); - UpdateBrowserVisibleSecurityStateIfNecessary(); - } - - // TODO(crbug.com/1064582): INVALIDATE_TYPE_TITLE is called only when a title - // is set on the active navigation entry, but not when the active entry - // changes, so check INVALIDATE_TYPE_LOAD here as well. However this should - // be fixed and INVALIDATE_TYPE_LOAD should be removed. - if (changed_flags & - (content::INVALIDATE_TYPE_TITLE | content::INVALIDATE_TYPE_LOAD)) { - std::u16string title = web_contents_->GetTitle(); - if (title_ != title) { - title_ = title; - for (auto& observer : observers_) - observer.OnTitleUpdated(title); - } - } -} - -content::JavaScriptDialogManager* TabImpl::GetJavaScriptDialogManager( - content::WebContents* web_contents) { -#if BUILDFLAG(IS_ANDROID) - return javascript_dialogs::TabModalDialogManager::FromWebContents( - web_contents); -#else - return nullptr; -#endif -} - -#if BUILDFLAG(IS_ANDROID) -std::unique_ptr<content::ColorChooser> TabImpl::OpenColorChooser( - content::WebContents* web_contents, - SkColor color, - const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) { - return std::make_unique<web_contents_delegate_android::ColorChooserAndroid>( - web_contents, color, suggestions); -} -#endif - -void TabImpl::CreateSmsPrompt(content::RenderFrameHost* render_frame_host, - const std::vector<url::Origin>& origin_list, - const std::string& one_time_code, - base::OnceClosure on_confirm, - base::OnceClosure on_cancel) { -#if BUILDFLAG(IS_ANDROID) - auto* web_contents = - content::WebContents::FromRenderFrameHost(render_frame_host); - sms::SmsInfoBar::Create( - web_contents, - infobars::ContentInfoBarManager::FromWebContents(web_contents), - origin_list, one_time_code, std::move(on_confirm), std::move(on_cancel)); -#else - NOTREACHED(); -#endif -} - -void TabImpl::RunFileChooser( - content::RenderFrameHost* render_frame_host, - scoped_refptr<content::FileSelectListener> listener, - const blink::mojom::FileChooserParams& params) { - FileSelectHelper::RunFileChooser(render_frame_host, std::move(listener), - params); -} - -bool TabImpl::IsBackForwardCacheSupported() { - return true; -} - -void TabImpl::RequestMediaAccessPermission( - content::WebContents* web_contents, - const content::MediaStreamRequest& request, - content::MediaResponseCallback callback) { -#if BUILDFLAG(IS_ANDROID) - MediaStreamManager::FromWebContents(web_contents) - ->RequestMediaAccessPermission(request, std::move(callback)); -#else - std::move(callback).Run(blink::mojom::StreamDevicesSet(), - blink::mojom::MediaStreamRequestResult::NOT_SUPPORTED, - nullptr); -#endif -} - -bool TabImpl::CheckMediaAccessPermission( - content::RenderFrameHost* render_frame_host, - const GURL& security_origin, - blink::mojom::MediaStreamType type) { - DCHECK(type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE || - type == blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE); - blink::PermissionType permission_type = - type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE - ? blink::PermissionType::AUDIO_CAPTURE - : blink::PermissionType::VIDEO_CAPTURE; - - // TODO(crbug.com/1321100): Remove `security_origin`. - if (render_frame_host->GetLastCommittedOrigin().GetURL() != security_origin) { - return false; - } - // It is OK to ignore `security_origin` because it will be calculated from - // `render_frame_host` and we always ignore `requesting_origin` for - // `AUDIO_CAPTURE` and `VIDEO_CAPTURE`. - // `render_frame_host->GetMainFrame()->GetLastCommittedOrigin()` will be used - // instead. - return render_frame_host->GetBrowserContext() - ->GetPermissionController() - ->GetPermissionStatusForCurrentDocument(permission_type, - render_frame_host) == - blink::mojom::PermissionStatus::GRANTED; -} - -void TabImpl::EnterFullscreenModeForTab( - content::RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options) { - // TODO(crbug.com/1232147): support |options|. - if (is_fullscreen_) { - // Typically EnterFullscreenModeForTab() should not be called consecutively, - // but there may be corner cases with oopif that lead to multiple - // consecutive calls. Avoid notifying the delegate in this case. - return; - } - is_fullscreen_ = true; - if (!IsActive()) { - // Process the request the tab is made active. - enter_fullscreen_on_gained_active_ = true; - return; - } - EnterFullscreenImpl(); -} - -void TabImpl::ExitFullscreenModeForTab(content::WebContents* web_contents) { - weak_ptr_factory_for_fullscreen_exit_.InvalidateWeakPtrs(); - is_fullscreen_ = false; - if (enter_fullscreen_on_gained_active_) - enter_fullscreen_on_gained_active_ = false; - else - fullscreen_delegate_->ExitFullscreen(); -} - -bool TabImpl::IsFullscreenForTabOrPending( - const content::WebContents* web_contents) { - return is_fullscreen_; -} - -blink::mojom::DisplayMode TabImpl::GetDisplayMode( - const content::WebContents* web_contents) { - return is_fullscreen_ ? blink::mojom::DisplayMode::kFullscreen - : blink::mojom::DisplayMode::kBrowser; -} - -void TabImpl::AddNewContents( - content::WebContents* source, - std::unique_ptr<content::WebContents> new_contents, - const GURL& target_url, - WindowOpenDisposition disposition, - const blink::mojom::WindowFeatures& window_features, - bool user_gesture, - bool* was_blocked) { - if (!new_tab_delegate_) { - *was_blocked = true; - return; - } - - // At this point the |new_contents| is beyond the popup blocker, but we use - // the same logic for determining if the popup tracker needs to be attached. - if (source && blocked_content::ConsiderForPopupBlocking(disposition)) { - blocked_content::PopupTracker::CreateForWebContents(new_contents.get(), - source, disposition); - } - - new_tab_delegate_->OnNewTab(browser_->CreateTab(std::move(new_contents)), - NewTabTypeFromWindowDisposition(disposition)); -} - -void TabImpl::CloseContents(content::WebContents* source) { - // The only time that |browser_| is null is during shutdown, and this callback - // shouldn't come in at that time. - DCHECK(browser_); - -#if BUILDFLAG(IS_ANDROID) - JNIEnv* env = AttachCurrentThread(); - Java_TabImpl_handleCloseFromWebContents(env, java_impl_); - // The above call resulted in the destruction of this; nothing to do but - // return. -#else - browser_->DestroyTab(this); -#endif -} - -void TabImpl::FindReply(content::WebContents* web_contents, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - GetFindTabHelper()->HandleFindReply(request_id, number_of_matches, - selection_rect, active_match_ordinal, - final_update); -} - -#if BUILDFLAG(IS_ANDROID) -// FindMatchRectsReply and OnFindResultAvailable forward find-related results to -// the Java TabImpl. The find actions themselves are initiated directly from -// Java via FindInPageBridge. -void TabImpl::FindMatchRectsReply(content::WebContents* web_contents, - int version, - const std::vector<gfx::RectF>& rects, - const gfx::RectF& active_rect) { - JNIEnv* env = AttachCurrentThread(); - // Create the details object. - ScopedJavaLocalRef<jobject> details_object = - Java_TabImpl_createFindMatchRectsDetails( - env, version, rects.size(), - ScopedJavaLocalRef<jobject>(Java_TabImpl_createRectF( - env, active_rect.x(), active_rect.y(), active_rect.right(), - active_rect.bottom()))); - - // Add the rects. - for (size_t i = 0; i < rects.size(); ++i) { - const gfx::RectF& rect = rects[i]; - Java_TabImpl_setMatchRectByIndex( - env, details_object, i, - ScopedJavaLocalRef<jobject>(Java_TabImpl_createRectF( - env, rect.x(), rect.y(), rect.right(), rect.bottom()))); - } - - Java_TabImpl_onFindMatchRectsAvailable(env, java_impl_, details_object); -} -#endif - -void TabImpl::PrimaryMainFrameRenderProcessGone( - base::TerminationStatus status) { -#if BUILDFLAG(IS_ANDROID) - // If a renderer process is lost when the tab is not visible, indicate to the - // WebContents that it should automatically reload the next time it becomes - // visible. - JNIEnv* env = AttachCurrentThread(); - if (Java_TabImpl_willAutomaticallyReloadAfterCrashImpl(env, java_impl_)) - web_contents()->GetController().SetNeedsReload(); -#endif - - for (auto& observer : observers_) - observer.OnRenderProcessGone(); -} - -void TabImpl::OnFindResultAvailable(content::WebContents* web_contents) { -#if BUILDFLAG(IS_ANDROID) - const find_in_page::FindNotificationDetails& find_result = - GetFindTabHelper()->find_result(); - JNIEnv* env = AttachCurrentThread(); - Java_TabImpl_onFindResultAvailable( - env, java_impl_, find_result.number_of_matches(), - find_result.active_match_ordinal(), find_result.final_update()); -#endif -} - -void TabImpl::DidChangeVisibleSecurityState() { - UpdateBrowserVisibleSecurityStateIfNecessary(); -} - -void TabImpl::UpdateBrowserVisibleSecurityStateIfNecessary() { - if (browser_ && browser_->GetActiveTab() == this) - browser_->VisibleSecurityStateOfActiveTabChanged(); -} - -void TabImpl::OnExitFullscreen() { - // If |processing_enter_fullscreen_| is true, it means the callback is being - // called while processing EnterFullscreenModeForTab(). WebContents doesn't - // deal well with this. FATAL as Android generally doesn't run with DCHECKs. - LOG_IF(FATAL, processing_enter_fullscreen_) - << "exiting fullscreen while entering fullscreen is not supported"; - web_contents_->ExitFullscreen(/* will_cause_resize */ false); -} - -void TabImpl::UpdateRendererPrefs(bool should_sync_prefs) { - blink::RendererPreferences* prefs = web_contents_->GetMutableRendererPrefs(); - content::UpdateFontRendererPreferencesFromSystemSettings(prefs); - prefs->accept_languages = i18n::GetAcceptLangs(); - if (should_sync_prefs) - web_contents_->SyncRendererPrefs(); -} - -#if BUILDFLAG(IS_ANDROID) - -void TabImpl::InitializeAutofillForTests() { - InitializeAutofillDriver(); -} - -void TabImpl::InitializeAutofillDriver() { - content::WebContents* web_contents = web_contents_.get(); - DCHECK( - !autofill::ContentAutofillDriverFactory::FromWebContents(web_contents)); - DCHECK(autofill::AutofillProvider::FromWebContents(web_contents)); - - AutofillClientImpl::CreateForWebContents(web_contents); -} - -#endif // BUILDFLAG(IS_ANDROID) - -find_in_page::FindTabHelper* TabImpl::GetFindTabHelper() { - return find_in_page::FindTabHelper::FromWebContents(web_contents_.get()); -} - -// static -sessions::SessionTabHelperDelegate* TabImpl::GetSessionServiceTabHelperDelegate( - content::WebContents* web_contents) { - TabImpl* tab = FromWebContents(web_contents); - return (tab && tab->browser_) ? tab->browser_->browser_persister() : nullptr; -} - -bool TabImpl::SetDataInternal(const std::map<std::string, std::string>& data) { - int total_size = 0; - for (const auto& kv : data) - total_size += kv.first.size() + kv.second.size(); - if (total_size > kMaxDataSize) - return false; - data_ = data; - for (auto& observer : data_observers_) - observer.OnDataChanged(this, data_); - return true; -} - -void TabImpl::EnterFullscreenImpl() { - // This ensures the existing callback is ignored. - weak_ptr_factory_for_fullscreen_exit_.InvalidateWeakPtrs(); - - auto exit_fullscreen_closure = - base::BindOnce(&TabImpl::OnExitFullscreen, - weak_ptr_factory_for_fullscreen_exit_.GetWeakPtr()); - base::AutoReset<bool> reset(&processing_enter_fullscreen_, true); - fullscreen_delegate_->EnterFullscreen(std::move(exit_fullscreen_closure)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/tab_impl.h b/weblayer/browser/tab_impl.h deleted file mode 100644 index 48dd139..0000000 --- a/weblayer/browser/tab_impl.h +++ /dev/null
@@ -1,367 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TAB_IMPL_H_ -#define WEBLAYER_BROWSER_TAB_IMPL_H_ - -#include <memory> -#include <set> -#include <string> - -#include "base/functional/callback_forward.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "base/scoped_observation_traits.h" -#include "build/build_config.h" -#include "components/find_in_page/find_result_observer.h" -#include "content/public/browser/color_chooser.h" -#include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_contents_observer.h" -#include "weblayer/browser/i18n_util.h" -#include "weblayer/public/tab.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/scoped_java_ref.h" -#endif - -namespace blink { -namespace web_pref { -struct WebPreferences; -} -} // namespace blink - -namespace content { -class RenderWidgetHostView; -class WebContents; -struct ContextMenuParams; -} // namespace content - -namespace gfx { -class Rect; -class Size; -} // namespace gfx - -namespace sessions { -class SessionTabHelperDelegate; -} - -namespace weblayer { -class BrowserImpl; -class FullscreenDelegate; -class NavigationControllerImpl; -class NewTabDelegate; -class ProfileImpl; - -class TabImpl : public Tab, - public content::WebContentsDelegate, - public content::WebContentsObserver, - public find_in_page::FindResultObserver { - public: - enum class ScreenShotErrors { - kNone = 0, - kScaleOutOfRange, - kTabNotActive, - kWebContentsNotVisible, - kNoSurface, - kNoRenderWidgetHostView, - kNoWindowAndroid, - kEmptyViewport, - kHiddenByControls, - kScaledToEmpty, - kCaptureFailed, - kBitmapAllocationFailed, - }; - - class DataObserver { - public: - // Called when SetData() is called on |tab|. - virtual void OnDataChanged( - TabImpl* tab, - const std::map<std::string, std::string>& data) = 0; - }; - - // TODO(sky): investigate a better way to not have so many ifdefs. -#if BUILDFLAG(IS_ANDROID) - TabImpl(ProfileImpl* profile, - const base::android::JavaParamRef<jobject>& java_impl, - std::unique_ptr<content::WebContents> web_contents); -#endif - explicit TabImpl(ProfileImpl* profile, - std::unique_ptr<content::WebContents> web_contents, - const std::string& guid = std::string()); - - TabImpl(const TabImpl&) = delete; - TabImpl& operator=(const TabImpl&) = delete; - - ~TabImpl() override; - - // Returns the TabImpl from the specified WebContents (which may be null), or - // null if |web_contents| was not created by a TabImpl. - static TabImpl* FromWebContents(content::WebContents* web_contents); - - static std::set<TabImpl*> GetAllTabImpl(); - - ProfileImpl* profile() { return profile_; } - - void set_browser(BrowserImpl* browser) { browser_ = browser; } - BrowserImpl* browser() { return browser_; } - - content::WebContents* web_contents() const { return web_contents_.get(); } - - bool has_new_tab_delegate() const { return new_tab_delegate_ != nullptr; } - NewTabDelegate* new_tab_delegate() const { return new_tab_delegate_; } - - // Called from Browser when this Tab is gaining/losing active status. - void OnGainedActive(); - void OnLosingActive(); - - bool IsActive(); - - void ShowContextMenu(const content::ContextMenuParams& params); - -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> GetJavaTab() { - return java_impl_; - } - - bool desktop_user_agent_enabled() { return desktop_user_agent_enabled_; } - - // Call this method to disable integration with the system-level Autofill - // infrastructure. Useful in conjunction with InitializeAutofillForTests(). - // Should be called early in the lifetime of WebLayer, and in - // particular, must be called before the TabImpl is attached to the browser - // on the Java side to have the desired effect. - static void DisableAutofillSystemIntegrationForTesting(); - - base::android::ScopedJavaLocalRef<jobject> GetWebContents(JNIEnv* env); - void ExecuteScript(JNIEnv* env, - const base::android::JavaParamRef<jstring>& script, - bool use_separate_isolate, - const base::android::JavaParamRef<jobject>& callback); - void SetJavaImpl(JNIEnv* env, - const base::android::JavaParamRef<jobject>& impl); - - // Invoked every time that the Java-side AutofillProvider instance is created, - // the native side autofill might have been initialized in the case that - // Android context is switched. - void InitializeAutofillIfNecessary(JNIEnv* env); - - base::android::ScopedJavaLocalRef<jstring> GetGuid(JNIEnv* env); - void CaptureScreenShot( - JNIEnv* env, - jfloat scale, - const base::android::JavaParamRef<jobject>& value_callback); - - jboolean SetData(JNIEnv* env, - const base::android::JavaParamRef<jobjectArray>& data); - base::android::ScopedJavaLocalRef<jobjectArray> GetData(JNIEnv* env); - jboolean CanTranslate(JNIEnv* env); - void ShowTranslateUi(JNIEnv* env); - void RemoveTabFromBrowserBeforeDestroying(JNIEnv* env); - void SetTranslateTargetLanguage( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& translate_target_lang); - void SetDesktopUserAgentEnabled(JNIEnv* env, jboolean enable); - jboolean IsDesktopUserAgentEnabled(JNIEnv* env); - void Download(JNIEnv* env, jlong native_context_menu_params); -#endif - - ErrorPageDelegate* error_page_delegate() { return error_page_delegate_; } - - void AddDataObserver(DataObserver* observer); - void RemoveDataObserver(DataObserver* observer); - - GoogleAccountsDelegate* google_accounts_delegate() { - return google_accounts_delegate_; - } - - // Tab: - Browser* GetBrowser() override; - void SetErrorPageDelegate(ErrorPageDelegate* delegate) override; - void SetFullscreenDelegate(FullscreenDelegate* delegate) override; - void SetNewTabDelegate(NewTabDelegate* delegate) override; - void SetGoogleAccountsDelegate(GoogleAccountsDelegate* delegate) override; - void AddObserver(TabObserver* observer) override; - void RemoveObserver(TabObserver* observer) override; - NavigationController* GetNavigationController() override; - void ExecuteScript(const std::u16string& script, - bool use_separate_isolate, - JavaScriptResultCallback callback) override; - const std::string& GetGuid() override; - void SetData(const std::map<std::string, std::string>& data) override; - const std::map<std::string, std::string>& GetData() override; - std::unique_ptr<FaviconFetcher> CreateFaviconFetcher( - FaviconFetcherDelegate* delegate) override; - void SetTranslateTargetLanguage( - const std::string& translate_target_lang) override; -#if !BUILDFLAG(IS_ANDROID) - void AttachToView(views::WebView* web_view) override; -#endif - - void WebPreferencesChanged(); - void SetWebPreferences(blink::web_pref::WebPreferences* prefs); - - // Executes |script| with a user gesture. - void ExecuteScriptWithUserGestureForTests(const std::u16string& script); - -#if BUILDFLAG(IS_ANDROID) - // Initializes the autofill system for tests. - void InitializeAutofillForTests(); -#endif // BUILDFLAG(IS_ANDROID) - - private: - // content::WebContentsDelegate: - content::WebContents* OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) override; - void ShowRepostFormWarningDialog(content::WebContents* source) override; - void NavigationStateChanged(content::WebContents* source, - content::InvalidateTypes changed_flags) override; - content::JavaScriptDialogManager* GetJavaScriptDialogManager( - content::WebContents* web_contents) override; -#if BUILDFLAG(IS_ANDROID) - std::unique_ptr<content::ColorChooser> OpenColorChooser( - content::WebContents* web_contents, - SkColor color, - const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) - override; -#endif - void RunFileChooser(content::RenderFrameHost* render_frame_host, - scoped_refptr<content::FileSelectListener> listener, - const blink::mojom::FileChooserParams& params) override; - void CreateSmsPrompt(content::RenderFrameHost*, - const std::vector<url::Origin>&, - const std::string& one_time_code, - base::OnceClosure on_confirm, - base::OnceClosure on_cancel) override; - bool IsBackForwardCacheSupported() override; - void RequestMediaAccessPermission( - content::WebContents* web_contents, - const content::MediaStreamRequest& request, - content::MediaResponseCallback callback) override; - bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host, - const GURL& security_origin, - blink::mojom::MediaStreamType type) override; - void EnterFullscreenModeForTab( - content::RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options) override; - void ExitFullscreenModeForTab(content::WebContents* web_contents) override; - bool IsFullscreenForTabOrPending( - const content::WebContents* web_contents) override; - blink::mojom::DisplayMode GetDisplayMode( - const content::WebContents* web_contents) override; - void AddNewContents(content::WebContents* source, - std::unique_ptr<content::WebContents> new_contents, - const GURL& target_url, - WindowOpenDisposition disposition, - const blink::mojom::WindowFeatures& window_features, - bool user_gesture, - bool* was_blocked) override; - void CloseContents(content::WebContents* source) override; - void FindReply(content::WebContents* web_contents, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) override; -#if BUILDFLAG(IS_ANDROID) - void FindMatchRectsReply(content::WebContents* web_contents, - int version, - const std::vector<gfx::RectF>& rects, - const gfx::RectF& active_rect) override; - - // Pointer arguments are outputs. Check the preconditions for capturing a - // screenshot and either set all outputs, or return an error code, in which - // case the state of output arguments is undefined. - ScreenShotErrors PrepareForCaptureScreenShot( - float scale, - content::RenderWidgetHostView** rwhv, - gfx::Rect* src_rect, - gfx::Size* output_size); -#endif - - // content::WebContentsObserver: - void PrimaryMainFrameRenderProcessGone( - base::TerminationStatus status) override; - void DidChangeVisibleSecurityState() override; - - // find_in_page::FindResultObserver: - void OnFindResultAvailable(content::WebContents* web_contents) override; - - // Called from closure supplied to delegate to exit fullscreen. - void OnExitFullscreen(); - - void UpdateRendererPrefs(bool should_sync_prefs); - - // Returns the FindTabHelper for the page, or null if none exists. - find_in_page::FindTabHelper* GetFindTabHelper(); - - static sessions::SessionTabHelperDelegate* GetSessionServiceTabHelperDelegate( - content::WebContents* web_contents); - -#if BUILDFLAG(IS_ANDROID) - void InitializeAutofillDriver(); -#endif - - void UpdateBrowserVisibleSecurityStateIfNecessary(); - - bool SetDataInternal(const std::map<std::string, std::string>& data); - - void EnterFullscreenImpl(); - - raw_ptr<BrowserImpl> browser_ = nullptr; - raw_ptr<ErrorPageDelegate> error_page_delegate_ = nullptr; - raw_ptr<FullscreenDelegate> fullscreen_delegate_ = nullptr; - raw_ptr<NewTabDelegate> new_tab_delegate_ = nullptr; - raw_ptr<GoogleAccountsDelegate> google_accounts_delegate_ = nullptr; - raw_ptr<ProfileImpl> profile_; - std::unique_ptr<content::WebContents> web_contents_; - std::unique_ptr<NavigationControllerImpl> navigation_controller_; - base::ObserverList<TabObserver>::Unchecked observers_; - base::CallbackListSubscription locale_change_subscription_; - -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> java_impl_; - - bool desktop_user_agent_enabled_ = false; -#endif - - bool is_fullscreen_ = false; - // Set to true doing EnterFullscreenModeForTab(). - bool processing_enter_fullscreen_ = false; - - // If true, the fullscreen delegate is called when the tab gains active. - bool enter_fullscreen_on_gained_active_ = false; - - const std::string guid_; - - std::map<std::string, std::string> data_; - base::ObserverList<DataObserver>::Unchecked data_observers_; - - std::u16string title_; - - base::WeakPtrFactory<TabImpl> weak_ptr_factory_for_fullscreen_exit_{this}; -}; - -} // namespace weblayer - -namespace base { - -template <> -struct ScopedObservationTraits<weblayer::TabImpl, - weblayer::TabImpl::DataObserver> { - static void AddObserver(weblayer::TabImpl* source, - weblayer::TabImpl::DataObserver* observer) { - source->AddDataObserver(observer); - } - static void RemoveObserver(weblayer::TabImpl* source, - weblayer::TabImpl::DataObserver* observer) { - source->RemoveDataObserver(observer); - } -}; - -} // namespace base - -#endif // WEBLAYER_BROWSER_TAB_IMPL_H_
diff --git a/weblayer/browser/test/test_infobar.cc b/weblayer/browser/test/test_infobar.cc deleted file mode 100644 index e276d55..0000000 --- a/weblayer/browser/test/test_infobar.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/test/test_infobar.h" - -#include <memory> -#include <utility> - -#include "base/functional/bind.h" -#include "components/infobars/content/content_infobar_manager.h" -#include "components/infobars/core/infobar_delegate.h" -#include "weblayer/browser/java/test_jni/TestInfoBar_jni.h" - -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -class TestInfoBarDelegate : public infobars::InfoBarDelegate { - public: - TestInfoBarDelegate() = default; - - ~TestInfoBarDelegate() override = default; - - infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override { - return InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR; - } -}; - -TestInfoBar::TestInfoBar(std::unique_ptr<TestInfoBarDelegate> delegate) - : infobars::InfoBarAndroid(std::move(delegate)) {} - -TestInfoBar::~TestInfoBar() = default; - -void TestInfoBar::ProcessButton(int action) {} - -ScopedJavaLocalRef<jobject> TestInfoBar::CreateRenderInfoBar( - JNIEnv* env, - const ResourceIdMapper& resource_id_mapper) { - return Java_TestInfoBar_create(env); -} - -// static -void TestInfoBar::Show(content::WebContents* web_contents) { - infobars::ContentInfoBarManager* manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - manager->AddInfoBar( - std::make_unique<TestInfoBar>(std::make_unique<TestInfoBarDelegate>())); -} - -static void JNI_TestInfoBar_Show( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& j_web_contents) { - auto* web_contents = - content::WebContents::FromJavaWebContents(j_web_contents); - TestInfoBar::Show(web_contents); -} - -} // namespace weblayer
diff --git a/weblayer/browser/test/test_infobar.h b/weblayer/browser/test/test_infobar.h deleted file mode 100644 index af7bf953..0000000 --- a/weblayer/browser/test/test_infobar.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TEST_TEST_INFOBAR_H_ -#define WEBLAYER_BROWSER_TEST_TEST_INFOBAR_H_ - -#include "base/android/jni_android.h" -#include "base/android/scoped_java_ref.h" -#include "components/infobars/android/infobar_android.h" -#include "components/infobars/core/infobar_delegate.h" -#include "content/public/browser/web_contents.h" - -namespace weblayer { - -class TestInfoBarDelegate; - -// A test infobar. -class TestInfoBar : public infobars::InfoBarAndroid { - public: - explicit TestInfoBar(std::unique_ptr<TestInfoBarDelegate> delegate); - ~TestInfoBar() override; - - TestInfoBar(const TestInfoBar&) = delete; - TestInfoBar& operator=(const TestInfoBar&) = delete; - - static void Show(content::WebContents* web_contents); - - protected: - infobars::InfoBarDelegate* GetDelegate(); - - // infobars::InfoBarAndroid overrides. - void ProcessButton(int action) override; - base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( - JNIEnv* env, - const ResourceIdMapper& resource_id_mapper) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TEST_TEST_INFOBAR_H_
diff --git a/weblayer/browser/test/test_weblayer_impl.cc b/weblayer/browser/test/test_weblayer_impl.cc deleted file mode 100644 index 92a1c6b..0000000 --- a/weblayer/browser/test/test_weblayer_impl.cc +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/java/test_jni/TestWebLayerImpl_jni.h" - -#include <utility> - -#include "base/android/callback_android.h" -#include "base/android/jni_string.h" -#include "base/no_destructor.h" -#include "base/test/scoped_feature_list.h" -#include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/download/public/background_service/features.h" -#include "components/translate/core/browser/translate_manager.h" -#include "content/public/test/browser_test_utils.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" - -using base::android::AttachCurrentThread; -using base::android::ScopedJavaGlobalRef; - -namespace weblayer { -namespace { - -void CheckMetadata( - std::unique_ptr<content::RenderFrameSubmissionObserver> observer, - int top_height, - int bottom_height, - const ScopedJavaGlobalRef<jobject>& runnable) { - const cc::RenderFrameMetadata& last_metadata = - observer->LastRenderFrameMetadata(); - if (last_metadata.top_controls_height == top_height && - last_metadata.bottom_controls_height == bottom_height) { - base::android::RunRunnableAndroid(runnable); - return; - } - auto* const observer_ptr = observer.get(); - observer_ptr->NotifyOnNextMetadataChange( - base::BindOnce(&CheckMetadata, std::move(observer), top_height, - bottom_height, runnable)); -} - -} // namespace - -static void JNI_TestWebLayerImpl_WaitForBrowserControlsMetadataState( - JNIEnv* env, - jlong tab_impl, - jint top_height, - jint bottom_height, - const base::android::JavaParamRef<jobject>& runnable) { - TabImpl* tab = reinterpret_cast<TabImpl*>(tab_impl); - auto observer = std::make_unique<content::RenderFrameSubmissionObserver>( - tab->web_contents()); - CheckMetadata(std::move(observer), top_height, bottom_height, - ScopedJavaGlobalRef<jobject>(runnable)); -} - -static void JNI_TestWebLayerImpl_SetIgnoreMissingKeyForTranslateManager( - JNIEnv* env, - jboolean ignore) { - translate::TranslateManager::SetIgnoreMissingKeyForTesting(ignore); -} - -static void JNI_TestWebLayerImpl_ExpediteDownloadService(JNIEnv* env) { - static base::NoDestructor<base::test::ScopedFeatureList> feature_list; - feature_list->InitAndEnableFeatureWithParameters( - download::kDownloadServiceFeature, {{"start_up_delay_ms", "0"}}); -} - -static void JNI_TestWebLayerImpl_GrantLocationPermission( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& jurl) { - GURL url(base::android::ConvertJavaStringToUTF8(env, jurl)); - for (auto* profile : ProfileImpl::GetAllProfiles()) { - HostContentSettingsMapFactory::GetForBrowserContext( - profile->GetBrowserContext()) - ->SetContentSettingDefaultScope( - url, url, ContentSettingsType::GEOLOCATION, CONTENT_SETTING_ALLOW); - } -} - -} // namespace weblayer
diff --git a/weblayer/browser/tracking_protection_settings_factory.cc b/weblayer/browser/tracking_protection_settings_factory.cc deleted file mode 100644 index 9f9b1f5..0000000 --- a/weblayer/browser/tracking_protection_settings_factory.cc +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/tracking_protection_settings_factory.h" - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/prefs/pref_service.h" -#include "components/privacy_sandbox/tracking_protection_settings.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" - -namespace weblayer { - -// static -privacy_sandbox::TrackingProtectionSettings* -TrackingProtectionSettingsFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<privacy_sandbox::TrackingProtectionSettings*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -TrackingProtectionSettingsFactory* -TrackingProtectionSettingsFactory::GetInstance() { - static base::NoDestructor<TrackingProtectionSettingsFactory> factory; - return factory.get(); -} - -TrackingProtectionSettingsFactory::TrackingProtectionSettingsFactory() - : BrowserContextKeyedServiceFactory( - "TrackingProtectionSettings", - BrowserContextDependencyManager::GetInstance()) {} - -TrackingProtectionSettingsFactory::~TrackingProtectionSettingsFactory() = - default; - -content::BrowserContext* -TrackingProtectionSettingsFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -std::unique_ptr<KeyedService> -TrackingProtectionSettingsFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return std::make_unique<privacy_sandbox::TrackingProtectionSettings>( - user_prefs::UserPrefs::Get(context), nullptr); -} - -} // namespace weblayer
diff --git a/weblayer/browser/tracking_protection_settings_factory.h b/weblayer/browser/tracking_protection_settings_factory.h deleted file mode 100644 index 90776f1..0000000 --- a/weblayer/browser/tracking_protection_settings_factory.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TRACKING_PROTECTION_SETTINGS_FACTORY_H_ -#define WEBLAYER_BROWSER_TRACKING_PROTECTION_SETTINGS_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace privacy_sandbox { -class TrackingProtectionSettings; -} - -namespace weblayer { - -class TrackingProtectionSettingsFactory - : public BrowserContextKeyedServiceFactory { - public: - TrackingProtectionSettingsFactory(const TrackingProtectionSettingsFactory&) = - delete; - TrackingProtectionSettingsFactory& operator=( - const TrackingProtectionSettingsFactory&) = delete; - - static scoped_refptr<privacy_sandbox::TrackingProtectionSettings> - GetForBrowserContext(content::BrowserContext* browser_context); - static TrackingProtectionSettingsFactory* GetInstance(); - - private: - friend class base::NoDestructor<TrackingProtectionSettingsFactory>; - - TrackingProtectionSettingsFactory(); - ~TrackingProtectionSettingsFactory() override; - - // BrowserContextKeyedServiceFactory methods: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TRACKING_PROTECTION_SETTINGS_FACTORY_H_
diff --git a/weblayer/browser/translate_browsertest.cc b/weblayer/browser/translate_browsertest.cc deleted file mode 100644 index f140445..0000000 --- a/weblayer/browser/translate_browsertest.cc +++ /dev/null
@@ -1,1014 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "build/build_config.h" -#include "components/infobars/android/infobar_android.h" // nogncheck -#include "components/infobars/content/content_infobar_manager.h" -#include "components/infobars/core/infobar_manager.h" // nogncheck -#include "components/translate/content/browser/translate_waiter.h" -#include "components/translate/core/browser/language_state.h" -#include "components/translate/core/browser/translate_download_manager.h" -#include "components/translate/core/browser/translate_error_details.h" -#include "components/translate/core/browser/translate_manager.h" -#include "components/translate/core/common/language_detection_details.h" -#include "components/translate/core/common/translate_switches.h" -#include "content/public/browser/browser_context.h" -#include "net/base/mock_network_change_notifier.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/browser/translate_client_impl.h" -#include "weblayer/browser/translate_compact_infobar.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/android/browsertests_apk/translate_test_bridge.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/test_navigation_observer.h" -#include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -static std::string kTestValidScript = R"( - var google = {}; - google.translate = (function() { - return { - TranslateService: function() { - return { - isAvailable : function() { - return true; - }, - restore : function() { - return; - }, - getDetectedLanguage : function() { - return "fr"; - }, - translatePage : function(sourceLang, targetLang, - onTranslateProgress) { - var error = (sourceLang == 'auto') ? true : false; - onTranslateProgress(100, true, error); - } - }; - } - }; - })(); - cr.googleTranslate.onTranslateElementLoad();)"; - -static std::string kTestScriptInitializationError = R"( - var google = {}; - google.translate = (function() { - return { - TranslateService: function() { - return error; - } - }; - })(); - cr.googleTranslate.onTranslateElementLoad();)"; - -static std::string kTestScriptTimeout = R"( - var google = {}; - google.translate = (function() { - return { - TranslateService: function() { - return { - isAvailable : function() { - return false; - }, - }; - } - }; - })(); - cr.googleTranslate.onTranslateElementLoad();)"; - -TranslateClientImpl* GetTranslateClient(Shell* shell) { - return TranslateClientImpl::FromWebContents( - static_cast<TabImpl*>(shell->tab())->web_contents()); -} - -std::unique_ptr<translate::TranslateWaiter> CreateTranslateWaiter( - Shell* shell, - translate::TranslateWaiter::WaitEvent wait_event) { - return std::make_unique<translate::TranslateWaiter>( - GetTranslateClient(shell)->translate_driver(), wait_event); -} - -} // namespace - -class TestInfoBarManagerObserver : public infobars::InfoBarManager::Observer { - public: - TestInfoBarManagerObserver() = default; - ~TestInfoBarManagerObserver() override = default; - void OnInfoBarAdded(infobars::InfoBar* infobar) override { - if (on_infobar_added_callback_) - std::move(on_infobar_added_callback_).Run(); - } - - void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override { - if (on_infobar_removed_callback_) - std::move(on_infobar_removed_callback_).Run(); - } - - void set_on_infobar_added_callback(base::OnceClosure callback) { - on_infobar_added_callback_ = std::move(callback); - } - - void set_on_infobar_removed_callback(base::OnceClosure callback) { - on_infobar_removed_callback_ = std::move(callback); - } - - private: - base::OnceClosure on_infobar_added_callback_; - base::OnceClosure on_infobar_removed_callback_; -}; - -class TranslateBrowserTest : public WebLayerBrowserTest { - public: - TranslateBrowserTest() { - error_subscription_ = - translate::TranslateManager::RegisterTranslateErrorCallback( - base::BindRepeating(&TranslateBrowserTest::OnTranslateError, - base::Unretained(this))); - } - ~TranslateBrowserTest() override = default; - - void SetUpOnMainThread() override { - embedded_test_server()->RegisterRequestHandler(base::BindRepeating( - &TranslateBrowserTest::HandleRequest, base::Unretained(this))); - embedded_test_server()->StartAcceptingConnections(); - - // Translation will not be offered if NetworkChangeNotifier reports that the - // app is offline, which can occur on bots. Prevent this. - // NOTE: MockNetworkChangeNotifier cannot be instantiated earlier than this - // due to its dependence on browser state having been created. - mock_network_change_notifier_ = - std::make_unique<net::test::ScopedMockNetworkChangeNotifier>(); - mock_network_change_notifier_->mock_network_change_notifier() - ->SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - - // By default, translation is not offered if the Google API key is not set. - GetTranslateClient(shell()) - ->GetTranslateManager() - ->SetIgnoreMissingKeyForTesting(true); - - GetTranslateClient(shell())->GetTranslatePrefs()->ResetToDefaults(); - } - - void TearDownOnMainThread() override { - language_determination_waiter_.reset(); - page_translation_waiter_.reset(); - mock_network_change_notifier_.reset(); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); - - command_line->AppendSwitchASCII( - translate::switches::kTranslateScriptURL, - embedded_test_server()->GetURL("/mock_translate_script.js").spec()); - } - - protected: - translate::TranslateErrors GetPageTranslatedResult() { return error_type_; } - void SetTranslateScript(const std::string& script) { script_ = script; } - - void ResetLanguageDeterminationWaiter() { - language_determination_waiter_ = CreateTranslateWaiter( - shell(), translate::TranslateWaiter::WaitEvent::kLanguageDetermined); - } - - void ResetPageTranslationWaiter() { - page_translation_waiter_ = CreateTranslateWaiter( - shell(), translate::TranslateWaiter::WaitEvent::kPageTranslated); - } - - std::unique_ptr<translate::TranslateWaiter> language_determination_waiter_; - std::unique_ptr<translate::TranslateWaiter> page_translation_waiter_; - - private: - std::unique_ptr<net::test_server::HttpResponse> HandleRequest( - const net::test_server::HttpRequest& request) { - if (request.GetURL().path() != "/mock_translate_script.js") - return nullptr; - - auto http_response = - std::make_unique<net::test_server::BasicHttpResponse>(); - http_response->set_code(net::HTTP_OK); - http_response->set_content(script_); - http_response->set_content_type("text/javascript"); - return std::move(http_response); - } - - void OnTranslateError(const translate::TranslateErrorDetails& details) { - error_type_ = details.error; - } - - std::unique_ptr<net::test::ScopedMockNetworkChangeNotifier> - mock_network_change_notifier_; - - translate::TranslateErrors error_type_ = translate::TranslateErrors::NONE; - base::CallbackListSubscription error_subscription_; - std::string script_; -}; - -// Tests that the CLD (Compact Language Detection) works properly. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageLanguageDetection) { - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Go to a page in English. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/english_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("en", translate_client->GetLanguageState().source_language()); - - // Now navigate to a page in French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); -} - -// Tests that firing the page language determined notification for a -// failed-but-committed navigation does not cause a crash. Regression test for -// crbug.com/1262047. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - PageLanguageDetectionInFailedButCommittedNavigation) { - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - auto url = embedded_test_server()->GetURL("/empty404.html"); - TestNavigationObserver navigation_failed_observer( - url, TestNavigationObserver::NavigationEvent::kFailure, shell()); - shell()->tab()->GetNavigationController()->Navigate(url); - navigation_failed_observer.Wait(); - - // Fire the OnLanguageDetermined() notification manually to mimic the - // production flow in which this is crashing (crbug.com/1262047). - // TODO(blundell): Replace this manual triggering by doing a - // failed-but-committed navigation that results in the OnLanguageDetermined() - // notification firing once I determine which navigations result in that flow - // in production. - translate::LanguageDetectionDetails language_details; - language_details.adopted_language = "en"; - translate_client->OnLanguageDetermined(language_details); -} - -// Test that the translation was successful. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageTranslationSuccess) { - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Navigate to a page in French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // Translate the page through TranslateManager. - ResetPageTranslationWaiter(); - translate::TranslateManager* manager = - translate_client->GetTranslateManager(); - manager->TranslatePage(translate_client->GetLanguageState().source_language(), - "en", true); - - page_translation_waiter_->Wait(); - - EXPECT_FALSE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult()); -} - -class IncognitoTranslateBrowserTest : public TranslateBrowserTest { - public: - IncognitoTranslateBrowserTest() { SetShellStartsInIncognitoMode(); } -}; - -// Test that the translation infrastructure is set up properly when the user is -// in incognito mode. -IN_PROC_BROWSER_TEST_F(IncognitoTranslateBrowserTest, - DISABLED_PageTranslationSuccess_IncognitoMode) { - ASSERT_TRUE(GetProfile()->GetBrowserContext()->IsOffTheRecord()); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Navigate to a page in French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // Translate the page through TranslateManager. - ResetPageTranslationWaiter(); - translate::TranslateManager* manager = - translate_client->GetTranslateManager(); - manager->TranslatePage(translate_client->GetLanguageState().source_language(), - "en", true); - - page_translation_waiter_->Wait(); - - EXPECT_FALSE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult()); -} - -// Test if there was an error during translation. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageTranslationError) { - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Navigate to a empty page to result in the model returning "und". - // An "und" result will result in "auto" as the source language - // in the translate script. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/clipboard.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("und", translate_client->GetLanguageState().source_language()); - - // Translate the page through TranslateManager. - ResetPageTranslationWaiter(); - translate::TranslateManager* manager = - translate_client->GetTranslateManager(); - manager->TranslatePage(translate_client->GetLanguageState().source_language(), - "en", true); - - page_translation_waiter_->Wait(); - - EXPECT_TRUE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::TRANSLATION_ERROR, - GetPageTranslatedResult()); -} - -// Test if there was an error during translate library initialization. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - PageTranslationInitializationError) { - SetTranslateScript(kTestScriptInitializationError); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Navigate to a page in French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // Translate the page through TranslateManager. - ResetPageTranslationWaiter(); - translate::TranslateManager* manager = - translate_client->GetTranslateManager(); - manager->TranslatePage(translate_client->GetLanguageState().source_language(), - "en", true); - - page_translation_waiter_->Wait(); - - EXPECT_TRUE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::INITIALIZATION_ERROR, - GetPageTranslatedResult()); -} - -// Test the checks translate lib never gets ready and throws timeout. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageTranslationTimeoutError) { - SetTranslateScript(kTestScriptTimeout); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Navigate to a page in French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // Translate the page through TranslateManager. - ResetPageTranslationWaiter(); - translate::TranslateManager* manager = - translate_client->GetTranslateManager(); - manager->TranslatePage(translate_client->GetLanguageState().source_language(), - "en", true); - - page_translation_waiter_->Wait(); - - EXPECT_TRUE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::TRANSLATION_TIMEOUT, - GetPageTranslatedResult()); -} - -// Test that autotranslation kicks in if configured via prefs. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, Autotranslation) { - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Before browsing, set autotranslate from French to Chinese. - translate_client->GetTranslatePrefs()->AddLanguagePairToAlwaysTranslateList( - "fr", "zh-CN"); - - // Navigate to a page in French. - ResetLanguageDeterminationWaiter(); - ResetPageTranslationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // Autotranslation should kick in. - page_translation_waiter_->Wait(); - - EXPECT_FALSE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult()); - EXPECT_EQ("zh-CN", translate_client->GetLanguageState().current_language()); -} - -// Test that the translation infobar is presented when visiting a page with a -// translation opportunity and removed when navigating away. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, TranslateInfoBarPresentation) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - EXPECT_EQ(0u, infobar_manager->infobar_count()); - // Navigate to a page in French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // The translate infobar should be added. - run_loop.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - auto* infobar = - static_cast<infobars::InfoBarAndroid*>(infobar_manager->infobar_at(0)); - EXPECT_TRUE(infobar->HasSetJavaInfoBar()); - - base::RunLoop run_loop2; - infobar_observer.set_on_infobar_removed_callback(run_loop2.QuitClosure()); - - NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - - // The translate infobar should be removed. - run_loop2.Run(); - - EXPECT_EQ(0u, infobar_manager->infobar_count()); - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that the translation infobar is not presented when visiting a page with -// a translation opportunity but where the page has specified that it should not -// be translated. -IN_PROC_BROWSER_TEST_F( - TranslateBrowserTest, - TranslateInfoBarNotPresentedWhenPageSpecifiesNoTranslate) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - // Navigate to a page in French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page_no_translate.html")), - shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // NOTE: There is no notification to wait for the event of the infobar not - // showing. However, in practice the infobar is added synchronously, so if it - // were to be shown, this check would fail. - EXPECT_EQ(0u, infobar_manager->infobar_count()); -} - -// Test that the translation can be successfully initiated via infobar. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, TranslationViaInfoBar) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - // Navigate to a page in French and wait for the infobar to be added. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - run_loop.Run(); - - // Select the target language via the Java infobar and ensure that translation - // occurs. - ResetPageTranslationWaiter(); - auto* infobar = - static_cast<TranslateCompactInfoBar*>(infobar_manager->infobar_at(0)); - TranslateTestBridge::SelectButton( - infobar, infobars::InfoBarAndroid::ActionType::ACTION_TRANSLATE); - - page_translation_waiter_->Wait(); - - EXPECT_FALSE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult()); - - // The translate infobar should still be present. - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - // NOTE: The notification that the translate state of the page changed can - // occur synchronously once reversion is initiated, so it's necessary to start - // listening for that notification prior to initiating the reversion. - auto translate_reversion_waiter = CreateTranslateWaiter( - shell(), translate::TranslateWaiter::WaitEvent::kIsPageTranslatedChanged); - - // Revert to the source language via the Java infobar and ensure that the - // translation is undone. - TranslateTestBridge::SelectButton( - infobar, - infobars::InfoBarAndroid::ActionType::ACTION_TRANSLATE_SHOW_ORIGINAL); - - translate_reversion_waiter->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().current_language()); - - // The translate infobar should still be present. - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that translation occurs when a target language is set. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - TranslationViaPredefinedTargetLanguage) { - auto* tab = static_cast<TabImpl*>(shell()->tab()); - auto* web_contents = tab->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - tab->SetTranslateTargetLanguage("ru"); - - // Navigate to a page in French and wait for the infobar to be added and - // autotranslation to occur. - ResetPageTranslationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - - run_loop.Run(); - - page_translation_waiter_->Wait(); - - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - EXPECT_FALSE(translate_client->GetLanguageState().translation_error()); - EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult()); - EXPECT_EQ("ru", translate_client->GetLanguageState().current_language()); - - // The translate infobar should still be present. - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that the infobar appears on pages in the user's locale iff a target -// language is set. -IN_PROC_BROWSER_TEST_F( - TranslateBrowserTest, - InfoBarAppearsForDefaultLanguageWhenPredefinedTargetLanguageIsSet) { - auto* tab = static_cast<TabImpl*>(shell()->tab()); - auto* web_contents = tab->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - // Navigate to a page in English: the infobar should not appear. - ResetPageTranslationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/english_page.html")), shell()); - - // NOTE: There is no notification to wait for for the event of the infobar not - // showing. However, in practice the infobar is added synchronously, so if it - // were to be shown, this check would fail. - EXPECT_EQ(0u, infobar_manager->infobar_count()); - - // Set a target language, navigate again, and verify that the infobar now - // appears. - tab->SetTranslateTargetLanguage("ru"); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/english_page.html")), shell()); - - run_loop.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that when a predefined target language is set, the infobar does not -// appear on pages in that language. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - InfoBarDoesNotAppearForPageInPredefinedTargetLanguage) { - auto* tab = static_cast<TabImpl*>(shell()->tab()); - auto* web_contents = tab->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - // Navigate to a page in French: the infobar should appear. - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - - run_loop.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - // Set the target language to French. - tab->SetTranslateTargetLanguage("fr"); - - // Navigate again to a page in French: the infobar should not appear. - ResetPageTranslationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - - // NOTE: There is no notification to wait for for the event of the infobar not - // showing. However, in practice the infobar is added synchronously, so if it - // were to be shown, this check would fail. - EXPECT_EQ(0u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that the translation infobar stays present when the "never translate -// language" item is clicked. Note that this behavior is intentionally different -// from that of Chrome, where the infobar is removed in this case and a snackbar -// is shown. As WebLayer has no snackbars, the UX decision was to simply leave -// the infobar open to allow the user to revert the decision if desired. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - TranslateInfoBarNeverTranslateLanguage) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - // Navigate to a page in French and wait for the infobar to be added. - ResetLanguageDeterminationWaiter(); - EXPECT_EQ(0u, infobar_manager->infobar_count()); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - run_loop.Run(); - - auto* infobar = - static_cast<TranslateCompactInfoBar*>(infobar_manager->infobar_at(0)); - TranslateTestBridge::ClickOverflowMenuItem( - infobar, - TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_LANGUAGE); - - // The translate infobar should still be present. - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - // However, the infobar should not be shown on a new navigation to a page in - // French. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page2.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // NOTE: There is no notification to wait for for the event of the infobar not - // showing. However, in practice the infobar is added synchronously, so if it - // were to be shown, this check would fail. - EXPECT_EQ(0u, infobar_manager->infobar_count()); - - // The infobar *should* be shown on a navigation to this site if the page's - // language is detected as something other than French. - base::RunLoop run_loop2; - infobar_observer.set_on_infobar_added_callback(run_loop2.QuitClosure()); - - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/german_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("de", translate_client->GetLanguageState().source_language()); - - run_loop2.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that the infobar shows when a predefined target language is set even if -// the source language is in the "never translate" set. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - PredefinedTargetLanguageOverridesLanguageBlocklist) { - auto* tab = static_cast<TabImpl*>(shell()->tab()); - auto* web_contents = tab->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - tab->SetTranslateTargetLanguage("ru"); - - // Navigate to a page in French and wait for the infobar to be added. - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - - run_loop.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - auto* infobar = - static_cast<TranslateCompactInfoBar*>(infobar_manager->infobar_at(0)); - TranslateTestBridge::ClickOverflowMenuItem( - infobar, - TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_LANGUAGE); - - // Since a predefined target language is set, the infobar should still be - // shown on a new navigation to a page in French even though it's blocklisted. - ResetLanguageDeterminationWaiter(); - base::RunLoop run_loop2; - infobar_observer.set_on_infobar_added_callback(run_loop2.QuitClosure()); - - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page2.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - run_loop2.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that the translation infobar stays present when the "never translate -// site" item is clicked. Note that this behavior is intentionally different -// from that of Chrome, where the infobar is removed in this case and a snackbar -// is shown. As WebLayer has no snackbars, the UX decision was to simply leave -// the infobar open to allow the user to revert the decision if desired. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - TranslateInfoBarNeverTranslateSite) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - // Navigate to a page in French and wait for the infobar to be added. - ResetLanguageDeterminationWaiter(); - EXPECT_EQ(0u, infobar_manager->infobar_count()); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - run_loop.Run(); - - auto* infobar = - static_cast<TranslateCompactInfoBar*>(infobar_manager->infobar_at(0)); - TranslateTestBridge::ClickOverflowMenuItem( - infobar, TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_SITE); - - // The translate infobar should still be present. - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - // However, the infobar should not be shown on a new navigation to this site, - // independent of the detected language. - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page2.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // NOTE: There is no notification to wait for for the event of the infobar not - // showing. However, in practice the infobar is added synchronously, so if it - // were to be shown, this check would fail. - EXPECT_EQ(0u, infobar_manager->infobar_count()); - - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/german_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("de", translate_client->GetLanguageState().source_language()); - EXPECT_EQ(0u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Test that the infobar does not show when a predefined target language is set -// and the user selects to never translate the site. -IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, - PredefinedTargetLanguageDoesNotOverrideSiteBlocklist) { - auto* tab = static_cast<TabImpl*>(shell()->tab()); - auto* web_contents = tab->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - tab->SetTranslateTargetLanguage("ru"); - - // Navigate and wait for the infobar to be added. - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - - run_loop.Run(); - - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - // Blocklist the site. - auto* infobar = - static_cast<TranslateCompactInfoBar*>(infobar_manager->infobar_at(0)); - TranslateTestBridge::ClickOverflowMenuItem( - infobar, TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_SITE); - - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page2.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - // NOTE: There is no notification to wait for for the event of the infobar not - // showing. However, in practice the infobar is added synchronously, so if it - // were to be shown, this check would fail. - EXPECT_EQ(0u, infobar_manager->infobar_count()); - - infobar_manager->RemoveObserver(&infobar_observer); -} - -// Parameterized to run tests on the "never translate language" and "never -// translate site" menu items. -class NeverTranslateMenuItemTranslateBrowserTest - : public TranslateBrowserTest, - public testing::WithParamInterface< - TranslateTestBridge::OverflowMenuItemId> {}; - -// Test that clicking and unclicking a never translate item ends up being a -// no-op. -IN_PROC_BROWSER_TEST_P(NeverTranslateMenuItemTranslateBrowserTest, - TranslateInfoBarToggleAndToggleBackNeverTranslateItem) { - auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents(); - auto* infobar_manager = - infobars::ContentInfoBarManager::FromWebContents(web_contents); - - SetTranslateScript(kTestValidScript); - - TranslateClientImpl* translate_client = GetTranslateClient(shell()); - - TestInfoBarManagerObserver infobar_observer; - infobar_manager->AddObserver(&infobar_observer); - - // Navigate to a page in French, wait for the infobar to be added, and click - // twice on the given overflow menu item. - { - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - ResetLanguageDeterminationWaiter(); - EXPECT_EQ(0u, infobar_manager->infobar_count()); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - run_loop.Run(); - - auto* infobar = - static_cast<TranslateCompactInfoBar*>(infobar_manager->infobar_at(0)); - TranslateTestBridge::ClickOverflowMenuItem(infobar, GetParam()); - - // The translate infobar should still be present. - EXPECT_EQ(1u, infobar_manager->infobar_count()); - - TranslateTestBridge::ClickOverflowMenuItem(infobar, GetParam()); - } - - // The infobar should be shown on a new navigation to a page in the same - // language. - { - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/french_page2.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("fr", translate_client->GetLanguageState().source_language()); - - run_loop.Run(); - } - - // The infobar should be shown on a new navigation to a page in a different - // language in the same site. - { - base::RunLoop run_loop; - infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure()); - - ResetLanguageDeterminationWaiter(); - NavigateAndWaitForCompletion( - GURL(embedded_test_server()->GetURL("/german_page.html")), shell()); - language_determination_waiter_->Wait(); - EXPECT_EQ("de", translate_client->GetLanguageState().source_language()); - - run_loop.Run(); - } - - infobar_manager->RemoveObserver(&infobar_observer); -} - -INSTANTIATE_TEST_SUITE_P( - All, - NeverTranslateMenuItemTranslateBrowserTest, - ::testing::Values( - TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_LANGUAGE, - TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_SITE)); - -} // namespace weblayer
diff --git a/weblayer/browser/translate_client_impl.cc b/weblayer/browser/translate_client_impl.cc deleted file mode 100644 index 3eec8b4..0000000 --- a/weblayer/browser/translate_client_impl.cc +++ /dev/null
@@ -1,187 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/translate_client_impl.h" - -#include <memory> -#include <vector> - -#include "build/build_config.h" -#include "components/infobars/core/infobar.h" -#include "components/language/core/browser/pref_names.h" -#include "components/translate/content/browser/content_translate_driver.h" -#include "components/translate/content/browser/content_translate_util.h" -#include "components/translate/core/browser/translate_manager.h" -#include "components/translate/core/browser/translate_prefs.h" -#include "components/variations/service/variations_service.h" -#include "content/public/common/url_constants.h" -#include "url/gurl.h" -#include "weblayer/browser/accept_languages_service_factory.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/feature_list_creator.h" -#include "weblayer/browser/navigation_controller_impl.h" -#include "weblayer/browser/page_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/browser/translate_ranker_factory.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/infobars/content/content_infobar_manager.h" -#include "weblayer/browser/translate_compact_infobar.h" -#endif - -namespace weblayer { - -namespace { - -std::unique_ptr<translate::TranslatePrefs> CreateTranslatePrefs( - PrefService* prefs) { - std::unique_ptr<translate::TranslatePrefs> translate_prefs( - new translate::TranslatePrefs(prefs)); - - // We need to obtain the country here, since it comes from VariationsService. - // components/ does not have access to that. - variations::VariationsService* variations_service = - FeatureListCreator::GetInstance()->variations_service(); - if (variations_service) { - translate_prefs->SetCountry( - variations_service->GetStoredPermanentCountry()); - } - - return translate_prefs; -} - -} // namespace - -TranslateClientImpl::TranslateClientImpl(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents), - content::WebContentsUserData<TranslateClientImpl>(*web_contents), - translate_driver_(*web_contents, - /*url_language_histogram=*/nullptr, - /*translate_model_service=*/nullptr), - translate_manager_(new translate::TranslateManager( - this, - TranslateRankerFactory::GetForBrowserContext( - web_contents->GetBrowserContext()), - /*language_model=*/nullptr)) { - observation_.Observe(&translate_driver_); - translate_driver_.set_translate_manager(translate_manager_.get()); -} - -TranslateClientImpl::~TranslateClientImpl() = default; - -const translate::LanguageState& TranslateClientImpl::GetLanguageState() { - return *translate_manager_->GetLanguageState(); -} - -bool TranslateClientImpl::ShowTranslateUI(translate::TranslateStep step, - const std::string& source_language, - const std::string& target_language, - translate::TranslateErrors error_type, - bool triggered_from_menu) { -#if BUILDFLAG(IS_ANDROID) - if (error_type != translate::TranslateErrors::NONE) - step = translate::TRANSLATE_STEP_TRANSLATE_ERROR; - translate::TranslateInfoBarDelegate::Create( - step != translate::TRANSLATE_STEP_BEFORE_TRANSLATE, - translate_manager_->GetWeakPtr(), - infobars::ContentInfoBarManager::FromWebContents(web_contents()), step, - source_language, target_language, error_type, triggered_from_menu); - return true; -#else - return false; -#endif -} - -translate::TranslateDriver* TranslateClientImpl::GetTranslateDriver() { - return &translate_driver_; -} - -translate::TranslateManager* TranslateClientImpl::GetTranslateManager() { - return translate_manager_.get(); -} - -PrefService* TranslateClientImpl::GetPrefs() { - BrowserContextImpl* browser_context = - static_cast<BrowserContextImpl*>(web_contents()->GetBrowserContext()); - return browser_context->pref_service(); -} - -std::unique_ptr<translate::TranslatePrefs> -TranslateClientImpl::GetTranslatePrefs() { - return CreateTranslatePrefs(GetPrefs()); -} - -language::AcceptLanguagesService* -TranslateClientImpl::GetAcceptLanguagesService() { - return AcceptLanguagesServiceFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); -} - -#if BUILDFLAG(IS_ANDROID) -std::unique_ptr<infobars::InfoBar> TranslateClientImpl::CreateInfoBar( - std::unique_ptr<translate::TranslateInfoBarDelegate> delegate) const { - return std::make_unique<TranslateCompactInfoBar>(std::move(delegate)); -} - -int TranslateClientImpl::GetInfobarIconID() const { - NOTREACHED(); - return 0; -} -#endif - -bool TranslateClientImpl::IsTranslatableURL(const GURL& url) { - return translate::IsTranslatableURL(url); -} - -void TranslateClientImpl::OnLanguageDetermined( - const translate::LanguageDetectionDetails& details) { - // Inform NavigationControllerImpl that the language has been determined. Note - // that this event is implicitly regarded as being for the Page corresponding - // to the most recently committed primary main-frame navigation, if one exists - // (see the call to SetPageLanguageInNavigation() in - // ContentTranslateDriver::RegisterPage()); this corresponds to - // WebContents::GetPrimaryMainFrame()::GetPage(). Note also that in certain - // corner cases (e.g., tab startup) there might not be such a committed - // primary main-frame navigation; in those cases there won't be a - // weblayer::Page corresponding to the primary page, as weblayer::Page objects - // are created only at navigation commit. - // TODO(crbug.com/1231889): Rearchitect translate's renderer-browser Mojo - // connection to be able to explicitly determine the document/content::Page - // with which this language determination event is associated. - PageImpl* page = - PageImpl::GetForPage(web_contents()->GetPrimaryMainFrame()->GetPage()); - if (page) { - std::string language = details.adopted_language; - - auto* tab = TabImpl::FromWebContents(web_contents()); - auto* navigation_controller = - static_cast<NavigationControllerImpl*>(tab->GetNavigationController()); - navigation_controller->OnPageLanguageDetermined(page, language); - } - - // Show translate UI if desired. - if (show_translate_ui_on_ready_) { - GetTranslateManager()->ShowTranslateUI(); - show_translate_ui_on_ready_ = false; - } -} - -void TranslateClientImpl::ShowTranslateUiWhenReady() { - if (GetLanguageState().source_language().empty()) { - show_translate_ui_on_ready_ = true; - } else { - GetTranslateManager()->ShowTranslateUI(); - } -} - -void TranslateClientImpl::WebContentsDestroyed() { - // Translation process can be interrupted. - // Destroying the TranslateManager now guarantees that it never has to deal - // with web_contents() being null. - translate_manager_.reset(); -} - -} // namespace weblayer - -WEB_CONTENTS_USER_DATA_KEY_IMPL(weblayer::TranslateClientImpl);
diff --git a/weblayer/browser/translate_client_impl.h b/weblayer/browser/translate_client_impl.h deleted file mode 100644 index e83ec70d..0000000 --- a/weblayer/browser/translate_client_impl.h +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TRANSLATE_CLIENT_IMPL_H_ -#define WEBLAYER_BROWSER_TRANSLATE_CLIENT_IMPL_H_ - -#include <memory> -#include <string> - -#include "base/scoped_observation.h" -#include "build/build_config.h" -#include "components/translate/content/browser/content_translate_driver.h" -#include "components/translate/core/browser/translate_client.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace content { -class WebContents; -} // namespace content - -namespace translate { -class LanguageState; -class TranslateManager; -} // namespace translate - -namespace weblayer { - -class TranslateClientImpl - : public translate::TranslateClient, - public translate::TranslateDriver::LanguageDetectionObserver, - public content::WebContentsObserver, - public content::WebContentsUserData<TranslateClientImpl> { - public: - TranslateClientImpl(const TranslateClientImpl&) = delete; - TranslateClientImpl& operator=(const TranslateClientImpl&) = delete; - - ~TranslateClientImpl() override; - - // Gets the LanguageState associated with the page. - const translate::LanguageState& GetLanguageState(); - - // Returns the ContentTranslateDriver instance associated with this - // WebContents. - translate::ContentTranslateDriver* translate_driver() { - return &translate_driver_; - } - - // Gets the associated TranslateManager. - translate::TranslateManager* GetTranslateManager(); - - // TranslateClient implementation. - translate::TranslateDriver* GetTranslateDriver() override; - PrefService* GetPrefs() override; - std::unique_ptr<translate::TranslatePrefs> GetTranslatePrefs() override; - language::AcceptLanguagesService* GetAcceptLanguagesService() override; -#if BUILDFLAG(IS_ANDROID) - std::unique_ptr<infobars::InfoBar> CreateInfoBar( - std::unique_ptr<translate::TranslateInfoBarDelegate> delegate) - const override; - int GetInfobarIconID() const override; -#endif - bool ShowTranslateUI(translate::TranslateStep step, - const std::string& source_language, - const std::string& target_language, - translate::TranslateErrors error_type, - bool triggered_from_menu) override; - bool IsTranslatableURL(const GURL& url) override; - - // TranslateDriver::LanguageDetectionObserver implementation. - void OnLanguageDetermined( - const translate::LanguageDetectionDetails& details) override; - - // Show the translation UI when the necessary state (e.g. source language) is - // ready. - void ShowTranslateUiWhenReady(); - - private: - explicit TranslateClientImpl(content::WebContents* web_contents); - friend class content::WebContentsUserData<TranslateClientImpl>; - - // content::WebContentsObserver implementation. - void WebContentsDestroyed() override; - - translate::ContentTranslateDriver translate_driver_; - std::unique_ptr<translate::TranslateManager> translate_manager_; - - // Whether to show translation UI when ready. - bool show_translate_ui_on_ready_ = false; - - base::ScopedObservation<translate::TranslateDriver, - translate::TranslateDriver::LanguageDetectionObserver> - observation_{this}; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TRANSLATE_CLIENT_IMPL_H_
diff --git a/weblayer/browser/translate_compact_infobar.cc b/weblayer/browser/translate_compact_infobar.cc deleted file mode 100644 index c9d00cb..0000000 --- a/weblayer/browser/translate_compact_infobar.cc +++ /dev/null
@@ -1,242 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/translate_compact_infobar.h" - -#include <stddef.h> - -#include <memory> - -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "base/android/jni_weak_ref.h" -#include "base/functional/bind.h" -#include "base/metrics/field_trial_params.h" -#include "base/types/cxx23_to_underlying.h" -#include "components/infobars/content/content_infobar_manager.h" -#include "components/translate/content/android/translate_utils.h" -#include "components/translate/core/browser/translate_infobar_delegate.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/java/jni/TranslateCompactInfoBar_jni.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/browser/translate_client_impl.h" - -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -// Finch parameter names: -const char kTranslateTabDefaultTextColor[] = "translate_tab_default_text_color"; - -// TranslateInfoBar ----------------------------------------------------------- - -TranslateCompactInfoBar::TranslateCompactInfoBar( - std::unique_ptr<translate::TranslateInfoBarDelegate> delegate) - : infobars::InfoBarAndroid(std::move(delegate)), action_flags_(FLAG_NONE) { - GetDelegate()->AddObserver(this); - - // Flip the translate bit if auto translate is enabled. - if (GetDelegate()->translate_step() == translate::TRANSLATE_STEP_TRANSLATING) - action_flags_ |= FLAG_TRANSLATE; -} - -TranslateCompactInfoBar::~TranslateCompactInfoBar() { - GetDelegate()->RemoveObserver(this); -} - -ScopedJavaLocalRef<jobject> TranslateCompactInfoBar::CreateRenderInfoBar( - JNIEnv* env, - const ResourceIdMapper& resource_id_mapper) { - translate::TranslateInfoBarDelegate* delegate = GetDelegate(); - - translate::JavaLanguageInfoWrapper translate_languages = - translate::TranslateUtils::GetTranslateLanguagesInJavaFormat(env, - delegate); - - ScopedJavaLocalRef<jstring> source_language_code = - base::android::ConvertUTF8ToJavaString(env, - delegate->source_language_code()); - - ScopedJavaLocalRef<jstring> target_language_code = - base::android::ConvertUTF8ToJavaString(env, - delegate->target_language_code()); - content::WebContents* web_contents = - infobars::ContentInfoBarManager::WebContentsFromInfoBar(this); - - TabImpl* tab = - web_contents ? TabImpl::FromWebContents(web_contents) : nullptr; - - return Java_TranslateCompactInfoBar_create( - env, tab ? tab->GetJavaTab() : nullptr, delegate->translate_step(), - source_language_code, target_language_code, - delegate->ShouldNeverTranslateLanguage(), - delegate->IsSiteOnNeverPromptList(), delegate->ShouldAlwaysTranslate(), - delegate->triggered_from_menu(), translate_languages.java_languages, - translate_languages.java_codes, translate_languages.java_hash_codes, - TabDefaultTextColor()); -} - -void TranslateCompactInfoBar::ProcessButton(int action) { - if (!owner()) - return; // We're closing; don't call anything, it might access the owner. - - translate::TranslateInfoBarDelegate* delegate = GetDelegate(); - if (action == infobars::InfoBarAndroid::ACTION_TRANSLATE) { - action_flags_ |= FLAG_TRANSLATE; - delegate->Translate(); - if (delegate->ShouldAutoAlwaysTranslate()) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_TranslateCompactInfoBar_setAutoAlwaysTranslate(env, - GetJavaInfoBar()); - } - } else if (action == - infobars::InfoBarAndroid::ACTION_TRANSLATE_SHOW_ORIGINAL) { - action_flags_ |= FLAG_REVERT; - delegate->RevertWithoutClosingInfobar(); - } else { - DCHECK_EQ(infobars::InfoBarAndroid::ACTION_NONE, action); - } -} - -void TranslateCompactInfoBar::SetJavaInfoBar( - const base::android::JavaRef<jobject>& java_info_bar) { - infobars::InfoBarAndroid::SetJavaInfoBar(java_info_bar); - JNIEnv* env = base::android::AttachCurrentThread(); - Java_TranslateCompactInfoBar_setNativePtr(env, java_info_bar, - reinterpret_cast<intptr_t>(this)); -} - -void TranslateCompactInfoBar::ApplyStringTranslateOption( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - int option, - const JavaParamRef<jstring>& value) { - translate::TranslateInfoBarDelegate* delegate = GetDelegate(); - if (option == translate::TranslateUtils::OPTION_SOURCE_CODE) { - std::string source_code = - base::android::ConvertJavaStringToUTF8(env, value); - delegate->UpdateSourceLanguage(source_code); - } else if (option == translate::TranslateUtils::OPTION_TARGET_CODE) { - std::string target_code = - base::android::ConvertJavaStringToUTF8(env, value); - delegate->UpdateTargetLanguage(target_code); - } else { - DCHECK(false); - } -} - -void TranslateCompactInfoBar::ApplyBoolTranslateOption( - JNIEnv* env, - const JavaParamRef<jobject>& obj, - int option, - jboolean value) { - translate::TranslateInfoBarDelegate* delegate = GetDelegate(); - if (option == translate::TranslateUtils::OPTION_ALWAYS_TRANSLATE) { - if (delegate->ShouldAlwaysTranslate() != value) { - action_flags_ |= FLAG_ALWAYS_TRANSLATE; - delegate->ToggleAlwaysTranslate(); - } - } else if (option == translate::TranslateUtils::OPTION_NEVER_TRANSLATE) { - bool language_blocklisted = !delegate->IsTranslatableLanguageByPrefs(); - if (language_blocklisted != value) { - delegate->RevertWithoutClosingInfobar(); - action_flags_ |= FLAG_NEVER_LANGUAGE; - delegate->ToggleTranslatableLanguageByPrefs(); - } - } else if (option == translate::TranslateUtils::OPTION_NEVER_TRANSLATE_SITE) { - if (delegate->IsSiteOnNeverPromptList() != value) { - delegate->RevertWithoutClosingInfobar(); - action_flags_ |= FLAG_NEVER_SITE; - delegate->ToggleNeverPromptSite(); - } - } else { - DCHECK(false); - } -} - -jboolean TranslateCompactInfoBar::ShouldAutoNeverTranslate( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jboolean menu_expanded) { - // Flip menu expanded bit. - if (menu_expanded) - action_flags_ |= FLAG_EXPAND_MENU; - - if (!IsDeclinedByUser()) - return false; - - return GetDelegate()->ShouldAutoNeverTranslate(); -} - -// Returns true if the current tab is an incognito tab. -jboolean TranslateCompactInfoBar::IsIncognito( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj) { - content::WebContents* web_contents = - infobars::ContentInfoBarManager::WebContentsFromInfoBar(this); - if (!web_contents) - return false; - return web_contents->GetBrowserContext()->IsOffTheRecord(); -} - -int TranslateCompactInfoBar::GetParam(const std::string& paramName, - int default_value) { - std::map<std::string, std::string> params; - if (!base::GetFieldTrialParams(translate::kTranslateCompactUI.name, - ¶ms)) { - return default_value; - } - int value = 0; - base::StringToInt(params[paramName], &value); - return value <= 0 ? default_value : value; -} - -int TranslateCompactInfoBar::TabDefaultTextColor() { - return GetParam(kTranslateTabDefaultTextColor, 0); -} - -translate::TranslateInfoBarDelegate* TranslateCompactInfoBar::GetDelegate() { - return delegate()->AsTranslateInfoBarDelegate(); -} - -void TranslateCompactInfoBar::OnTranslateStepChanged( - translate::TranslateStep step, - translate::TranslateErrors error_type) { - // If the tab lost active state while translation was occurring, the Java - // infobar will now be gone. In that case there is nothing to do here. - if (!HasSetJavaInfoBar()) - return; // No connected Java infobar - - if (!owner()) - return; // We're closing; don't call anything. - - if ((step == translate::TRANSLATE_STEP_AFTER_TRANSLATE) || - (step == translate::TRANSLATE_STEP_TRANSLATE_ERROR)) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_TranslateCompactInfoBar_onPageTranslated( - env, GetJavaInfoBar(), base::to_underlying(error_type)); - } -} - -void TranslateCompactInfoBar::OnTargetLanguageChanged( - const std::string& target_language_code) { - // In WebLayer, target language changes are only initiated by the UI. This - // method should always be a no-op. - DCHECK_EQ(GetDelegate()->target_language_code(), target_language_code); -} - -bool TranslateCompactInfoBar::IsDeclinedByUser() { - // Whether there is any affirmative action bit. - return action_flags_ == FLAG_NONE; -} - -void TranslateCompactInfoBar::OnTranslateInfoBarDelegateDestroyed( - translate::TranslateInfoBarDelegate* delegate) { - DCHECK_EQ(GetDelegate(), delegate); - GetDelegate()->RemoveObserver(this); -} - -} // namespace weblayer
diff --git a/weblayer/browser/translate_compact_infobar.h b/weblayer/browser/translate_compact_infobar.h deleted file mode 100644 index 2dcee94ce..0000000 --- a/weblayer/browser/translate_compact_infobar.h +++ /dev/null
@@ -1,103 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TRANSLATE_COMPACT_INFOBAR_H_ -#define WEBLAYER_BROWSER_TRANSLATE_COMPACT_INFOBAR_H_ - -#include "base/android/scoped_java_ref.h" -#include "components/infobars/android/infobar_android.h" -#include "components/translate/core/browser/translate_infobar_delegate.h" -#include "components/translate/core/browser/translate_step.h" -#include "components/translate/core/common/translate_errors.h" - -namespace translate { -class TranslateInfoBarDelegate; -} - -namespace weblayer { - -class TranslateCompactInfoBar - : public infobars::InfoBarAndroid, - public translate::TranslateInfoBarDelegate::Observer { - public: - explicit TranslateCompactInfoBar( - std::unique_ptr<translate::TranslateInfoBarDelegate> delegate); - - TranslateCompactInfoBar(const TranslateCompactInfoBar&) = delete; - TranslateCompactInfoBar& operator=(const TranslateCompactInfoBar&) = delete; - - ~TranslateCompactInfoBar() override; - - // JNI method specific to string settings in translate. - void ApplyStringTranslateOption( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - int option, - const base::android::JavaParamRef<jstring>& value); - - // JNI method specific to boolean settings in translate. - void ApplyBoolTranslateOption(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - int option, - jboolean value); - - // Check whether we should automatically trigger "Never Translate Language". - jboolean ShouldAutoNeverTranslate( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jboolean menu_expanded); - - // Returns true if the current tab is an incognito tab. - jboolean IsIncognito(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj); - - // TranslateInfoBarDelegate::Observer implementation. - void OnTranslateStepChanged(translate::TranslateStep step, - translate::TranslateErrors error_type) override; - void OnTargetLanguageChanged( - const std::string& target_language_code) override; - // Returns true if the user didn't take any affirmative action. - // The function will be called when the translate infobar is dismissed. - // If it's true, we will record a declined event. - bool IsDeclinedByUser() override; - void OnTranslateInfoBarDelegateDestroyed( - translate::TranslateInfoBarDelegate* delegate) override; - - private: - // infobars::InfoBarAndroid: - base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( - JNIEnv* env, - const ResourceIdMapper& resource_id_mapper) override; - void ProcessButton(int action) override; - void SetJavaInfoBar( - const base::android::JavaRef<jobject>& java_info_bar) override; - - // Get the value of a specified finch parameter in TranslateCompactUI. If the - // finch parameter does not exist, default_value will be returned. - int GetParam(const std::string& paramName, int default_value); - // Get the value of the finch parameter: translate_tab_default_text_color. - // Default value is 0, which means using TabLayout default color. - // If it's not 0, we will set the text color manually based on the value. - int TabDefaultTextColor(); - - translate::TranslateInfoBarDelegate* GetDelegate(); - - // Bits for trace user's affirmative actions. - unsigned int action_flags_; - - // Affirmative action flags to record what the user has done in one session. - enum ActionFlag { - FLAG_NONE = 0, - FLAG_TRANSLATE = 1 << 0, - FLAG_REVERT = 1 << 1, - FLAG_ALWAYS_TRANSLATE = 1 << 2, - FLAG_NEVER_LANGUAGE = 1 << 3, - FLAG_NEVER_SITE = 1 << 4, - FLAG_EXPAND_MENU = 1 << 5, - }; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TRANSLATE_COMPACT_INFOBAR_H_
diff --git a/weblayer/browser/translate_ranker_factory.cc b/weblayer/browser/translate_ranker_factory.cc deleted file mode 100644 index 5935fb53..0000000 --- a/weblayer/browser/translate_ranker_factory.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/translate_ranker_factory.h" - -#include "base/files/file_path.h" -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/translate/core/browser/translate_ranker_impl.h" -#include "content/public/browser/browser_context.h" -#include "services/metrics/public/cpp/ukm_recorder.h" - -namespace weblayer { - -// static -translate::TranslateRanker* TranslateRankerFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<translate::TranslateRanker*>( - GetInstance()->GetServiceForBrowserContext(browser_context, true)); -} - -// static -TranslateRankerFactory* TranslateRankerFactory::GetInstance() { - static base::NoDestructor<TranslateRankerFactory> factory; - return factory.get(); -} - -TranslateRankerFactory::TranslateRankerFactory() - : BrowserContextKeyedServiceFactory( - "TranslateRanker", - BrowserContextDependencyManager::GetInstance()) {} - -TranslateRankerFactory::~TranslateRankerFactory() = default; - -std::unique_ptr<KeyedService> -TranslateRankerFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* browser_context) const { - return std::make_unique<translate::TranslateRankerImpl>( - translate::TranslateRankerImpl::GetModelPath(browser_context->GetPath()), - translate::TranslateRankerImpl::GetModelURL(), ukm::UkmRecorder::Get()); -} - -content::BrowserContext* TranslateRankerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/translate_ranker_factory.h b/weblayer/browser/translate_ranker_factory.h deleted file mode 100644 index c3eebe3..0000000 --- a/weblayer/browser/translate_ranker_factory.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TRANSLATE_RANKER_FACTORY_H_ -#define WEBLAYER_BROWSER_TRANSLATE_RANKER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace content { -class BrowserContext; -} - -namespace translate { -class TranslateRanker; -} - -namespace weblayer { - -// TranslateRankerFactory is a way to associate a TranslateRanker instance to a -// BrowserContext. -class TranslateRankerFactory : public BrowserContextKeyedServiceFactory { - public: - TranslateRankerFactory(const TranslateRankerFactory&) = delete; - TranslateRankerFactory& operator=(const TranslateRankerFactory&) = delete; - - static TranslateRankerFactory* GetInstance(); - static translate::TranslateRanker* GetForBrowserContext( - content::BrowserContext* browser_context); - - private: - friend class base::NoDestructor<TranslateRankerFactory>; - - TranslateRankerFactory(); - ~TranslateRankerFactory() override; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - - // Note: In //chrome, when the service is requested for a - // Profile in incognito mode the factory supplies the associated original - // Profile. However, WebLayer doesn't have a concept of incognito profiles - // being associated with regular profiles, so the service gets its own - // instance in incognito mode. - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TRANSLATE_RANKER_FACTORY_H_
diff --git a/weblayer/browser/tts_environment_android_impl.cc b/weblayer/browser/tts_environment_android_impl.cc deleted file mode 100644 index df9d8ff..0000000 --- a/weblayer/browser/tts_environment_android_impl.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/tts_environment_android_impl.h" - -#include "base/functional/callback.h" - -namespace weblayer { - -TtsEnvironmentAndroidImpl::TtsEnvironmentAndroidImpl() = default; - -TtsEnvironmentAndroidImpl::~TtsEnvironmentAndroidImpl() = default; - -bool TtsEnvironmentAndroidImpl::CanSpeakUtterancesFromHiddenWebContents() { - // For simplicity's sake, disallow playing utterances in hidden WebContents. - // Other options are to allow this, and instead cancel any utterances when - // all browsers are paused. - return false; -} - -bool TtsEnvironmentAndroidImpl::CanSpeakNow() { - // Always return true, as by the time we get here we know the WebContents - // is visible (because CanSpeakUtterancesFromHiddenWebContents() returns - // false). Further, when the fragment is paused/stopped the WebContents is - // hidden, which triggers the utterance to stop (because - // CanSpeakUtterancesFromHiddenWebContents() returns false). - return true; -} - -void TtsEnvironmentAndroidImpl::SetCanSpeakNowChangedCallback( - base::RepeatingClosure callback) { - // As CanSpeakNow() always returns true, there is nothing to do here. -} - -} // namespace weblayer
diff --git a/weblayer/browser/tts_environment_android_impl.h b/weblayer/browser/tts_environment_android_impl.h deleted file mode 100644 index 244339b..0000000 --- a/weblayer/browser/tts_environment_android_impl.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TTS_ENVIRONMENT_ANDROID_IMPL_H_ -#define WEBLAYER_BROWSER_TTS_ENVIRONMENT_ANDROID_IMPL_H_ - -#include "content/public/browser/tts_environment_android.h" - -namespace weblayer { - -// WebLayer implementation of TtsEnvironmentAndroid. This does not allow -// speech from hidden WebContents. -class TtsEnvironmentAndroidImpl : public content::TtsEnvironmentAndroid { - public: - TtsEnvironmentAndroidImpl(); - TtsEnvironmentAndroidImpl(const TtsEnvironmentAndroidImpl&) = delete; - TtsEnvironmentAndroidImpl& operator=(const TtsEnvironmentAndroidImpl&) = - delete; - ~TtsEnvironmentAndroidImpl() override; - - // TtsEnvironment: - bool CanSpeakUtterancesFromHiddenWebContents() override; - bool CanSpeakNow() override; - void SetCanSpeakNowChangedCallback(base::RepeatingClosure callback) override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TTS_ENVIRONMENT_ANDROID_IMPL_H_
diff --git a/weblayer/browser/verdict_cache_manager_factory.cc b/weblayer/browser/verdict_cache_manager_factory.cc deleted file mode 100644 index 14442cab..0000000 --- a/weblayer/browser/verdict_cache_manager_factory.cc +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/verdict_cache_manager_factory.h" - -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/safe_browsing/core/browser/verdict_cache_manager.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/host_content_settings_map_factory.h" - -namespace weblayer { - -// static -safe_browsing::VerdictCacheManager* -VerdictCacheManagerFactory::GetForBrowserContext( - content::BrowserContext* browser_context) { - return static_cast<safe_browsing::VerdictCacheManager*>( - GetInstance()->GetServiceForBrowserContext(browser_context, - /* create= */ true)); -} - -// static -VerdictCacheManagerFactory* VerdictCacheManagerFactory::GetInstance() { - return base::Singleton<VerdictCacheManagerFactory>::get(); -} - -VerdictCacheManagerFactory::VerdictCacheManagerFactory() - : BrowserContextKeyedServiceFactory( - "VerdictCacheManager", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -std::unique_ptr<KeyedService> -VerdictCacheManagerFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - BrowserContextImpl* context_impl = static_cast<BrowserContextImpl*>(context); - return std::make_unique<safe_browsing::VerdictCacheManager>( - /*history_service=*/nullptr, - HostContentSettingsMapFactory::GetForBrowserContext(context), - context_impl->pref_service(), /*sync_observer=*/nullptr); -} - -} // namespace weblayer
diff --git a/weblayer/browser/verdict_cache_manager_factory.h b/weblayer/browser/verdict_cache_manager_factory.h deleted file mode 100644 index 153db13..0000000 --- a/weblayer/browser/verdict_cache_manager_factory.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_VERDICT_CACHE_MANAGER_FACTORY_H_ -#define WEBLAYER_BROWSER_VERDICT_CACHE_MANAGER_FACTORY_H_ - -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class KeyedService; - -namespace content { -class BrowserContext; -} - -namespace safe_browsing { -class VerdictCacheManager; -} - -namespace weblayer { - -// Singleton that owns VerdictCacheManager objects and associates them -// them with BrowserContextImpl instances. -class VerdictCacheManagerFactory : public BrowserContextKeyedServiceFactory { - public: - // Creates the manager if it doesn't exist already for the given - // |browser_context|. If the manager already exists, return its pointer. - static safe_browsing::VerdictCacheManager* GetForBrowserContext( - content::BrowserContext* browser_context); - - // Get the singleton instance. - static VerdictCacheManagerFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<VerdictCacheManagerFactory>; - - VerdictCacheManagerFactory(); - ~VerdictCacheManagerFactory() override = default; - VerdictCacheManagerFactory(const VerdictCacheManagerFactory&) = delete; - VerdictCacheManagerFactory& operator=(const VerdictCacheManagerFactory&) = - delete; - - // BrowserContextKeyedServiceFactory: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_VERDICT_CACHE_MANAGER_FACTORY_H_
diff --git a/weblayer/browser/web_contents_view_delegate_impl.cc b/weblayer/browser/web_contents_view_delegate_impl.cc deleted file mode 100644 index 8ffe087c..0000000 --- a/weblayer/browser/web_contents_view_delegate_impl.cc +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/web_contents_view_delegate_impl.h" - -#include <memory> - -#include "weblayer/browser/tab_impl.h" - -namespace weblayer { - -WebContentsViewDelegateImpl::WebContentsViewDelegateImpl( - content::WebContents* web_contents) - : web_contents_(web_contents) {} - -WebContentsViewDelegateImpl::~WebContentsViewDelegateImpl() = default; - -void WebContentsViewDelegateImpl::ShowContextMenu( - content::RenderFrameHost& render_frame_host, - const content::ContextMenuParams& params) { - TabImpl* tab = TabImpl::FromWebContents(web_contents_); - if (tab) - tab->ShowContextMenu(params); -} - -std::unique_ptr<content::WebContentsViewDelegate> CreateWebContentsViewDelegate( - content::WebContents* web_contents) { - return std::make_unique<WebContentsViewDelegateImpl>(web_contents); -} - -} // namespace weblayer
diff --git a/weblayer/browser/web_contents_view_delegate_impl.h b/weblayer/browser/web_contents_view_delegate_impl.h deleted file mode 100644 index 487dc89..0000000 --- a/weblayer/browser/web_contents_view_delegate_impl.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEB_CONTENTS_VIEW_DELEGATE_IMPL_H_ -#define WEBLAYER_BROWSER_WEB_CONTENTS_VIEW_DELEGATE_IMPL_H_ - -#include "base/memory/raw_ptr.h" -#include "content/public/browser/web_contents_view_delegate.h" - -namespace content { -class WebContents; -} - -namespace weblayer { - -class WebContentsViewDelegateImpl : public content::WebContentsViewDelegate { - public: - explicit WebContentsViewDelegateImpl(content::WebContents* web_contents); - - WebContentsViewDelegateImpl(const WebContentsViewDelegateImpl&) = delete; - WebContentsViewDelegateImpl& operator=(const WebContentsViewDelegateImpl&) = - delete; - - ~WebContentsViewDelegateImpl() override; - - // WebContentsViewDelegate overrides. - void ShowContextMenu(content::RenderFrameHost& render_frame_host, - const content::ContextMenuParams& params) override; - - private: - raw_ptr<content::WebContents> web_contents_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEB_CONTENTS_VIEW_DELEGATE_IMPL_H_
diff --git a/weblayer/browser/web_data_service_factory.cc b/weblayer/browser/web_data_service_factory.cc deleted file mode 100644 index 5fbe435..0000000 --- a/weblayer/browser/web_data_service_factory.cc +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/web_data_service_factory.h" - -#include "base/files/file_path.h" -#include "base/functional/bind.h" -#include "base/no_destructor.h" -#include "base/notreached.h" -#include "components/webdata_services/web_data_service_wrapper.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "weblayer/browser/i18n_util.h" - -namespace weblayer { - -namespace { - -// Callback to show error dialog on profile load error. -void ProfileErrorCallback(WebDataServiceWrapper::ErrorType error_type, - sql::InitStatus status, - const std::string& diagnostics) { - NOTIMPLEMENTED(); -} - -} // namespace - -WebDataServiceFactory::WebDataServiceFactory() = default; - -WebDataServiceFactory::~WebDataServiceFactory() = default; - -// static -WebDataServiceFactory* WebDataServiceFactory::GetInstance() { - static base::NoDestructor<WebDataServiceFactory> instance; - return instance.get(); -} - -content::BrowserContext* WebDataServiceFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -std::unique_ptr<KeyedService> -WebDataServiceFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - const base::FilePath& profile_path = context->GetPath(); - return std::make_unique<WebDataServiceWrapper>( - profile_path, i18n::GetApplicationLocale(), - content::GetUIThreadTaskRunner({}), - base::BindRepeating(&ProfileErrorCallback)); -} - -bool WebDataServiceFactory::ServiceIsNULLWhileTesting() const { - return true; -} - -} // namespace weblayer
diff --git a/weblayer/browser/web_data_service_factory.h b/weblayer/browser/web_data_service_factory.h deleted file mode 100644 index e4133cd..0000000 --- a/weblayer/browser/web_data_service_factory.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEB_DATA_SERVICE_FACTORY_H_ -#define WEBLAYER_BROWSER_WEB_DATA_SERVICE_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/webdata_services/web_data_service_wrapper_factory.h" - -namespace weblayer { - -// Singleton that owns all WebDataServiceWrappers and associates them with -// Profiles. -class WebDataServiceFactory - : public webdata_services::WebDataServiceWrapperFactory { - public: - WebDataServiceFactory(const WebDataServiceFactory&) = delete; - WebDataServiceFactory& operator=(const WebDataServiceFactory&) = delete; - - static WebDataServiceFactory* GetInstance(); - - private: - friend class base::NoDestructor<WebDataServiceFactory>; - - WebDataServiceFactory(); - ~WebDataServiceFactory() override; - - // |BrowserContextKeyedServiceFactory| methods: - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; - bool ServiceIsNULLWhileTesting() const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEB_DATA_SERVICE_FACTORY_H_
diff --git a/weblayer/browser/webapps/webapk_install_scheduler.cc b/weblayer/browser/webapps/webapk_install_scheduler.cc deleted file mode 100644 index 09a8c3a..0000000 --- a/weblayer/browser/webapps/webapk_install_scheduler.cc +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webapps/webapk_install_scheduler.h" - -#include <utility> - -#include "base/functional/bind.h" -#include "base/task/thread_pool.h" -#include "components/webapps/browser/android/shortcut_info.h" -#include "components/webapps/browser/android/webapk/webapk_icon_hasher.h" -#include "components/webapps/browser/android/webapk/webapk_proto_builder.h" -#include "components/webapps/browser/android/webapk/webapk_types.h" -#include "components/webapps/browser/android/webapps_utils.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_contents.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "url/gurl.h" -#include "weblayer/browser/webapps/webapk_install_scheduler_bridge.h" - -namespace weblayer { - -WebApkInstallScheduler::WebApkInstallScheduler( - const webapps::ShortcutInfo& shortcut_info, - const SkBitmap& primary_icon, - WebApkInstallFinishedCallback callback) - : webapps_client_callback_(std::move(callback)), - primary_icon_(primary_icon) { - shortcut_info_ = std::make_unique<webapps::ShortcutInfo>(shortcut_info); -} - -WebApkInstallScheduler::~WebApkInstallScheduler() = default; - -// static -void WebApkInstallScheduler::FetchProtoAndScheduleInstall( - content::WebContents* web_contents, - const webapps::ShortcutInfo& shortcut_info, - const SkBitmap& primary_icon, - WebApkInstallFinishedCallback callback) { - // Self owned WebApkInstallScheduler that destroys itself as soon as its - // OnResult function is called when the scheduled installation failed or - // finished. - WebApkInstallScheduler* scheduler = new WebApkInstallScheduler( - shortcut_info, primary_icon, std::move(callback)); - scheduler->FetchMurmur2Hashes(web_contents); -} - -void WebApkInstallScheduler::FetchProtoAndScheduleInstallForTesting( - content::WebContents* web_contents) { - FetchMurmur2Hashes(web_contents); -} - -void WebApkInstallScheduler::FetchMurmur2Hashes( - content::WebContents* web_contents) { - // We need to take the hash of the bitmap at the icon URL prior to any - // transformations being applied to the bitmap (such as encoding/decoding - // the bitmap). The icon hash is used to determine whether the icon that - // the user sees matches the icon of a WebAPK that the WebAPK server - // generated for another user. (The icon can be dynamically generated.) - // - // We redownload the icon in order to take the Murmur2 hash. The redownload - // should be fast because the icon should be in the HTTP cache. - std::vector<webapps::WebappIcon> icons = shortcut_info_->GetWebApkIcons(); - - webapps::WebApkIconHasher::DownloadAndComputeMurmur2Hash( - web_contents->GetBrowserContext() - ->GetDefaultStoragePartition() - ->GetURLLoaderFactoryForBrowserProcess() - .get(), - web_contents->GetWeakPtr(), url::Origin::Create(shortcut_info_->url), - icons, - base::BindOnce(&WebApkInstallScheduler::OnGotIconMurmur2HashesBuildProto, - weak_ptr_factory_.GetWeakPtr())); -} - -void WebApkInstallScheduler::OnGotIconMurmur2HashesBuildProto( - absl::optional<std::map<std::string, webapps::WebApkIconHasher::Icon>> - hashes) { - if (!hashes) { - OnResult(webapps::WebApkInstallResult::ICON_HASHER_ERROR); - return; - } - - webapps::BuildProto( - *shortcut_info_.get(), shortcut_info_->manifest_id, - std::string() /* primary_icon_data */, - std::string() /* splash_icon_data */, "" /* package_name */, - "" /* version */, std::move(*hashes), false /* is_manifest_stale */, - false /* is_app_identity_update_supported */, - base::BindOnce(&WebApkInstallScheduler::ScheduleWithChrome, - weak_ptr_factory_.GetWeakPtr())); -} - -void WebApkInstallScheduler::ScheduleWithChrome( - std::unique_ptr<std::string> serialized_proto) { - WebApkInstallSchedulerBridge::ScheduleWebApkInstallWithChrome( - std::move(serialized_proto), primary_icon_, - shortcut_info_->is_primary_icon_maskable, - base::BindOnce(&WebApkInstallScheduler::OnResult, - weak_ptr_factory_.GetWeakPtr())); -} - -void WebApkInstallScheduler::OnResult(webapps::WebApkInstallResult result) { - // Toasts have to be called on the UI thread, but the - // WebApkInstallSchedulerClient already makes sure that the callback, which is - // triggered by the Chrome-service, is invoked on the UI thread. - webapps::WebappsUtils::ShowWebApkInstallResultToast(result); - - std::move(webapps_client_callback_).Run(shortcut_info_->manifest_id); - delete this; -} - -// static -bool WebApkInstallScheduler::IsInstallServiceAvailable() { - return WebApkInstallSchedulerBridge::IsInstallServiceAvailable(); -} - -} // namespace weblayer
diff --git a/weblayer/browser/webapps/webapk_install_scheduler.h b/weblayer/browser/webapps/webapk_install_scheduler.h deleted file mode 100644 index e6ad388..0000000 --- a/weblayer/browser/webapps/webapk_install_scheduler.h +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_H_ -#define WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_H_ - -#include <memory> - -#include "base/functional/callback.h" -#include "base/memory/weak_ptr.h" -#include "components/webapps/browser/android/webapk/webapk_icon_hasher.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "weblayer/browser/webapps/weblayer_webapps_client.h" - -namespace content { -class WebContents; -} // namespace content - -namespace webapps { -struct ShortcutInfo; -enum class WebApkInstallResult; -} // namespace webapps - -namespace weblayer { - -class WebApkInstallSchedulerBridge; - -// Class that schedules the WebAPK installation via the Chrome -// WebApkInstallCoordinatorService. Creates a self-owned -// WebApkInstallSchedulerBridge instance when building the proto is complete. -// |finish_callback| is called once the install completed or failed. -class WebApkInstallScheduler { - public: - // Called when the scheduling of an WebAPK-installation with the Chrome - // service finished or failed. - using FinishCallback = base::OnceCallback<void(webapps::WebApkInstallResult)>; - - virtual ~WebApkInstallScheduler(); - using WebApkInstallFinishedCallback = - weblayer::WebLayerWebappsClient::WebApkInstallFinishedCallback; - - WebApkInstallScheduler(const WebApkInstallScheduler&) = delete; - WebApkInstallScheduler& operator=(const WebApkInstallScheduler&) = delete; - - static void FetchProtoAndScheduleInstall( - content::WebContents* web_contents, - const webapps::ShortcutInfo& shortcut_info, - const SkBitmap& primary_icon, - WebApkInstallFinishedCallback callback); - - void FetchProtoAndScheduleInstallForTesting( - content::WebContents* web_contents); - - static bool IsInstallServiceAvailable(); - - private: - WebApkInstallScheduler(const webapps::ShortcutInfo& shortcut_info, - const SkBitmap& primary_icon, - WebApkInstallFinishedCallback callback); - - friend class TestWebApkInstallScheduler; - - void FetchMurmur2Hashes(content::WebContents* web_contents); - - void OnGotIconMurmur2HashesBuildProto( - absl::optional<std::map<std::string, webapps::WebApkIconHasher::Icon>> - hashes); - - virtual void ScheduleWithChrome( - std::unique_ptr<std::string> serialized_proto); - - virtual void OnResult(webapps::WebApkInstallResult result); - - WebApkInstallFinishedCallback webapps_client_callback_; - std::unique_ptr<webapps::ShortcutInfo> shortcut_info_; - const SkBitmap primary_icon_; - - // Used to get |weak_ptr_|. - base::WeakPtrFactory<WebApkInstallScheduler> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_H_
diff --git a/weblayer/browser/webapps/webapk_install_scheduler_bridge.cc b/weblayer/browser/webapps/webapk_install_scheduler_bridge.cc deleted file mode 100644 index 22c3d49..0000000 --- a/weblayer/browser/webapps/webapk_install_scheduler_bridge.cc +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webapps/webapk_install_scheduler_bridge.h" - -#include <jni.h> -#include <string> - -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "components/webapps/browser/android/webapk/webapk_types.h" -#include "ui/gfx/android/java_bitmap.h" -#include "url/gurl.h" -#include "weblayer/browser/java/jni/WebApkInstallSchedulerBridge_jni.h" - -using base::android::ConvertUTF16ToJavaString; -using base::android::ScopedJavaLocalRef; -using base::android::ToJavaByteArray; -using gfx::ConvertToJavaBitmap; - -namespace weblayer { - -// static -bool WebApkInstallSchedulerBridge::IsInstallServiceAvailable() { - return Java_WebApkInstallSchedulerBridge_isInstallServiceAvailable( - base::android::AttachCurrentThread()); -} - -WebApkInstallSchedulerBridge::WebApkInstallSchedulerBridge( - FinishCallback finish_callback) { - finish_callback_ = std::move(finish_callback); - - JNIEnv* env = base::android::AttachCurrentThread(); - java_ref_.Reset(Java_WebApkInstallSchedulerBridge_create( - env, reinterpret_cast<intptr_t>(this))); -} - -WebApkInstallSchedulerBridge::~WebApkInstallSchedulerBridge() { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_WebApkInstallSchedulerBridge_destroy(env, java_ref_); - java_ref_.Reset(); -} - -// static -void WebApkInstallSchedulerBridge::ScheduleWebApkInstallWithChrome( - std::unique_ptr<std::string> serialized_proto, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable, - FinishCallback finish_callback) { - // WebApkInstallSchedulerBridge owns itself and deletes itself when finished. - WebApkInstallSchedulerBridge* bridge = - new WebApkInstallSchedulerBridge(std::move(finish_callback)); - bridge->ScheduleWebApkInstallWithChrome( - std::move(serialized_proto), primary_icon, is_primary_icon_maskable); -} - -void WebApkInstallSchedulerBridge::ScheduleWebApkInstallWithChrome( - std::unique_ptr<std::string> serialized_proto, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable) { - JNIEnv* env = base::android::AttachCurrentThread(); - - ScopedJavaLocalRef<jbyteArray> java_serialized_proto = - ToJavaByteArray(env, *serialized_proto); - ScopedJavaLocalRef<jobject> java_primary_icon = - ConvertToJavaBitmap(primary_icon); - - Java_WebApkInstallSchedulerBridge_scheduleInstall( - env, java_ref_, java_serialized_proto, java_primary_icon, - is_primary_icon_maskable); -} - -void WebApkInstallSchedulerBridge::OnInstallFinished( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jint result) { - std::move(finish_callback_) - .Run(static_cast<webapps::WebApkInstallResult>(result)); - - delete this; -} - -} // namespace weblayer \ No newline at end of file
diff --git a/weblayer/browser/webapps/webapk_install_scheduler_bridge.h b/weblayer/browser/webapps/webapk_install_scheduler_bridge.h deleted file mode 100644 index a47f02f..0000000 --- a/weblayer/browser/webapps/webapk_install_scheduler_bridge.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_BRIDGE_H_ -#define WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_BRIDGE_H_ - -#include "base/android/scoped_java_ref.h" -#include "components/webapps/browser/android/webapk/webapk_icon_hasher.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "weblayer/browser/webapps/webapk_install_scheduler.h" - -namespace webapps { -enum class WebApkInstallResult; -} // namespace webapps - -namespace weblayer { - -// The native WebApkInstallSchedulerBridge owns itself, and deletes itself and -// its Java counterpart when finished. -class WebApkInstallSchedulerBridge { - public: - using FinishCallback = WebApkInstallScheduler::FinishCallback; - - ~WebApkInstallSchedulerBridge(); - - WebApkInstallSchedulerBridge(const WebApkInstallSchedulerBridge&) = delete; - WebApkInstallSchedulerBridge& operator=(const WebApkInstallSchedulerBridge&) = - delete; - - static void ScheduleWebApkInstallWithChrome( - std::unique_ptr<std::string> serialized_proto, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable, - FinishCallback finish_callback); - - static bool IsInstallServiceAvailable(); - - void OnInstallFinished(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jint result); - - private: - WebApkInstallSchedulerBridge(FinishCallback finish_callback); - - void ScheduleWebApkInstallWithChrome( - std::unique_ptr<std::string> serialized_proto, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable); - - FinishCallback finish_callback_; - - // Points to the Java Object. - base::android::ScopedJavaGlobalRef<jobject> java_ref_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_BRIDGE_H_
diff --git a/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc b/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc deleted file mode 100644 index 9970784..0000000 --- a/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc +++ /dev/null
@@ -1,234 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webapps/webapk_install_scheduler.h" - -#include "base/files/file_path.h" -#include "base/memory/raw_ptr.h" -#include "base/run_loop.h" -#include "base/task/single_thread_task_runner.h" -#include "components/webapps/browser/android/shortcut_info.h" -#include "components/webapps/browser/android/webapk/webapk_types.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test.h" - -// Keep these tests in sync with tests for building the WebAPK-proto in -// chrome/browser/android/webapk/webapk_installer_unittest.cc. - -namespace { - -const base::FilePath::CharType kTestDataDir[] = - FILE_PATH_LITERAL("components/test/data/webapps"); - -// Start URL for the WebAPK -const char* kStartUrl = "/index.html"; - -// The URLs of best icons from Web Manifest. We use a random file in the test -// data directory. Since WebApkInstallScheduler does not try to decode the file -// as an image it is OK that the file is not an image. -const char* kBestPrimaryIconUrl = "/simple.html"; -const char* kBestSplashIconUrl = "/nostore.html"; -const char* kBestShortcutIconUrl = "/title1.html"; - -// Icon which has Cross-Origin-Resource-Policy: same-origin set. -const char* kBestPrimaryIconCorpUrl = "/cors_same_origin.png"; - -} // namespace - -namespace weblayer { - -class TestWebApkInstallScheduler : public WebApkInstallScheduler { - public: - TestWebApkInstallScheduler(const webapps::ShortcutInfo& shortcut_info, - const SkBitmap& primary_icon, - WebApkInstallFinishedCallback callback) - : WebApkInstallScheduler(shortcut_info, - primary_icon, - std::move(callback)) {} - - TestWebApkInstallScheduler(const TestWebApkInstallScheduler&) = delete; - TestWebApkInstallScheduler& operator=(const TestWebApkInstallScheduler&) = - delete; - - void ScheduleWithChrome( - std::unique_ptr<std::string> serialized_proto) override { - PostTaskToRunSuccessCallback(); - } - - // Function used for testing FetchProtoAndScheduleInstall. |callback| can - // be set to forward the result-value in the OnResult-callback to a test for - // verification. - void FetchProtoAndScheduleInstallForTesting( - content::WebContents* web_contents, - WebApkInstallScheduler::FinishCallback callback) { - callback_ = std::move(callback); - - WebApkInstallScheduler::FetchProtoAndScheduleInstallForTesting( - web_contents); - } - - void OnResult(webapps::WebApkInstallResult result) override { - // Pass the |result| to the callback for verification. - std::move(callback_).Run(result); - - WebApkInstallScheduler::OnResult(result); - } - - void PostTaskToRunSuccessCallback() { - base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(&TestWebApkInstallScheduler::OnResult, - base::Unretained(this), - webapps::WebApkInstallResult::SUCCESS)); - } - - private: - WebApkInstallScheduler::FinishCallback callback_; -}; - -// Wrapper class for running WebApkInstallScheduler#FetchProtoAndScheduleInstall -// that makes the WebApkInstallResult that is received in the OnResult-callback -// accessible for testing. -class WebApkInstallSchedulerRunner { - public: - WebApkInstallSchedulerRunner() {} - - WebApkInstallSchedulerRunner(const WebApkInstallSchedulerRunner&) = delete; - WebApkInstallSchedulerRunner& operator=(const WebApkInstallSchedulerRunner&) = - delete; - - ~WebApkInstallSchedulerRunner() {} - - void RunFetchProtoAndScheduleInstall( - std::unique_ptr<TestWebApkInstallScheduler> fetcher, - content::WebContents* web_contents) { - base::RunLoop run_loop; - on_completed_callback_ = run_loop.QuitClosure(); - - // WebApkInstallScheduler owns itself. - fetcher.release()->FetchProtoAndScheduleInstallForTesting( - web_contents, base::BindOnce(&WebApkInstallSchedulerRunner::OnCompleted, - base::Unretained(this))); - - run_loop.Run(); - } - - webapps::WebApkInstallResult result() { return result_; } - - private: - void OnCompleted(webapps::WebApkInstallResult result) { - result_ = result; - std::move(on_completed_callback_).Run(); - } - - // Called after the installation process has succeeded or failed. - base::OnceClosure on_completed_callback_; - - // The result of the installation process. - webapps::WebApkInstallResult result_; -}; - -class WebApkInstallSchedulerTest : public WebLayerBrowserTest { - public: - WebApkInstallSchedulerTest() = default; - ~WebApkInstallSchedulerTest() override = default; - - WebApkInstallSchedulerTest(const WebApkInstallSchedulerTest&) = delete; - WebApkInstallSchedulerTest& operator=(const WebApkInstallSchedulerTest&) = - delete; - - void SetUpOnMainThread() override { - WebLayerBrowserTest::SetUpOnMainThread(); - - web_contents_ = static_cast<TabImpl*>(shell()->tab())->web_contents(); - - test_server_.AddDefaultHandlers(base::FilePath(kTestDataDir)); - ASSERT_TRUE(test_server_.Start()); - } - - content::WebContents* web_contents() { return web_contents_; } - - net::test_server::EmbeddedTestServer* test_server() { return &test_server_; } - - std::unique_ptr<TestWebApkInstallScheduler> DefaultWebApkInstallScheduler( - webapps::ShortcutInfo info) { - std::unique_ptr<TestWebApkInstallScheduler> scheduler_bridge( - new TestWebApkInstallScheduler( - info, SkBitmap(), - base::BindOnce(&WebApkInstallSchedulerTest::OnInstallFinished, - base::Unretained(this)))); - return scheduler_bridge; - } - - webapps::ShortcutInfo DefaultShortcutInfo() { - webapps::ShortcutInfo info(test_server_.GetURL(kStartUrl)); - info.best_primary_icon_url = test_server_.GetURL(kBestPrimaryIconUrl); - info.splash_image_url = test_server_.GetURL(kBestSplashIconUrl); - info.best_shortcut_icon_urls.push_back( - test_server_.GetURL(kBestShortcutIconUrl)); - return info; - } - - private: - raw_ptr<content::WebContents> web_contents_; - - net::EmbeddedTestServer test_server_; - - void OnInstallFinished(GURL manifest_id) {} -}; - -// Test building the WebAPK-proto is succeeding. -IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, Success) { - WebApkInstallSchedulerRunner runner; - runner.RunFetchProtoAndScheduleInstall( - DefaultWebApkInstallScheduler(DefaultShortcutInfo()), web_contents()); - EXPECT_EQ(webapps::WebApkInstallResult::SUCCESS, runner.result()); -} - -// Test that building the WebAPK-proto succeeds when the primary icon is guarded -// by a Cross-Origin-Resource-Policy: same-origin header and the icon is -// same-origin with the start URL. -IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, - CrossOriginResourcePolicySameOriginIconSuccess) { - webapps::ShortcutInfo shortcut_info = DefaultShortcutInfo(); - shortcut_info.best_primary_icon_url = - test_server()->GetURL(kBestPrimaryIconCorpUrl); - - WebApkInstallSchedulerRunner runner; - runner.RunFetchProtoAndScheduleInstall( - DefaultWebApkInstallScheduler(shortcut_info), web_contents()); - EXPECT_EQ(webapps::WebApkInstallResult::SUCCESS, runner.result()); -} - -// Test that building the WebAPK-proto fails if fetching the bitmap at the best -// primary icon URL returns no content. In a perfect world the fetch would -// always succeed because the fetch for the same icon succeeded recently. -IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, - BestPrimaryIconUrlDownloadTimesOut) { - webapps::ShortcutInfo shortcut_info = DefaultShortcutInfo(); - shortcut_info.best_primary_icon_url = test_server()->GetURL("/nocontent"); - - WebApkInstallSchedulerRunner runner; - runner.RunFetchProtoAndScheduleInstall( - DefaultWebApkInstallScheduler(shortcut_info), web_contents()); - EXPECT_EQ(webapps::WebApkInstallResult::ICON_HASHER_ERROR, runner.result()); -} - -// Test that building the WebAPK-proto fails if fetching the bitmap at the best -// splash icon URL returns no content. In a perfect world the fetch would always -// succeed because the fetch for the same icon succeeded recently. -IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, - BestSplashIconUrlDownloadTimesOut) { - webapps::ShortcutInfo shortcut_info = DefaultShortcutInfo(); - shortcut_info.best_primary_icon_url = test_server()->GetURL("/nocontent"); - - WebApkInstallSchedulerRunner runner; - runner.RunFetchProtoAndScheduleInstall( - DefaultWebApkInstallScheduler(shortcut_info), web_contents()); - EXPECT_EQ(webapps::WebApkInstallResult::ICON_HASHER_ERROR, runner.result()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/webapps/webapps_utils.cc b/weblayer/browser/webapps/webapps_utils.cc deleted file mode 100644 index d7a46240..0000000 --- a/weblayer/browser/webapps/webapps_utils.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webapps/webapps_utils.h" - -#include <string> - -#include "base/android/jni_string.h" -#include "ui/gfx/android/java_bitmap.h" -#include "url/gurl.h" -#include "weblayer/browser/java/jni/WebappsHelper_jni.h" - -using base::android::ConvertUTF16ToJavaString; -using base::android::ConvertUTF8ToJavaString; -using base::android::ScopedJavaLocalRef; - -namespace webapps { - -void addShortcutToHomescreen(const std::string& id, - const GURL& url, - const std::u16string& user_title, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable) { - JNIEnv* env = base::android::AttachCurrentThread(); - ScopedJavaLocalRef<jstring> java_id = ConvertUTF8ToJavaString(env, id); - ScopedJavaLocalRef<jstring> java_url = - ConvertUTF8ToJavaString(env, url.spec()); - ScopedJavaLocalRef<jstring> java_user_title = - ConvertUTF16ToJavaString(env, user_title); - - ScopedJavaLocalRef<jobject> java_bitmap; - if (!primary_icon.drawsNothing()) - java_bitmap = gfx::ConvertToJavaBitmap(primary_icon); - - Java_WebappsHelper_addShortcutToHomescreen(env, java_id, java_url, - java_user_title, java_bitmap, - is_primary_icon_maskable); -} - -} // namespace webapps
diff --git a/weblayer/browser/webapps/webapps_utils.h b/weblayer/browser/webapps/webapps_utils.h deleted file mode 100644 index 013b082..0000000 --- a/weblayer/browser/webapps/webapps_utils.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBAPPS_UTILS_H_ -#define WEBLAYER_BROWSER_WEBAPPS_WEBAPPS_UTILS_H_ - -#include <string> - -class GURL; -class SkBitmap; - -namespace webapps { - -// Adds a shortcut to the home screen. Calls the native method -// addShortcutToHomescreen in WebappsHelper.java -void addShortcutToHomescreen(const std::string& id, - const GURL& url, - const std::u16string& user_title, - const SkBitmap& primary_icon, - bool is_primary_icon_maskable); - -} // namespace webapps - -#endif // WEBLAYER_BROWSER_WEBAPPS_WEBAPPS_UTILS_H_
diff --git a/weblayer/browser/webapps/weblayer_app_banner_manager_android.cc b/weblayer/browser/webapps/weblayer_app_banner_manager_android.cc deleted file mode 100644 index ac57410..0000000 --- a/weblayer/browser/webapps/weblayer_app_banner_manager_android.cc +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webapps/weblayer_app_banner_manager_android.h" - -#include "components/webapps/browser/android/app_banner_manager_android.h" - -namespace weblayer { - -WebLayerAppBannerManagerAndroid::WebLayerAppBannerManagerAndroid( - content::WebContents* web_contents) - : AppBannerManagerAndroid(web_contents), - content::WebContentsUserData<WebLayerAppBannerManagerAndroid>( - *web_contents) {} - -WebLayerAppBannerManagerAndroid::~WebLayerAppBannerManagerAndroid() = default; - -void WebLayerAppBannerManagerAndroid::MaybeShowAmbientBadge() { - // TODO(crbug/1420605): Enable WebApk install BottomSheet/Banner for WebEngine - // sandbox mode. -} - -void WebLayerAppBannerManagerAndroid::ShowBannerUi( - webapps::WebappInstallSource install_source) { - // TODO(crbug/1420605): Enable WebApk install BottomSheet/Banner for WebEngine - // sandbox mode. -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(WebLayerAppBannerManagerAndroid); - -} // namespace weblayer
diff --git a/weblayer/browser/webapps/weblayer_app_banner_manager_android.h b/weblayer/browser/webapps/weblayer_app_banner_manager_android.h deleted file mode 100644 index a2c2291..0000000 --- a/weblayer/browser/webapps/weblayer_app_banner_manager_android.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_APP_BANNER_MANAGER_ANDROID_H_ -#define WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_APP_BANNER_MANAGER_ANDROID_H_ - -#include "components/webapps/browser/android/app_banner_manager_android.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace weblayer { - -class WebLayerAppBannerManagerAndroid - : public webapps::AppBannerManagerAndroid, - public content::WebContentsUserData<WebLayerAppBannerManagerAndroid> { - public: - explicit WebLayerAppBannerManagerAndroid(content::WebContents* web_contents); - WebLayerAppBannerManagerAndroid(const WebLayerAppBannerManagerAndroid&) = - delete; - WebLayerAppBannerManagerAndroid& operator=( - const WebLayerAppBannerManagerAndroid&) = delete; - ~WebLayerAppBannerManagerAndroid() override; - - using content::WebContentsUserData< - WebLayerAppBannerManagerAndroid>::FromWebContents; - - protected: - void MaybeShowAmbientBadge() override; - void ShowBannerUi(webapps::WebappInstallSource install_source) override; - - private: - friend class content::WebContentsUserData<WebLayerAppBannerManagerAndroid>; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_APP_BANNER_MANAGER_ANDROID_H_
diff --git a/weblayer/browser/webapps/weblayer_webapps_client.cc b/weblayer/browser/webapps/weblayer_webapps_client.cc deleted file mode 100644 index f3a5d34..0000000 --- a/weblayer/browser/webapps/weblayer_webapps_client.cc +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webapps/weblayer_webapps_client.h" - -#include <string> - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/feature_list.h" -#include "base/logging.h" -#include "base/no_destructor.h" -#include "base/uuid.h" -#include "build/build_config.h" -#include "components/infobars/content/content_infobar_manager.h" -#include "components/security_state/content/content_utils.h" -#include "components/webapps/browser/android/add_to_homescreen_params.h" -#include "components/webapps/browser/android/shortcut_info.h" -#include "components/webapps/browser/features.h" -#include "components/webapps/browser/installable/installable_metrics.h" -#include "content/public/browser/browser_context.h" -#include "ui/android/color_utils_android.h" -#include "ui/gfx/android/java_bitmap.h" -#include "url/gurl.h" -#include "url/origin.h" -#include "weblayer/browser/webapps/webapk_install_scheduler.h" -#include "weblayer/browser/webapps/webapps_utils.h" -#include "weblayer/browser/webapps/weblayer_app_banner_manager_android.h" - -namespace weblayer { - -using base::android::ConvertUTF16ToJavaString; -using base::android::ConvertUTF8ToJavaString; -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -WebLayerWebappsClient::WebLayerWebappsClient() = default; -WebLayerWebappsClient::~WebLayerWebappsClient() = default; - -// static -void WebLayerWebappsClient::Create() { - static base::NoDestructor<WebLayerWebappsClient> instance; - instance.get(); -} - -bool WebLayerWebappsClient::IsOriginConsideredSecure( - const url::Origin& origin) { - return false; -} - -security_state::SecurityLevel -WebLayerWebappsClient::GetSecurityLevelForWebContents( - content::WebContents* web_contents) { - auto state = security_state::GetVisibleSecurityState(web_contents); - return security_state::GetSecurityLevel( - *state, - /* used_policy_installed_certificate */ false); -} - -infobars::ContentInfoBarManager* -WebLayerWebappsClient::GetInfoBarManagerForWebContents( - content::WebContents* web_contents) { - return infobars::ContentInfoBarManager::FromWebContents(web_contents); -} - -webapps::WebappInstallSource WebLayerWebappsClient::GetInstallSource( - content::WebContents* web_contents, - webapps::InstallTrigger trigger) { - if (trigger == webapps::InstallTrigger::AMBIENT_BADGE) { - // RICH_INSTALL_UI is the new name for AMBIENT_BADGE. - return webapps::WebappInstallSource::RICH_INSTALL_UI_WEBLAYER; - } - return webapps::WebappInstallSource::COUNT; -} - -webapps::AppBannerManager* WebLayerWebappsClient::GetAppBannerManager( - content::WebContents* web_contents) { - return WebLayerAppBannerManagerAndroid::FromWebContents(web_contents); -} - -bool WebLayerWebappsClient::IsInstallationInProgress( - content::WebContents* web_contents, - const GURL& manifest_id) { - return current_install_ids_.count(manifest_id); -} - -bool WebLayerWebappsClient::CanShowAppBanners( - content::WebContents* web_contents) { - return WebApkInstallScheduler::IsInstallServiceAvailable(); -} - -void WebLayerWebappsClient::OnWebApkInstallInitiatedFromAppMenu( - content::WebContents* web_contents) {} - -void WebLayerWebappsClient::InstallWebApk( - content::WebContents* web_contents, - const webapps::AddToHomescreenParams& params) { - DCHECK(current_install_ids_.count(params.shortcut_info->manifest_id) == 0); - current_install_ids_.insert(params.shortcut_info->manifest_id); - WebApkInstallScheduler::FetchProtoAndScheduleInstall( - web_contents, *(params.shortcut_info), params.primary_icon, - base::BindOnce(&WebLayerWebappsClient::OnInstallFinished, - weak_ptr_factory_.GetWeakPtr())); -} - -void WebLayerWebappsClient::InstallShortcut( - content::WebContents* web_contents, - const webapps::AddToHomescreenParams& params) { - const webapps::ShortcutInfo& info = *params.shortcut_info; - - webapps::addShortcutToHomescreen( - base::Uuid::GenerateRandomV4().AsLowercaseString(), info.url, - info.user_title, params.primary_icon, info.is_primary_icon_maskable); -} - -void WebLayerWebappsClient::OnInstallFinished(GURL manifest_id) { - DCHECK(current_install_ids_.count(manifest_id) == 1); - current_install_ids_.erase(manifest_id); -} - -} // namespace weblayer
diff --git a/weblayer/browser/webapps/weblayer_webapps_client.h b/weblayer/browser/webapps/weblayer_webapps_client.h deleted file mode 100644 index 859e751..0000000 --- a/weblayer/browser/webapps/weblayer_webapps_client.h +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_WEBAPPS_CLIENT_H_ -#define WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_WEBAPPS_CLIENT_H_ - -#include <set> - -#include "base/memory/weak_ptr.h" -#include "base/no_destructor.h" -#include "build/build_config.h" -#include "components/webapps/browser/webapps_client.h" - -class GURL; - -namespace url { -class Origin; -} - -namespace weblayer { - -class WebLayerWebappsClient : public webapps::WebappsClient { - public: - // Called when the scheduling of an WebAPK installation with the Chrome - // service finished or failed. - using WebApkInstallFinishedCallback = base::OnceCallback<void(GURL)>; - - WebLayerWebappsClient(const WebLayerWebappsClient&) = delete; - WebLayerWebappsClient& operator=(const WebLayerWebappsClient&) = delete; - - static void Create(); - - // WebappsClient: - bool IsOriginConsideredSecure(const url::Origin& origin) override; - security_state::SecurityLevel GetSecurityLevelForWebContents( - content::WebContents* web_contents) override; - infobars::ContentInfoBarManager* GetInfoBarManagerForWebContents( - content::WebContents* web_contents) override; - webapps::WebappInstallSource GetInstallSource( - content::WebContents* web_contents, - webapps::InstallTrigger trigger) override; - webapps::AppBannerManager* GetAppBannerManager( - content::WebContents* web_contents) override; -#if BUILDFLAG(IS_ANDROID) - bool IsInstallationInProgress(content::WebContents* web_contents, - const GURL& manifest_id) override; - bool CanShowAppBanners(content::WebContents* web_contents) override; - void OnWebApkInstallInitiatedFromAppMenu( - content::WebContents* web_contents) override; - void InstallWebApk(content::WebContents* web_contents, - const webapps::AddToHomescreenParams& params) override; - void InstallShortcut(content::WebContents* web_contents, - const webapps::AddToHomescreenParams& params) override; -#endif - - private: - friend base::NoDestructor<WebLayerWebappsClient>; - - WebLayerWebappsClient(); - ~WebLayerWebappsClient() override; - - void OnInstallFinished(GURL manifest_id); - - std::set<GURL> current_install_ids_; - - // Used to get |weak_ptr_|. - base::WeakPtrFactory<WebLayerWebappsClient> weak_ptr_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_WEBAPPS_CLIENT_H_
diff --git a/weblayer/browser/weblayer_browser_interface_binders.cc b/weblayer/browser/weblayer_browser_interface_binders.cc deleted file mode 100644 index cb8ee03..0000000 --- a/weblayer/browser/weblayer_browser_interface_binders.cc +++ /dev/null
@@ -1,144 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_browser_interface_binders.h" - -#include "base/functional/bind.h" -#include "build/build_config.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" -#include "components/no_state_prefetch/browser/no_state_prefetch_processor_impl.h" -#include "components/no_state_prefetch/common/prerender_canceler.mojom.h" -#include "components/payments/content/payment_credential_factory.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_controller.h" -#include "third_party/blink/public/mojom/payments/payment_credential.mojom.h" -#include "third_party/blink/public/mojom/payments/payment_request.mojom.h" -#include "third_party/blink/public/mojom/prerender/prerender.mojom.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_processor_impl_delegate_impl.h" -#include "weblayer/browser/no_state_prefetch/no_state_prefetch_utils.h" -#include "weblayer/browser/translate_client_impl.h" -#include "weblayer/browser/webui/weblayer_internals.mojom.h" -#include "weblayer/browser/webui/weblayer_internals_ui.h" - -#if BUILDFLAG(IS_ANDROID) -#include "mojo/public/cpp/bindings/self_owned_receiver.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h" -#include "third_party/blink/public/mojom/webshare/webshare.mojom.h" -#endif - -namespace weblayer { -namespace { - -void BindContentTranslateDriver( - content::RenderFrameHost* host, - mojo::PendingReceiver<translate::mojom::ContentTranslateDriver> receiver) { - // Translation does not currently work in subframes. - // TODO(crbug.com/1073370): Transition WebLayer to per-frame translation - // architecture once it's ready. - if (host->GetParent()) - return; - - auto* contents = content::WebContents::FromRenderFrameHost(host); - if (!contents) - return; - - TranslateClientImpl* const translate_client = - TranslateClientImpl::FromWebContents(contents); - translate_client->translate_driver()->AddReceiver(std::move(receiver)); -} - -void BindPageHandler( - content::RenderFrameHost* host, - mojo::PendingReceiver<weblayer_internals::mojom::PageHandler> receiver) { - auto* contents = content::WebContents::FromRenderFrameHost(host); - if (!contents) - return; - - content::WebUI* web_ui = contents->GetWebUI(); - - // Performs a safe downcast to the concrete WebUIController subclass. - WebLayerInternalsUI* concrete_controller = - web_ui ? web_ui->GetController()->GetAs<WebLayerInternalsUI>() : nullptr; - - // This is expected to be called only for main frames and for the right - // WebUI pages matching the same WebUI associated to the RenderFrameHost. - if (host->GetParent() || !concrete_controller) - return; - - concrete_controller->BindInterface(std::move(receiver)); -} - -void BindNoStatePrefetchProcessor( - content::RenderFrameHost* frame_host, - mojo::PendingReceiver<blink::mojom::NoStatePrefetchProcessor> receiver) { - prerender::NoStatePrefetchProcessorImpl::Create( - frame_host, std::move(receiver), - std::make_unique<NoStatePrefetchProcessorImplDelegateImpl>()); -} - -void BindPrerenderCanceler( - content::RenderFrameHost* frame_host, - mojo::PendingReceiver<prerender::mojom::PrerenderCanceler> receiver) { - auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host); - if (!web_contents) - return; - - auto* no_state_prefetch_contents = - NoStatePrefetchContentsFromWebContents(web_contents); - if (!no_state_prefetch_contents) - return; - no_state_prefetch_contents->AddPrerenderCancelerReceiver(std::move(receiver)); -} - -#if BUILDFLAG(IS_ANDROID) -template <typename Interface> -void ForwardToJavaWebContents(content::RenderFrameHost* frame_host, - mojo::PendingReceiver<Interface> receiver) { - content::WebContents* contents = - content::WebContents::FromRenderFrameHost(frame_host); - if (contents) - contents->GetJavaInterfaces()->GetInterface(std::move(receiver)); -} - -template <typename Interface> -void ForwardToJavaFrame(content::RenderFrameHost* render_frame_host, - mojo::PendingReceiver<Interface> receiver) { - render_frame_host->GetJavaInterfaces()->GetInterface(std::move(receiver)); -} -#endif - -} // namespace - -void PopulateWebLayerFrameBinders( - content::RenderFrameHost* render_frame_host, - mojo::BinderMapWithContext<content::RenderFrameHost*>* map) { - map->Add<weblayer_internals::mojom::PageHandler>( - base::BindRepeating(&BindPageHandler)); - - map->Add<translate::mojom::ContentTranslateDriver>( - base::BindRepeating(&BindContentTranslateDriver)); - - map->Add<blink::mojom::NoStatePrefetchProcessor>( - base::BindRepeating(&BindNoStatePrefetchProcessor)); - - map->Add<prerender::mojom::PrerenderCanceler>( - base::BindRepeating(&BindPrerenderCanceler)); - -#if BUILDFLAG(IS_ANDROID) - map->Add<blink::mojom::InstalledAppProvider>(base::BindRepeating( - &ForwardToJavaFrame<blink::mojom::InstalledAppProvider>)); - map->Add<blink::mojom::ShareService>(base::BindRepeating( - &ForwardToJavaWebContents<blink::mojom::ShareService>)); - map->Add<payments::mojom::PaymentRequest>(base::BindRepeating( - &ForwardToJavaFrame<payments::mojom::PaymentRequest>)); - map->Add<payments::mojom::PaymentCredential>( - base::BindRepeating(&payments::CreatePaymentCredential)); -#endif -} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_browser_interface_binders.h b/weblayer/browser/weblayer_browser_interface_binders.h deleted file mode 100644 index d0b56cc..0000000 --- a/weblayer/browser/weblayer_browser_interface_binders.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_BROWSER_INTERFACE_BINDERS_H_ -#define WEBLAYER_BROWSER_WEBLAYER_BROWSER_INTERFACE_BINDERS_H_ - -#include "mojo/public/cpp/bindings/binder_map.h" - -namespace content { -class RenderFrameHost; -} - -namespace weblayer { - -void PopulateWebLayerFrameBinders( - content::RenderFrameHost* render_frame_host, - mojo::BinderMapWithContext<content::RenderFrameHost*>* binder_map); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_BROWSER_INTERFACE_BINDERS_H_
diff --git a/weblayer/browser/weblayer_factory_impl_android.cc b/weblayer/browser/weblayer_factory_impl_android.cc deleted file mode 100644 index f70caa9..0000000 --- a/weblayer/browser/weblayer_factory_impl_android.cc +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_factory_impl_android.h" - -#include "weblayer/browser/java/jni/WebLayerFactoryImpl_jni.h" - -namespace weblayer { - -int WebLayerFactoryImplAndroid::GetClientMajorVersion() { - JNIEnv* env = base::android::AttachCurrentThread(); - return Java_WebLayerFactoryImpl_getClientMajorVersion(env); -} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_factory_impl_android.h b/weblayer/browser/weblayer_factory_impl_android.h deleted file mode 100644 index e49d1b55..0000000 --- a/weblayer/browser/weblayer_factory_impl_android.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_FACTORY_IMPL_ANDROID_H_ -#define WEBLAYER_BROWSER_WEBLAYER_FACTORY_IMPL_ANDROID_H_ - -namespace weblayer { - -// Exposes functionality from WebLayerFactoryImpl.java to C++. -class WebLayerFactoryImplAndroid { - public: - static int GetClientMajorVersion(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_FACTORY_IMPL_ANDROID_H_
diff --git a/weblayer/browser/weblayer_features.cc b/weblayer/browser/weblayer_features.cc deleted file mode 100644 index ff9c35db..0000000 --- a/weblayer/browser/weblayer_features.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_features.h" - -#include "build/build_config.h" - -namespace weblayer { - -#if BUILDFLAG(IS_ANDROID) -// Used to disable browser-control animations. -BASE_FEATURE(kImmediatelyHideBrowserControlsForTest, - "ImmediatelyHideBrowserControlsForTest", - base::FEATURE_DISABLED_BY_DEFAULT); -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_features.h b/weblayer/browser/weblayer_features.h deleted file mode 100644 index 5ab250e..0000000 --- a/weblayer/browser/weblayer_features.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_FEATURES_H_ -#define WEBLAYER_BROWSER_WEBLAYER_FEATURES_H_ - -#include "base/feature_list.h" -#include "build/build_config.h" - -namespace weblayer { - -#if BUILDFLAG(IS_ANDROID) -BASE_DECLARE_FEATURE(kImmediatelyHideBrowserControlsForTest); -#endif - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_FEATURES_H_
diff --git a/weblayer/browser/weblayer_field_trials.cc b/weblayer/browser/weblayer_field_trials.cc deleted file mode 100644 index ffdd7056..0000000 --- a/weblayer/browser/weblayer_field_trials.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_field_trials.h" - -#include "base/path_service.h" -#include "components/metrics/persistent_histograms.h" -#include "weblayer/common/weblayer_paths.h" - -namespace weblayer { - -void WebLayerFieldTrials::OnVariationsSetupComplete() { - // Persistent histograms must be enabled as soon as possible. - base::FilePath metrics_dir; - if (base::PathService::Get(DIR_USER_DATA, &metrics_dir)) { - InstantiatePersistentHistogramsWithFeaturesAndCleanup(metrics_dir); - } else { - NOTREACHED(); - } -} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_field_trials.h b/weblayer/browser/weblayer_field_trials.h deleted file mode 100644 index 406a030..0000000 --- a/weblayer/browser/weblayer_field_trials.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_FIELD_TRIALS_H_ -#define WEBLAYER_BROWSER_WEBLAYER_FIELD_TRIALS_H_ - -#include "components/variations/platform_field_trials.h" - -namespace weblayer { - -// Responsible for setting up field trials specific to WebLayer. Currently all -// functions are stubs, as WebLayer has no specific field trials. -class WebLayerFieldTrials : public variations::PlatformFieldTrials { - public: - WebLayerFieldTrials() = default; - - WebLayerFieldTrials(const WebLayerFieldTrials&) = delete; - WebLayerFieldTrials& operator=(const WebLayerFieldTrials&) = delete; - - ~WebLayerFieldTrials() override = default; - - // variations::PlatformFieldTrials: - void OnVariationsSetupComplete() override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_FIELD_TRIALS_H_
diff --git a/weblayer/browser/weblayer_impl_android.cc b/weblayer/browser/weblayer_impl_android.cc deleted file mode 100644 index ef9d5072..0000000 --- a/weblayer/browser/weblayer_impl_android.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_impl_android.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "components/component_updater/android/component_loader_policy.h" -#include "components/crash/core/common/crash_key.h" -#include "components/embedder_support/user_agent_utils.h" -#include "components/page_info/android/page_info_client.h" -#include "components/variations/variations_ids_provider.h" -#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" -#include "weblayer/browser/component_updater/registration.h" -#include "weblayer/browser/devtools_server_android.h" -#include "weblayer/browser/java/jni/WebLayerImpl_jni.h" -#include "weblayer/common/crash_reporter/crash_keys.h" - -using base::android::JavaParamRef; - -namespace weblayer { - -static void JNI_WebLayerImpl_SetRemoteDebuggingEnabled(JNIEnv* env, - jboolean enabled) { - DevToolsServerAndroid::SetRemoteDebuggingEnabled(enabled); -} - -static jboolean JNI_WebLayerImpl_IsRemoteDebuggingEnabled(JNIEnv* env) { - return DevToolsServerAndroid::GetRemoteDebuggingEnabled(); -} - -static void JNI_WebLayerImpl_SetIsWebViewCompatMode(JNIEnv* env, - jboolean value) { - static crash_reporter::CrashKeyString<1> crash_key( - crash_keys::kWeblayerWebViewCompatMode); - crash_key.Set(value ? "1" : "0"); -} - -static base::android::ScopedJavaLocalRef<jstring> -JNI_WebLayerImpl_GetUserAgentString(JNIEnv* env) { - return base::android::ConvertUTF8ToJavaString( - base::android::AttachCurrentThread(), embedder_support::GetUserAgent()); -} - -static void JNI_WebLayerImpl_RegisterExternalExperimentIDs( - JNIEnv* env, - const JavaParamRef<jintArray>& jexperiment_ids) { - std::vector<int> experiment_ids; - // A null |jexperiment_ids| is the same as an empty list. - if (jexperiment_ids) { - base::android::JavaIntArrayToIntVector(env, jexperiment_ids, - &experiment_ids); - } - - WebLayerMetricsServiceClient::GetInstance()->RegisterExternalExperiments( - experiment_ids); -} - -static base::android::ScopedJavaLocalRef<jstring> -JNI_WebLayerImpl_GetXClientDataHeader(JNIEnv* env) { - std::string header; - auto headers = - variations::VariationsIdsProvider::GetInstance()->GetClientDataHeaders( - false /* is_signed_in */); - if (headers) - header = - headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY); - return base::android::ConvertUTF8ToJavaString(env, header); -} - -std::u16string GetClientApplicationName() { - JNIEnv* env = base::android::AttachCurrentThread(); - - return base::android::ConvertJavaStringToUTF16( - env, Java_WebLayerImpl_getEmbedderName(env)); -} - -static base::android::ScopedJavaLocalRef<jobjectArray> -JNI_WebLayerImpl_GetComponentLoaderPolicies(JNIEnv* env) { - return component_updater::AndroidComponentLoaderPolicy:: - ToJavaArrayOfAndroidComponentLoaderPolicy(env, - GetComponentLoaderPolicies()); -} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_impl_android.h b/weblayer/browser/weblayer_impl_android.h deleted file mode 100644 index 3f2b7b77f..0000000 --- a/weblayer/browser/weblayer_impl_android.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_IMPL_ANDROID_H_ -#define WEBLAYER_BROWSER_WEBLAYER_IMPL_ANDROID_H_ - -#include <string> - - -namespace weblayer { - -// Returns the name of the WebLayer embedder. -std::u16string GetClientApplicationName(); - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_IMPL_ANDROID_H_
diff --git a/weblayer/browser/weblayer_metrics_service_accessor.h b/weblayer/browser/weblayer_metrics_service_accessor.h deleted file mode 100644 index 8aae36fc..0000000 --- a/weblayer/browser/weblayer_metrics_service_accessor.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_METRICS_SERVICE_ACCESSOR_H_ -#define WEBLAYER_BROWSER_WEBLAYER_METRICS_SERVICE_ACCESSOR_H_ - -#include "components/metrics/metrics_service_accessor.h" - -namespace weblayer { - -// This class gives and documents access to metrics::MetricsServiceAccessor -// methods. Since these methods are protected in the base case, each user has to -// be explicitly declared as a 'friend' below. -class WebLayerMetricsServiceAccessor : public metrics::MetricsServiceAccessor { - private: - friend class WebLayerSafeBrowsingUIManagerDelegate; - friend class WebLayerAssistantFieldTrialUtil; - - WebLayerMetricsServiceAccessor() = delete; - WebLayerMetricsServiceAccessor(const WebLayerMetricsServiceAccessor&) = - delete; - WebLayerMetricsServiceAccessor& operator=( - const WebLayerMetricsServiceAccessor&) = delete; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_METRICS_SERVICE_ACCESSOR_H_
diff --git a/weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.cc b/weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.cc deleted file mode 100644 index 6a0f7f34..0000000 --- a/weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.h" - -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" -#include "components/page_load_metrics/browser/page_load_metrics_memory_tracker.h" - -namespace weblayer { - -page_load_metrics::PageLoadMetricsMemoryTracker* -WeblayerPageLoadMetricsMemoryTrackerFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<page_load_metrics::PageLoadMetricsMemoryTracker*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -WeblayerPageLoadMetricsMemoryTrackerFactory* -WeblayerPageLoadMetricsMemoryTrackerFactory::GetInstance() { - return base::Singleton<WeblayerPageLoadMetricsMemoryTrackerFactory>::get(); -} - -WeblayerPageLoadMetricsMemoryTrackerFactory:: - WeblayerPageLoadMetricsMemoryTrackerFactory() - : BrowserContextKeyedServiceFactory( - "PageLoadMetricsMemoryTracker", - BrowserContextDependencyManager::GetInstance()) {} - -bool WeblayerPageLoadMetricsMemoryTrackerFactory:: - ServiceIsCreatedWithBrowserContext() const { - return base::FeatureList::IsEnabled(features::kV8PerFrameMemoryMonitoring); -} - -std::unique_ptr<KeyedService> WeblayerPageLoadMetricsMemoryTrackerFactory:: - BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<page_load_metrics::PageLoadMetricsMemoryTracker>(); -} - -content::BrowserContext* -WeblayerPageLoadMetricsMemoryTrackerFactory::GetBrowserContextToUse( - content::BrowserContext* context) const { - return context; -} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.h b/weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.h deleted file mode 100644 index be672005..0000000 --- a/weblayer/browser/weblayer_page_load_metrics_memory_tracker_factory.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_PAGE_LOAD_METRICS_MEMORY_TRACKER_FACTORY_H_ -#define WEBLAYER_BROWSER_WEBLAYER_PAGE_LOAD_METRICS_MEMORY_TRACKER_FACTORY_H_ - -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace page_load_metrics { -class PageLoadMetricsMemoryTracker; -} // namespace page_load_metrics - -namespace weblayer { - -class WeblayerPageLoadMetricsMemoryTrackerFactory - : public BrowserContextKeyedServiceFactory { - public: - static page_load_metrics::PageLoadMetricsMemoryTracker* GetForBrowserContext( - content::BrowserContext* context); - - static WeblayerPageLoadMetricsMemoryTrackerFactory* GetInstance(); - - WeblayerPageLoadMetricsMemoryTrackerFactory(); - - private: - // BrowserContextKeyedServiceFactory: - bool ServiceIsCreatedWithBrowserContext() const override; - - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; - - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_PAGE_LOAD_METRICS_MEMORY_TRACKER_FACTORY_H_
diff --git a/weblayer/browser/weblayer_security_blocking_page_factory.cc b/weblayer/browser/weblayer_security_blocking_page_factory.cc deleted file mode 100644 index 46171208..0000000 --- a/weblayer/browser/weblayer_security_blocking_page_factory.cc +++ /dev/null
@@ -1,232 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_security_blocking_page_factory.h" - -#include "build/build_config.h" -#include "components/captive_portal/core/buildflags.h" -#include "components/security_interstitials/content/content_metrics_helper.h" -#include "components/security_interstitials/content/insecure_form_blocking_page.h" -#include "components/security_interstitials/content/settings_page_helper.h" -#include "components/security_interstitials/content/ssl_blocking_page.h" -#include "components/security_interstitials/core/metrics_helper.h" -#include "content/public/browser/web_contents.h" -#include "weblayer/browser/captive_portal_service_factory.h" -#include "weblayer/browser/insecure_form_controller_client.h" -#include "weblayer/browser/ssl_error_controller_client.h" - -#if BUILDFLAG(IS_ANDROID) -#include "content/public/browser/page_navigator.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/referrer.h" -#include "ui/base/window_open_disposition.h" -#endif - -namespace weblayer { - -namespace { - -#if BUILDFLAG(IS_ANDROID) -GURL GetCaptivePortalLoginPageUrlInternal() { - // NOTE: This is taken from the default login URL in //chrome's - // CaptivePortalHelper.java, which is used in the implementation referenced - // in OpenLoginPage() below. - return GURL("http://connectivitycheck.gstatic.com/generate_204"); -} -#endif - -void OpenLoginPage(content::WebContents* web_contents) { - // TODO(https://crbug.com/1030692): Componentize and share the - // Android implementation from //chrome's - // ChromeSecurityBlockingPageFactory::OpenLoginPage(), from which this is - // adapted. -#if BUILDFLAG(IS_ANDROID) - content::OpenURLParams params(GetCaptivePortalLoginPageUrlInternal(), - content::Referrer(), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_LINK, false); - web_contents->OpenURL(params); -#else - NOTIMPLEMENTED(); -#endif -} - -std::unique_ptr<security_interstitials::MetricsHelper> -CreateMetricsHelperAndStartRecording(content::WebContents* web_contents, - const GURL& request_url, - const std::string& metric_prefix, - bool overridable) { - security_interstitials::MetricsHelper::ReportDetails report_details; - report_details.metric_prefix = metric_prefix; - auto metrics_helper = std::make_unique<ContentMetricsHelper>( - /*history_service=*/nullptr, request_url, report_details); -#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) - metrics_helper.get()->StartRecordingCaptivePortalMetrics( - CaptivePortalServiceFactory::GetForBrowserContext( - web_contents->GetBrowserContext()), - overridable); -#endif - - return metrics_helper; -} - -std::unique_ptr<security_interstitials::SettingsPageHelper> -CreateSettingsPageHelper() { - // TODO(crbug.com/1078381): Set settings_page_helper once enhanced protection - // is supported on weblayer. - return nullptr; -} - -} // namespace - -std::unique_ptr<SSLBlockingPage> -WebLayerSecurityBlockingPageFactory::CreateSSLPage( - content::WebContents* web_contents, - int cert_error, - const net::SSLInfo& ssl_info, - const GURL& request_url, - int options_mask, - const base::Time& time_triggered, - const GURL& support_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter) { - bool overridable = SSLBlockingPage::IsOverridable(options_mask); - - auto controller_client = std::make_unique<SSLErrorControllerClient>( - web_contents, cert_error, ssl_info, request_url, - CreateMetricsHelperAndStartRecording( - web_contents, request_url, - overridable ? "ssl_overridable" : "ssl_nonoverridable", overridable), - CreateSettingsPageHelper()); - - auto interstitial_page = std::make_unique<SSLBlockingPage>( - web_contents, cert_error, ssl_info, request_url, options_mask, - base::Time::NowFromSystemTime(), /*support_url=*/GURL(), - std::move(ssl_cert_reporter), overridable, - /*can_show_enhanced_protection_message=*/false, - std::move(controller_client)); - - return interstitial_page; -} - -std::unique_ptr<CaptivePortalBlockingPage> -WebLayerSecurityBlockingPageFactory::CreateCaptivePortalBlockingPage( - content::WebContents* web_contents, - const GURL& request_url, - const GURL& login_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter, - const net::SSLInfo& ssl_info, - int cert_error) { - auto controller_client = std::make_unique<SSLErrorControllerClient>( - web_contents, cert_error, ssl_info, request_url, - CreateMetricsHelperAndStartRecording(web_contents, request_url, - "captive_portal", false), - CreateSettingsPageHelper()); - - auto interstitial_page = std::make_unique<CaptivePortalBlockingPage>( - web_contents, request_url, login_url, std::move(ssl_cert_reporter), - /*can_show_enhanced_protection_message=*/false, ssl_info, - std::move(controller_client), base::BindRepeating(&OpenLoginPage)); - - return interstitial_page; -} - -std::unique_ptr<BadClockBlockingPage> -WebLayerSecurityBlockingPageFactory::CreateBadClockBlockingPage( - content::WebContents* web_contents, - int cert_error, - const net::SSLInfo& ssl_info, - const GURL& request_url, - const base::Time& time_triggered, - ssl_errors::ClockState clock_state, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter) { - auto controller_client = std::make_unique<SSLErrorControllerClient>( - web_contents, cert_error, ssl_info, request_url, - CreateMetricsHelperAndStartRecording(web_contents, request_url, - "bad_clock", false), - CreateSettingsPageHelper()); - - auto interstitial_page = std::make_unique<BadClockBlockingPage>( - web_contents, cert_error, ssl_info, request_url, - base::Time::NowFromSystemTime(), - /*can_show_enhanced_protection_message=*/false, clock_state, - std::move(ssl_cert_reporter), std::move(controller_client)); - - return interstitial_page; -} - -std::unique_ptr<MITMSoftwareBlockingPage> -WebLayerSecurityBlockingPageFactory::CreateMITMSoftwareBlockingPage( - content::WebContents* web_contents, - int cert_error, - const GURL& request_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter, - const net::SSLInfo& ssl_info, - const std::string& mitm_software_name) { - auto controller_client = std::make_unique<SSLErrorControllerClient>( - web_contents, cert_error, ssl_info, request_url, - CreateMetricsHelperAndStartRecording(web_contents, request_url, - "mitm_software", false), - CreateSettingsPageHelper()); - - auto interstitial_page = std::make_unique<MITMSoftwareBlockingPage>( - web_contents, cert_error, request_url, std::move(ssl_cert_reporter), - /*can_show_enhanced_protection_message=*/false, ssl_info, - mitm_software_name, - /*is_enterprise_managed=*/false, std::move(controller_client)); - - return interstitial_page; -} - -std::unique_ptr<BlockedInterceptionBlockingPage> -WebLayerSecurityBlockingPageFactory::CreateBlockedInterceptionBlockingPage( - content::WebContents* web_contents, - int cert_error, - const GURL& request_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter, - const net::SSLInfo& ssl_info) { - auto controller_client = std::make_unique<SSLErrorControllerClient>( - web_contents, cert_error, ssl_info, request_url, - CreateMetricsHelperAndStartRecording(web_contents, request_url, - "blocked_interception", false), - CreateSettingsPageHelper()); - - auto interstitial_page = std::make_unique<BlockedInterceptionBlockingPage>( - web_contents, cert_error, request_url, std::move(ssl_cert_reporter), - /*can_show_enhanced_protection_message=*/false, ssl_info, - std::move(controller_client)); - - return interstitial_page; -} - -std::unique_ptr<security_interstitials::InsecureFormBlockingPage> -WebLayerSecurityBlockingPageFactory::CreateInsecureFormBlockingPage( - content::WebContents* web_contents, - const GURL& request_url) { - std::unique_ptr<InsecureFormControllerClient> client = - std::make_unique<InsecureFormControllerClient>(web_contents, request_url); - auto page = - std::make_unique<security_interstitials::InsecureFormBlockingPage>( - web_contents, request_url, std::move(client)); - return page; -} - -std::unique_ptr<security_interstitials::HttpsOnlyModeBlockingPage> -WebLayerSecurityBlockingPageFactory::CreateHttpsOnlyModeBlockingPage( - content::WebContents* web_contents, - const GURL& request_url, - security_interstitials::https_only_mode::HttpInterstitialState - interstitial_state) { - // HTTPS-only mode is not implemented for weblayer. - return nullptr; -} - -#if BUILDFLAG(IS_ANDROID) -// static -GURL WebLayerSecurityBlockingPageFactory:: - GetCaptivePortalLoginPageUrlForTesting() { - return GetCaptivePortalLoginPageUrlInternal(); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_security_blocking_page_factory.h b/weblayer/browser/weblayer_security_blocking_page_factory.h deleted file mode 100644 index 05e529c..0000000 --- a/weblayer/browser/weblayer_security_blocking_page_factory.h +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_SECURITY_BLOCKING_PAGE_FACTORY_H_ -#define WEBLAYER_BROWSER_WEBLAYER_SECURITY_BLOCKING_PAGE_FACTORY_H_ - -#include "build/build_config.h" -#include "components/captive_portal/core/buildflags.h" -#include "components/security_interstitials/content/bad_clock_blocking_page.h" -#include "components/security_interstitials/content/blocked_interception_blocking_page.h" -#include "components/security_interstitials/content/captive_portal_blocking_page.h" -#include "components/security_interstitials/content/https_only_mode_blocking_page.h" -#include "components/security_interstitials/content/insecure_form_blocking_page.h" -#include "components/security_interstitials/content/mitm_software_blocking_page.h" -#include "components/security_interstitials/content/security_blocking_page_factory.h" -#include "components/security_interstitials/content/ssl_blocking_page.h" -#include "components/security_interstitials/content/ssl_blocking_page_base.h" - -namespace weblayer { - -// //weblayer's implementation of the SecurityBlockingPageFactory interface. -class WebLayerSecurityBlockingPageFactory : public SecurityBlockingPageFactory { - public: - WebLayerSecurityBlockingPageFactory() = default; - ~WebLayerSecurityBlockingPageFactory() override = default; - WebLayerSecurityBlockingPageFactory( - const WebLayerSecurityBlockingPageFactory&) = delete; - WebLayerSecurityBlockingPageFactory& operator=( - const WebLayerSecurityBlockingPageFactory&) = delete; - - // SecurityBlockingPageFactory: - std::unique_ptr<SSLBlockingPage> CreateSSLPage( - content::WebContents* web_contents, - int cert_error, - const net::SSLInfo& ssl_info, - const GURL& request_url, - int options_mask, - const base::Time& time_triggered, - const GURL& support_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter) override; - std::unique_ptr<CaptivePortalBlockingPage> CreateCaptivePortalBlockingPage( - content::WebContents* web_contents, - const GURL& request_url, - const GURL& login_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter, - const net::SSLInfo& ssl_info, - int cert_error) override; - std::unique_ptr<BadClockBlockingPage> CreateBadClockBlockingPage( - content::WebContents* web_contents, - int cert_error, - const net::SSLInfo& ssl_info, - const GURL& request_url, - const base::Time& time_triggered, - ssl_errors::ClockState clock_state, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter) override; - std::unique_ptr<MITMSoftwareBlockingPage> CreateMITMSoftwareBlockingPage( - content::WebContents* web_contents, - int cert_error, - const GURL& request_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter, - const net::SSLInfo& ssl_info, - const std::string& mitm_software_name) override; - std::unique_ptr<BlockedInterceptionBlockingPage> - CreateBlockedInterceptionBlockingPage( - content::WebContents* web_contents, - int cert_error, - const GURL& request_url, - std::unique_ptr<SSLCertReporter> ssl_cert_reporter, - const net::SSLInfo& ssl_info) override; - std::unique_ptr<security_interstitials::InsecureFormBlockingPage> - CreateInsecureFormBlockingPage(content::WebContents* web_contents, - const GURL& request_url) override; - std::unique_ptr<security_interstitials::HttpsOnlyModeBlockingPage> - CreateHttpsOnlyModeBlockingPage( - content::WebContents* web_contents, - const GURL& request_url, - security_interstitials::https_only_mode::HttpInterstitialState - interstitial_state) override; - -#if BUILDFLAG(IS_ANDROID) - // Returns the URL that will be navigated to when the user clicks on the - // "Connect" button of the captive portal interstitial. Used by tests to - // verify this flow. - static GURL GetCaptivePortalLoginPageUrlForTesting(); -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_SECURITY_BLOCKING_PAGE_FACTORY_H_
diff --git a/weblayer/browser/weblayer_speech_recognition_manager_delegate.cc b/weblayer/browser/weblayer_speech_recognition_manager_delegate.cc deleted file mode 100644 index bf81c0b..0000000 --- a/weblayer/browser/weblayer_speech_recognition_manager_delegate.cc +++ /dev/null
@@ -1,116 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_speech_recognition_manager_delegate.h" - -#include <string> - -#include "base/functional/bind.h" -#include "build/build_config.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/speech_recognition_manager.h" -#include "content/public/browser/speech_recognition_session_context.h" -#include "content/public/browser/web_contents.h" -#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h" -#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h" - -using content::BrowserThread; - -namespace weblayer { - -WebLayerSpeechRecognitionManagerDelegate:: - WebLayerSpeechRecognitionManagerDelegate() = default; - -WebLayerSpeechRecognitionManagerDelegate:: - ~WebLayerSpeechRecognitionManagerDelegate() = default; - -void WebLayerSpeechRecognitionManagerDelegate::OnRecognitionStart( - int session_id) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete( - int session_id) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnRecognitionResults( - int session_id, - const std::vector<blink::mojom::SpeechRecognitionResultPtr>& result) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnRecognitionError( - int session_id, - const blink::mojom::SpeechRecognitionError& error) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnAudioLevelsChange( - int session_id, - float volume, - float noise_volume) {} - -void WebLayerSpeechRecognitionManagerDelegate::OnRecognitionEnd( - int session_id) {} - -void WebLayerSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( - int session_id, - base::OnceCallback<void(bool ask_user, bool is_allowed)> callback) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - const content::SpeechRecognitionSessionContext& context = - content::SpeechRecognitionManager::GetInstance()->GetSessionContext( - session_id); - - // Make sure that initiators (extensions/web pages) properly set the - // |render_process_id| field, which is needed later to retrieve the profile. - DCHECK_NE(context.render_process_id, 0); - - int render_process_id = context.render_process_id; - int render_frame_id = context.render_frame_id; - if (context.embedder_render_process_id) { - // If this is a request originated from a guest, we need to re-route the - // permission check through the embedder (app). - render_process_id = context.embedder_render_process_id; - render_frame_id = context.embedder_render_frame_id; - } - - // Check that the render frame type is appropriate, and whether or not we - // need to request permission from the user. - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&CheckRenderFrameType, std::move(callback), - render_process_id, render_frame_id)); -} - -content::SpeechRecognitionEventListener* -WebLayerSpeechRecognitionManagerDelegate::GetEventListener() { - return this; -} - -bool WebLayerSpeechRecognitionManagerDelegate::FilterProfanities( - int render_process_id) { - // TODO(timvolodine): to confirm how this setting should be used in weblayer. - // https://crbug.com/1068679. - return false; -} - -// static. -void WebLayerSpeechRecognitionManagerDelegate::CheckRenderFrameType( - base::OnceCallback<void(bool ask_user, bool is_allowed)> callback, - int render_process_id, - int render_frame_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - // Regular tab contents. - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), true /* check_permission */, - true /* allowed */)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_speech_recognition_manager_delegate.h b/weblayer/browser/weblayer_speech_recognition_manager_delegate.h deleted file mode 100644 index 657e2b3..0000000 --- a/weblayer/browser/weblayer_speech_recognition_manager_delegate.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_ -#define WEBLAYER_BROWSER_WEBLAYER_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_ - -#include "content/public/browser/speech_recognition_event_listener.h" -#include "content/public/browser/speech_recognition_manager_delegate.h" -#include "content/public/browser/speech_recognition_session_config.h" - -namespace weblayer { - -// WebLayer implementation of the SpeechRecognitionManagerDelegate interface. -class WebLayerSpeechRecognitionManagerDelegate - : public content::SpeechRecognitionManagerDelegate, - public content::SpeechRecognitionEventListener { - public: - WebLayerSpeechRecognitionManagerDelegate(); - ~WebLayerSpeechRecognitionManagerDelegate() override; - - WebLayerSpeechRecognitionManagerDelegate( - const WebLayerSpeechRecognitionManagerDelegate&) = delete; - WebLayerSpeechRecognitionManagerDelegate& operator=( - const WebLayerSpeechRecognitionManagerDelegate&) = delete; - - protected: - // SpeechRecognitionEventListener methods. - void OnRecognitionStart(int session_id) override; - void OnAudioStart(int session_id) override; - void OnEnvironmentEstimationComplete(int session_id) override; - void OnSoundStart(int session_id) override; - void OnSoundEnd(int session_id) override; - void OnAudioEnd(int session_id) override; - void OnRecognitionEnd(int session_id) override; - void OnRecognitionResults( - int session_id, - const std::vector<blink::mojom::SpeechRecognitionResultPtr>& result) - override; - void OnRecognitionError( - int session_id, - const blink::mojom::SpeechRecognitionError& error) override; - void OnAudioLevelsChange(int session_id, - float volume, - float noise_volume) override; - - // SpeechRecognitionManagerDelegate methods. - void CheckRecognitionIsAllowed( - int session_id, - base::OnceCallback<void(bool ask_user, bool is_allowed)> callback) - override; - content::SpeechRecognitionEventListener* GetEventListener() override; - bool FilterProfanities(int render_process_id) override; - - private: - // Checks for mojom::ViewType::kTabContents host in the UI thread and notifies - // back the result in the IO thread through |callback|. - static void CheckRenderFrameType( - base::OnceCallback<void(bool ask_user, bool is_allowed)> callback, - int render_process_id, - int render_frame_id); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
diff --git a/weblayer/browser/weblayer_variations_http_browsertest.cc b/weblayer/browser/weblayer_variations_http_browsertest.cc deleted file mode 100644 index 0940f6c..0000000 --- a/weblayer/browser/weblayer_variations_http_browsertest.cc +++ /dev/null
@@ -1,159 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/command_line.h" -#include "base/synchronization/lock.h" -#include "base/thread_annotations.h" -#include "components/variations/variations_ids_provider.h" -#include "content/public/test/network_connection_change_simulator.h" -#include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/embedded_test_server/http_request.h" -#include "net/test/embedded_test_server/http_response.h" -#include "weblayer/public/navigation.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -// The purpose of this test is to verify Variations code is correctly wired up -// for WebLayer. It's not intended to replicate VariationsHttpHeadersBrowserTest -class WebLayerVariationsHttpBrowserTest : public WebLayerBrowserTest { - public: - WebLayerVariationsHttpBrowserTest() - : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {} - - ~WebLayerVariationsHttpBrowserTest() override = default; - - void SetUp() override { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - - // HTTPS server only serves a valid cert for localhost, so this is needed to - // load pages from "www.google.com" without an interstitial. - command_line->AppendSwitch("ignore-certificate-errors"); - - WebLayerBrowserTest::SetUp(); - } - - void SetUpOnMainThread() override { - auto* variations_provider = - variations::VariationsIdsProvider::GetInstance(); - variations_provider->ForceVariationIds({"12", "456", "t789"}, ""); - - // The test makes requests to google.com which we want to redirect to the - // test server. - host_resolver()->AddRule("*", "127.0.0.1"); - - https_server_.RegisterRequestHandler( - base::BindRepeating(&WebLayerVariationsHttpBrowserTest::RequestHandler, - base::Unretained(this))); - - ASSERT_TRUE(https_server_.Start()); - } - - GURL GetGoogleUrlWithPath(const std::string& path) const { - return https_server_.GetURL("www.google.com", path); - } - - GURL GetGoogleRedirectUrl1() const { - return GetGoogleUrlWithPath("/redirect"); - } - - GURL GetGoogleRedirectUrl2() const { - return GetGoogleUrlWithPath("/redirect2"); - } - - GURL GetExampleUrlWithPath(const std::string& path) const { - return https_server_.GetURL("www.example.com", path); - } - - GURL GetExampleUrl() const { return GetExampleUrlWithPath("/landing.html"); } - - // Returns whether a given |header| has been received for a |url|. If - // |url| has not been observed, fails an EXPECT and returns false. - bool HasReceivedHeader(const GURL& url, const std::string& header) { - base::AutoLock lock(received_headers_lock_); - auto it = received_headers_.find(url); - EXPECT_TRUE(it != received_headers_.end()); - if (it == received_headers_.end()) - return false; - return it->second.find(header) != it->second.end(); - } - - std::unique_ptr<net::test_server::HttpResponse> RequestHandler( - const net::test_server::HttpRequest& request) { - // Retrieve the host name (without port) from the request headers. - std::string host = ""; - if (request.headers.find("Host") != request.headers.end()) - host = request.headers.find("Host")->second; - if (host.find(':') != std::string::npos) - host = host.substr(0, host.find(':')); - - // Recover the original URL of the request by replacing the host name in - // request.GetURL() (which is 127.0.0.1) with the host name from the request - // headers. - GURL::Replacements replacements; - replacements.SetHostStr(host); - GURL original_url = request.GetURL().ReplaceComponents(replacements); - - { - base::AutoLock lock(received_headers_lock_); - // Memorize the request headers for this URL for later verification. - received_headers_[original_url] = request.headers; - } - - // Set up a test server that redirects according to the - // following redirect chain: - // https://www.google.com:<port>/redirect - // --> https://www.google.com:<port>/redirect2 - // --> https://www.example.com:<port>/ - auto http_response = - std::make_unique<net::test_server::BasicHttpResponse>(); - http_response->AddCustomHeader("Access-Control-Allow-Origin", "*"); - if (request.relative_url == GetGoogleRedirectUrl1().path()) { - http_response->set_code(net::HTTP_MOVED_PERMANENTLY); - http_response->AddCustomHeader("Location", - GetGoogleRedirectUrl2().spec()); - } else if (request.relative_url == GetGoogleRedirectUrl2().path()) { - http_response->set_code(net::HTTP_MOVED_PERMANENTLY); - http_response->AddCustomHeader("Location", GetExampleUrl().spec()); - } else if (request.relative_url == GetExampleUrl().path()) { - http_response->set_code(net::HTTP_OK); - http_response->set_content("hello"); - http_response->set_content_type("text/plain"); - } else { - return nullptr; - } - return http_response; - } - - protected: - net::EmbeddedTestServer https_server_; - - base::Lock received_headers_lock_; - - // Stores the observed HTTP Request headers. - std::map<GURL, net::test_server::HttpRequest::HeaderMap> received_headers_ - GUARDED_BY(received_headers_lock_); -}; - -// Verify in an integration test that the variations header (X-Client-Data) is -// attached to network requests to Google but stripped on redirects. -IN_PROC_BROWSER_TEST_F(WebLayerVariationsHttpBrowserTest, - TestStrippingHeadersFromResourceRequest) { - OneShotNavigationObserver observer(shell()); - shell()->tab()->GetNavigationController()->Navigate(GetGoogleRedirectUrl1()); - observer.WaitForNavigation(); - - EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data")); - EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl2(), "X-Client-Data")); - EXPECT_TRUE(HasReceivedHeader(GetExampleUrl(), "Host")); - EXPECT_FALSE(HasReceivedHeader(GetExampleUrl(), "X-Client-Data")); -} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_variations_service_client.cc b/weblayer/browser/weblayer_variations_service_client.cc deleted file mode 100644 index d358a6d..0000000 --- a/weblayer/browser/weblayer_variations_service_client.cc +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/weblayer_variations_service_client.h" - -#include "build/build_config.h" -#include "components/version_info/channel.h" -#include "components/version_info/version_info.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/system_network_context_manager.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/version_info/android/channel_getter.h" -#endif - -using version_info::Channel; - -namespace weblayer { - -WebLayerVariationsServiceClient::WebLayerVariationsServiceClient( - SystemNetworkContextManager* network_context_manager) - : network_context_manager_(network_context_manager) { - DCHECK(network_context_manager_); -} - -WebLayerVariationsServiceClient::~WebLayerVariationsServiceClient() = default; - -base::Version WebLayerVariationsServiceClient::GetVersionForSimulation() { - return version_info::GetVersion(); -} - -scoped_refptr<network::SharedURLLoaderFactory> -WebLayerVariationsServiceClient::GetURLLoaderFactory() { - return network_context_manager_->GetSharedURLLoaderFactory(); -} - -network_time::NetworkTimeTracker* -WebLayerVariationsServiceClient::GetNetworkTimeTracker() { - return BrowserProcess::GetInstance()->GetNetworkTimeTracker(); -} - -Channel WebLayerVariationsServiceClient::GetChannel() { -#if BUILDFLAG(IS_ANDROID) - return version_info::android::GetChannel(); -#else - return version_info::Channel::UNKNOWN; -#endif -} - -bool WebLayerVariationsServiceClient::OverridesRestrictParameter( - std::string* parameter) { - return false; -} - -bool WebLayerVariationsServiceClient::IsEnterprise() { - return false; -} - -void WebLayerVariationsServiceClient:: - RemoveGoogleGroupsFromPrefsForDeletedProfiles(PrefService* local_state) {} - -} // namespace weblayer
diff --git a/weblayer/browser/weblayer_variations_service_client.h b/weblayer/browser/weblayer_variations_service_client.h deleted file mode 100644 index 9a7ef45..0000000 --- a/weblayer/browser/weblayer_variations_service_client.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBLAYER_VARIATIONS_SERVICE_CLIENT_H_ -#define WEBLAYER_BROWSER_WEBLAYER_VARIATIONS_SERVICE_CLIENT_H_ - -#include <string> - -#include "base/memory/raw_ptr.h" -#include "base/memory/scoped_refptr.h" -#include "components/variations/service/variations_service_client.h" - -namespace weblayer { - -class SystemNetworkContextManager; - -// WebLayerVariationsServiceClient provides an implementation of -// VariationsServiceClient, all members are currently stubs for WebLayer. -class WebLayerVariationsServiceClient - : public variations::VariationsServiceClient { - public: - explicit WebLayerVariationsServiceClient( - SystemNetworkContextManager* network_context_manager); - - WebLayerVariationsServiceClient(const WebLayerVariationsServiceClient&) = - delete; - WebLayerVariationsServiceClient& operator=( - const WebLayerVariationsServiceClient&) = delete; - - ~WebLayerVariationsServiceClient() override; - - private: - // variations::VariationsServiceClient: - base::Version GetVersionForSimulation() override; - scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; - network_time::NetworkTimeTracker* GetNetworkTimeTracker() override; - version_info::Channel GetChannel() override; - bool OverridesRestrictParameter(std::string* parameter) override; - bool IsEnterprise() override; - void RemoveGoogleGroupsFromPrefsForDeletedProfiles( - PrefService* local_state) override; - - raw_ptr<SystemNetworkContextManager> network_context_manager_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBLAYER_VARIATIONS_SERVICE_CLIENT_H_
diff --git a/weblayer/browser/webrtc/media_stream_manager.cc b/weblayer/browser/webrtc/media_stream_manager.cc deleted file mode 100644 index aaea5e5..0000000 --- a/weblayer/browser/webrtc/media_stream_manager.cc +++ /dev/null
@@ -1,225 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webrtc/media_stream_manager.h" - -#include <utility> - -#include "base/memory/raw_ptr.h" -#include "base/supports_user_data.h" -#include "components/webrtc/media_stream_devices_controller.h" -#include "content/public/browser/media_stream_request.h" -#include "content/public/browser/web_contents.h" -#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" -#include "weblayer/browser/java/jni/MediaStreamManager_jni.h" - -using base::android::AttachCurrentThread; -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -namespace { - -constexpr int kWebContentsUserDataKey = 0; - -struct UserData : public base::SupportsUserData::Data { - raw_ptr<MediaStreamManager, AcrossTasksDanglingUntriaged> manager = nullptr; -}; - -} // namespace - -// A class that tracks the lifecycle of a single active media stream. Ownership -// is passed off to MediaResponseCallback. -class MediaStreamManager::StreamUi : public content::MediaStreamUI { - public: - StreamUi(base::WeakPtr<MediaStreamManager> manager, - const blink::mojom::StreamDevicesSet& stream_devices) - : manager_(manager) { - DCHECK(manager_); - DCHECK_EQ(1u, stream_devices.stream_devices.size()); - streaming_audio_ = - stream_devices.stream_devices[0]->audio_device.has_value(); - streaming_video_ = - stream_devices.stream_devices[0]->video_device.has_value(); - } - StreamUi(const StreamUi&) = delete; - StreamUi& operator=(const StreamUi&) = delete; - - ~StreamUi() override { - if (manager_) - manager_->UnregisterStream(this); - } - - // content::MediaStreamUi: - gfx::NativeViewId OnStarted( - base::RepeatingClosure stop, - SourceCallback source, - const std::string& label, - std::vector<content::DesktopMediaID> screen_capture_ids, - StateChangeCallback state_change) override { - stop_ = std::move(stop); - if (manager_) - manager_->RegisterStream(this); - return 0; - } - void OnDeviceStoppedForSourceChange( - const std::string& label, - const content::DesktopMediaID& old_media_id, - const content::DesktopMediaID& new_media_id) override {} - void OnDeviceStopped(const std::string& label, - const content::DesktopMediaID& media_id) override {} - - bool streaming_audio() const { return streaming_audio_; } - - bool streaming_video() const { return streaming_video_; } - - void Stop() { - // The `stop_` callback does async processing. This means Stop() may be - // called multiple times. - if (stop_) - std::move(stop_).Run(); - } - - private: - base::WeakPtr<MediaStreamManager> manager_; - bool streaming_audio_ = false; - bool streaming_video_ = false; - base::OnceClosure stop_; -}; - -MediaStreamManager::MediaStreamManager( - const JavaParamRef<jobject>& j_object, - const JavaParamRef<jobject>& j_web_contents) - : j_object_(j_object) { - auto user_data = std::make_unique<UserData>(); - user_data->manager = this; - content::WebContents::FromJavaWebContents(j_web_contents) - ->SetUserData(&kWebContentsUserDataKey, std::move(user_data)); -} - -MediaStreamManager::~MediaStreamManager() = default; - -// static -MediaStreamManager* MediaStreamManager::FromWebContents( - content::WebContents* contents) { - UserData* user_data = reinterpret_cast<UserData*>( - contents->GetUserData(&kWebContentsUserDataKey)); - DCHECK(user_data); - return user_data->manager; -} - -void MediaStreamManager::RequestMediaAccessPermission( - const content::MediaStreamRequest& request, - content::MediaResponseCallback callback) { - webrtc::MediaStreamDevicesController::RequestPermissions( - request, nullptr, - base::BindOnce(&MediaStreamManager::OnMediaAccessPermissionResult, - weak_factory_.GetWeakPtr(), std::move(callback))); -} - -void MediaStreamManager::OnClientReadyToStream(JNIEnv* env, - int request_id, - bool allowed) { - auto request = requests_pending_client_approval_.find(request_id); - CHECK(request != requests_pending_client_approval_.end()); - if (allowed) { - std::move(request->second.callback) - .Run(*request->second.stream_devices_set_, request->second.result, - std::make_unique<StreamUi>(weak_factory_.GetWeakPtr(), - *request->second.stream_devices_set_)); - } else { - std::move(request->second.callback) - .Run(blink::mojom::StreamDevicesSet(), - blink::mojom::MediaStreamRequestResult::NO_HARDWARE, {}); - } - requests_pending_client_approval_.erase(request); -} - -void MediaStreamManager::StopStreaming(JNIEnv* env) { - std::set<StreamUi*> active_streams = active_streams_; - for (auto* stream : active_streams) - stream->Stop(); -} - -void MediaStreamManager::OnMediaAccessPermissionResult( - content::MediaResponseCallback callback, - const blink::mojom::StreamDevicesSet& stream_devices_set, - blink::mojom::MediaStreamRequestResult result, - bool blocked_by_permissions_policy, - ContentSetting audio_setting, - ContentSetting video_setting) { - // TODO(crbug.com/1300883): Generalize to multiple streams. - DCHECK((result != blink::mojom::MediaStreamRequestResult::OK && - stream_devices_set.stream_devices.empty()) || - (result == blink::mojom::MediaStreamRequestResult::OK && - stream_devices_set.stream_devices.size() == 1u)); - if (result != blink::mojom::MediaStreamRequestResult::OK) { - std::move(callback).Run(stream_devices_set, result, {}); - return; - } - - int request_id = next_request_id_++; - requests_pending_client_approval_[request_id] = RequestPendingClientApproval( - std::move(callback), stream_devices_set, result); - Java_MediaStreamManager_prepareToStream( - base::android::AttachCurrentThread(), j_object_, - stream_devices_set.stream_devices[0]->audio_device.has_value(), - stream_devices_set.stream_devices[0]->video_device.has_value(), - request_id); -} - -void MediaStreamManager::RegisterStream(StreamUi* stream) { - active_streams_.insert(stream); - Update(); -} - -void MediaStreamManager::UnregisterStream(StreamUi* stream) { - active_streams_.erase(stream); - Update(); -} - -void MediaStreamManager::Update() { - bool audio = false; - bool video = false; - for (const auto* stream : active_streams_) { - audio = audio || stream->streaming_audio(); - video = video || stream->streaming_video(); - } - - Java_MediaStreamManager_update(base::android::AttachCurrentThread(), - j_object_, audio, video); -} - -static jlong JNI_MediaStreamManager_Create( - JNIEnv* env, - const JavaParamRef<jobject>& j_object, - const JavaParamRef<jobject>& j_web_contents) { - return reinterpret_cast<intptr_t>( - new MediaStreamManager(j_object, j_web_contents)); -} - -static void JNI_MediaStreamManager_Destroy(JNIEnv* env, jlong native_manager) { - delete reinterpret_cast<MediaStreamManager*>(native_manager); -} - -MediaStreamManager::RequestPendingClientApproval:: - RequestPendingClientApproval() = default; - -MediaStreamManager::RequestPendingClientApproval::RequestPendingClientApproval( - content::MediaResponseCallback callback, - const blink::mojom::StreamDevicesSet& stream_devices_set, - blink::mojom::MediaStreamRequestResult result) - : callback(std::move(callback)), - stream_devices_set_(stream_devices_set.Clone()), - result(result) {} - -MediaStreamManager::RequestPendingClientApproval:: - ~RequestPendingClientApproval() = default; - -MediaStreamManager::RequestPendingClientApproval& -MediaStreamManager::RequestPendingClientApproval::operator=( - RequestPendingClientApproval&& other) = default; - -} // namespace weblayer
diff --git a/weblayer/browser/webrtc/media_stream_manager.h b/weblayer/browser/webrtc/media_stream_manager.h deleted file mode 100644 index 63e1a0c..0000000 --- a/weblayer/browser/webrtc/media_stream_manager.h +++ /dev/null
@@ -1,99 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBRTC_MEDIA_STREAM_MANAGER_H_ -#define WEBLAYER_BROWSER_WEBRTC_MEDIA_STREAM_MANAGER_H_ - -#include <map> -#include <set> - -#include "base/android/scoped_java_ref.h" -#include "base/memory/weak_ptr.h" -#include "components/content_settings/core/common/content_settings.h" -#include "content/public/browser/media_stream_request.h" -#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" - -namespace content { -class WebContents; -} - -namespace weblayer { - -// On Android, this class tracks active media streams and updates the Java -// object of the same name as streams come and go. The class is created and -// destroyed by the Java object. -// -// When a site requests a new stream, this class passes off the request to -// MediaStreamDevicesController, which handles Android permissions as well as -// per-site permissions. If that succeeds, the request is passed off to the -// embedder by way of MediaCaptureCallback, at which point the response is -// returned in |OnClientReadyToStream|. -class MediaStreamManager { - public: - // It's expected that |j_web_contents| outlasts |this|. - MediaStreamManager( - const base::android::JavaParamRef<jobject>& j_object, - const base::android::JavaParamRef<jobject>& j_web_contents); - MediaStreamManager(const MediaStreamManager&) = delete; - MediaStreamManager& operator=(const MediaStreamManager&) = delete; - ~MediaStreamManager(); - - static MediaStreamManager* FromWebContents(content::WebContents* contents); - - // Requests media access permission for the tab, if necessary, and runs - // |callback| as appropriate. This will create a StreamUi. - void RequestMediaAccessPermission(const content::MediaStreamRequest& request, - content::MediaResponseCallback callback); - - // The embedder has responded to the stream request. - void OnClientReadyToStream(JNIEnv* env, int request_id, bool allowed); - - // The embedder has requested all streams be stopped. - void StopStreaming(JNIEnv* env); - - private: - class StreamUi; - - void OnMediaAccessPermissionResult( - content::MediaResponseCallback callback, - const blink::mojom::StreamDevicesSet& stream_devices_set, - blink::mojom::MediaStreamRequestResult result, - bool blocked_by_permissions_policy, - ContentSetting audio_setting, - ContentSetting video_setting); - - void RegisterStream(StreamUi* stream); - void UnregisterStream(StreamUi* stream); - void Update(); - - std::set<StreamUi*> active_streams_; - - // Represents a user-approved request for which we're waiting on embedder - // approval. - struct RequestPendingClientApproval { - RequestPendingClientApproval(); - RequestPendingClientApproval( - content::MediaResponseCallback callback, - const blink::mojom::StreamDevicesSet& stream_devices_set, - blink::mojom::MediaStreamRequestResult result); - ~RequestPendingClientApproval(); - - RequestPendingClientApproval& operator=( - RequestPendingClientApproval&& other); - - content::MediaResponseCallback callback; - blink::mojom::StreamDevicesSetPtr stream_devices_set_; - blink::mojom::MediaStreamRequestResult result; - }; - std::map<int, RequestPendingClientApproval> requests_pending_client_approval_; - int next_request_id_ = 0; - - base::android::ScopedJavaGlobalRef<jobject> j_object_; - - base::WeakPtrFactory<MediaStreamManager> weak_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBRTC_MEDIA_STREAM_MANAGER_H_
diff --git a/weblayer/browser/webui/BUILD.gn b/weblayer/browser/webui/BUILD.gn deleted file mode 100644 index d380de3..0000000 --- a/weblayer/browser/webui/BUILD.gn +++ /dev/null
@@ -1,10 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//mojo/public/tools/bindings/mojom.gni") - -mojom("mojo_bindings") { - sources = [ "weblayer_internals.mojom" ] - webui_module_path = "/" -}
diff --git a/weblayer/browser/webui/OWNERS b/weblayer/browser/webui/OWNERS deleted file mode 100644 index 08850f4..0000000 --- a/weblayer/browser/webui/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/weblayer/browser/webui/net_export_ui.cc b/weblayer/browser/webui/net_export_ui.cc deleted file mode 100644 index 7889a72..0000000 --- a/weblayer/browser/webui/net_export_ui.cc +++ /dev/null
@@ -1,174 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webui/net_export_ui.h" - -#include "base/command_line.h" -#include "base/memory/raw_ptr.h" -#include "base/scoped_observation.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "components/net_log/net_export_file_writer.h" -#include "components/net_log/net_export_ui_constants.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/browser/web_ui_data_source.h" -#include "content/public/browser/web_ui_message_handler.h" -#include "weblayer/browser/system_network_context_manager.h" -#include "weblayer/grit/weblayer_resources.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/browser_ui/share/android/intent_helper.h" -#endif - -namespace weblayer { - -namespace { - -class NetExportMessageHandler - : public content::WebUIMessageHandler, - public net_log::NetExportFileWriter::StateObserver { - public: - NetExportMessageHandler() - : file_writer_(SystemNetworkContextManager::GetInstance() - ->GetNetExportFileWriter()) { - file_writer_->Initialize(); - } - - NetExportMessageHandler(const NetExportMessageHandler&) = delete; - NetExportMessageHandler& operator=(const NetExportMessageHandler&) = delete; - - ~NetExportMessageHandler() override { file_writer_->StopNetLog(); } - - // content::WebUIMessageHandler implementation. - void RegisterMessages() override { - web_ui()->RegisterMessageCallback( - net_log::kEnableNotifyUIWithStateHandler, - base::BindRepeating(&NetExportMessageHandler::OnEnableNotifyUIWithState, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - net_log::kStartNetLogHandler, - base::BindRepeating(&NetExportMessageHandler::OnStartNetLog, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - net_log::kStopNetLogHandler, - base::BindRepeating(&NetExportMessageHandler::OnStopNetLog, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - net_log::kSendNetLogHandler, - base::BindRepeating(&NetExportMessageHandler::OnSendNetLog, - base::Unretained(this))); - } - - // Messages - void OnEnableNotifyUIWithState(const base::Value::List& list) { - AllowJavascript(); - if (!state_observation_manager_.IsObserving()) { - state_observation_manager_.Observe(file_writer_.get()); - } - NotifyUIWithState(file_writer_->GetState()); - } - - void OnStartNetLog(const base::Value::List& params) { - // Determine the capture mode. - if (!params.empty() && params[0].is_string()) { - capture_mode_ = net_log::NetExportFileWriter::CaptureModeFromString( - params[0].GetString()); - } - - // Determine the max file size. - if (params.size() > 1 && params[1].is_int() && params[1].GetInt() > 0) - max_log_file_size_ = params[1].GetInt(); - - StartNetLog(base::FilePath()); - } - - void OnStopNetLog(const base::Value::List& list) { - file_writer_->StopNetLog(); - } - - void OnSendNetLog(const base::Value::List& list) { - file_writer_->GetFilePathToCompletedLog( - base::BindOnce(&NetExportMessageHandler::SendEmail)); - } - - // net_log::NetExportFileWriter::StateObserver implementation. - void OnNewState(const base::Value::Dict& state) override { - NotifyUIWithState(state); - } - - private: - // Send NetLog data via email. - static void SendEmail(const base::FilePath& file_to_send) { -#if BUILDFLAG(IS_ANDROID) - if (file_to_send.empty()) - return; - std::string email; - std::string subject = "WebLayer net_internals_log"; - std::string title = "Issue number: "; - std::string body = - "Please add some informative text about the network issues."; - base::FilePath::StringType file_to_attach(file_to_send.value()); - browser_ui::SendEmail(base::ASCIIToUTF16(email), - base::ASCIIToUTF16(subject), base::ASCIIToUTF16(body), - base::ASCIIToUTF16(title), - base::ASCIIToUTF16(file_to_attach)); -#endif - } - - void StartNetLog(const base::FilePath& path) { - file_writer_->StartNetLog( - path, capture_mode_, max_log_file_size_, - base::CommandLine::ForCurrentProcess()->GetCommandLineString(), - std::string(), - web_ui() - ->GetWebContents() - ->GetBrowserContext() - ->GetDefaultStoragePartition() - ->GetNetworkContext()); - } - - // Fires net-log-info-changed event to update the JavaScript UI in the - // renderer. - void NotifyUIWithState(const base::Value::Dict& state) { - FireWebUIListener(net_log::kNetLogInfoChangedEvent, state); - } - - // Cached pointer to SystemNetworkContextManager's NetExportFileWriter. - raw_ptr<net_log::NetExportFileWriter> file_writer_; - - base::ScopedObservation<net_log::NetExportFileWriter, - net_log::NetExportFileWriter::StateObserver> - state_observation_manager_{this}; - - // The capture mode and file size bound that the user chose in the UI when - // logging started is cached here and is read after a file path is chosen in - // the save dialog. Their values are only valid while the save dialog is open - // on the desktop UI. - net::NetLogCaptureMode capture_mode_ = net::NetLogCaptureMode::kDefault; - uint64_t max_log_file_size_ = net_log::NetExportFileWriter::kNoLimit; -}; - -} // namespace - -const char kChromeUINetExportHost[] = "net-export"; - -NetExportUI::NetExportUI(content::WebUI* web_ui) : WebUIController(web_ui) { - web_ui->AddMessageHandler(std::make_unique<NetExportMessageHandler>()); - - content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd( - web_ui->GetWebContents()->GetBrowserContext(), kChromeUINetExportHost); - source->UseStringsJs(); - source->AddResourcePath(net_log::kNetExportUICSS, IDR_NET_LOG_NET_EXPORT_CSS); - source->AddResourcePath(net_log::kNetExportUIJS, IDR_NET_LOG_NET_EXPORT_JS); - source->SetDefaultResource(IDR_NET_LOG_NET_EXPORT_HTML); -} - -NetExportUI::~NetExportUI() = default; - -WEB_UI_CONTROLLER_TYPE_IMPL(NetExportUI) - -} // namespace weblayer
diff --git a/weblayer/browser/webui/net_export_ui.h b/weblayer/browser/webui/net_export_ui.h deleted file mode 100644 index b626bbf..0000000 --- a/weblayer/browser/webui/net_export_ui.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBUI_NET_EXPORT_UI_H_ -#define WEBLAYER_BROWSER_WEBUI_NET_EXPORT_UI_H_ - -#include "build/build_config.h" -#include "content/public/browser/web_ui_controller.h" - -namespace weblayer { - -extern const char kChromeUINetExportHost[]; - -class NetExportUI : public content::WebUIController { - public: - explicit NetExportUI(content::WebUI* web_ui); - - NetExportUI(const NetExportUI&) = delete; - NetExportUI& operator=(const NetExportUI&) = delete; - - ~NetExportUI() override; - - private: - WEB_UI_CONTROLLER_TYPE_DECL(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBUI_NET_EXPORT_UI_H_
diff --git a/weblayer/browser/webui/web_ui_controller_factory.cc b/weblayer/browser/webui/web_ui_controller_factory.cc deleted file mode 100644 index 13d8a6d..0000000 --- a/weblayer/browser/webui/web_ui_controller_factory.cc +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webui/web_ui_controller_factory.h" - -#include "base/memory/ptr_util.h" -#include "base/no_destructor.h" -#include "content/public/browser/web_ui.h" -#include "url/gurl.h" -#include "weblayer/browser/webui/net_export_ui.h" -#include "weblayer/browser/webui/weblayer_internals_ui.h" - -namespace weblayer { -namespace { - -const content::WebUI::TypeID kWebLayerID = &kWebLayerID; - -// A function for creating a new WebUI. The caller owns the return value, which -// may be nullptr (for example, if the URL refers to an non-existent extension). -typedef content::WebUIController* ( - *WebUIFactoryFunctionPointer)(content::WebUI* web_ui, const GURL& url); - -// Template for defining WebUIFactoryFunctionPointer. -template <class T> -content::WebUIController* NewWebUI(content::WebUI* web_ui, const GURL& url) { - return new T(web_ui); -} - -WebUIFactoryFunctionPointer GetWebUIFactoryFunctionPointer(const GURL& url) { - if (url.host() == kChromeUIWebLayerHost) { - return &NewWebUI<WebLayerInternalsUI>; - } - if (url.host() == kChromeUINetExportHost) { - return &NewWebUI<NetExportUI>; - } - - return nullptr; -} - -content::WebUI::TypeID GetWebUITypeID(const GURL& url) { - if (url.host() == kChromeUIWebLayerHost || - url.host() == kChromeUINetExportHost) { - return kWebLayerID; - } - - return content::WebUI::kNoWebUI; -} - -} // namespace - -// static -WebUIControllerFactory* WebUIControllerFactory::GetInstance() { - static base::NoDestructor<WebUIControllerFactory> instance; - return instance.get(); -} - -WebUIControllerFactory::WebUIControllerFactory() = default; - -WebUIControllerFactory::~WebUIControllerFactory() = default; - -content::WebUI::TypeID WebUIControllerFactory::GetWebUIType( - content::BrowserContext* browser_context, - const GURL& url) { - return GetWebUITypeID(url); -} - -bool WebUIControllerFactory::UseWebUIForURL( - content::BrowserContext* browser_context, - const GURL& url) { - return GetWebUIType(browser_context, url) != content::WebUI::kNoWebUI; -} - -std::unique_ptr<content::WebUIController> -WebUIControllerFactory::CreateWebUIControllerForURL(content::WebUI* web_ui, - const GURL& url) { - WebUIFactoryFunctionPointer function = GetWebUIFactoryFunctionPointer(url); - if (!function) - return nullptr; - - return base::WrapUnique((*function)(web_ui, url)); -} - -} // namespace weblayer
diff --git a/weblayer/browser/webui/web_ui_controller_factory.h b/weblayer/browser/webui/web_ui_controller_factory.h deleted file mode 100644 index 60451229f..0000000 --- a/weblayer/browser/webui/web_ui_controller_factory.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBUI_WEB_UI_CONTROLLER_FACTORY_H_ -#define WEBLAYER_BROWSER_WEBUI_WEB_UI_CONTROLLER_FACTORY_H_ - -#include "base/no_destructor.h" -#include "content/public/browser/web_ui_controller_factory.h" - -namespace weblayer { - -class WebUIControllerFactory : public content::WebUIControllerFactory { - public: - WebUIControllerFactory(const WebUIControllerFactory&) = delete; - WebUIControllerFactory& operator=(const WebUIControllerFactory&) = delete; - - static WebUIControllerFactory* GetInstance(); - - // content::WebUIControllerFactory overrides - content::WebUI::TypeID GetWebUIType(content::BrowserContext* browser_context, - const GURL& url) override; - bool UseWebUIForURL(content::BrowserContext* browser_context, - const GURL& url) override; - std::unique_ptr<content::WebUIController> CreateWebUIControllerForURL( - content::WebUI* web_ui, - const GURL& url) override; - - private: - friend base::NoDestructor<WebUIControllerFactory>; - - WebUIControllerFactory(); - ~WebUIControllerFactory() override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBUI_WEB_UI_CONTROLLER_FACTORY_H_
diff --git a/weblayer/browser/webui/weblayer_internals.mojom b/weblayer/browser/webui/weblayer_internals.mojom deleted file mode 100644 index 27617c6a..0000000 --- a/weblayer/browser/webui/weblayer_internals.mojom +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module weblayer_internals.mojom; - -// Browser interface. -interface PageHandler { - // Gets whether remote debugging is currently enabled. - [EnableIf=is_android] - GetRemoteDebuggingEnabled() => (bool enabled); - - // Enables or disables remote debugging. - [EnableIf=is_android] - SetRemoteDebuggingEnabled(bool enabled); -};
diff --git a/weblayer/browser/webui/weblayer_internals_ui.cc b/weblayer/browser/webui/weblayer_internals_ui.cc deleted file mode 100644 index afae5cf..0000000 --- a/weblayer/browser/webui/weblayer_internals_ui.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/webui/weblayer_internals_ui.h" - -#include "build/build_config.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui_data_source.h" -#include "weblayer/browser/devtools_server_android.h" -#include "weblayer/grit/weblayer_resources.h" - -namespace weblayer { - -const char kChromeUIWebLayerHost[] = "weblayer"; - -WebLayerInternalsUI::WebLayerInternalsUI(content::WebUI* web_ui) - : ui::MojoWebUIController(web_ui) { - content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd( - web_ui->GetWebContents()->GetBrowserContext(), kChromeUIWebLayerHost); - source->AddResourcePath("weblayer_internals.js", IDR_WEBLAYER_INTERNALS_JS); - source->AddResourcePath("weblayer_internals.mojom-webui.js", - IDR_WEBLAYER_INTERNALS_MOJO_JS); - source->SetDefaultResource(IDR_WEBLAYER_INTERNALS_HTML); -} - -WebLayerInternalsUI::~WebLayerInternalsUI() = default; - -#if BUILDFLAG(IS_ANDROID) -void WebLayerInternalsUI::GetRemoteDebuggingEnabled( - GetRemoteDebuggingEnabledCallback callback) { - std::move(callback).Run(DevToolsServerAndroid::GetRemoteDebuggingEnabled()); -} - -void WebLayerInternalsUI::SetRemoteDebuggingEnabled(bool enabled) { - DevToolsServerAndroid::SetRemoteDebuggingEnabled(enabled); -} -#endif - -void WebLayerInternalsUI::BindInterface( - mojo::PendingReceiver<weblayer_internals::mojom::PageHandler> - pending_receiver) { - if (receiver_.is_bound()) - receiver_.reset(); - - receiver_.Bind(std::move(pending_receiver)); -} - -WEB_UI_CONTROLLER_TYPE_IMPL(WebLayerInternalsUI) - -} // namespace weblayer
diff --git a/weblayer/browser/webui/weblayer_internals_ui.h b/weblayer/browser/webui/weblayer_internals_ui.h deleted file mode 100644 index 5aee3c5..0000000 --- a/weblayer/browser/webui/weblayer_internals_ui.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_WEBUI_WEBLAYER_INTERNALS_UI_H_ -#define WEBLAYER_BROWSER_WEBUI_WEBLAYER_INTERNALS_UI_H_ - -#include "build/build_config.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "ui/webui/mojo_web_ui_controller.h" -#include "weblayer/browser/webui/weblayer_internals.mojom.h" - -namespace weblayer { - -extern const char kChromeUIWebLayerHost[]; - -class WebLayerInternalsUI : public ui::MojoWebUIController, - public weblayer_internals::mojom::PageHandler { - public: - explicit WebLayerInternalsUI(content::WebUI* web_ui); - - WebLayerInternalsUI(const WebLayerInternalsUI&) = delete; - WebLayerInternalsUI& operator=(const WebLayerInternalsUI&) = delete; - - ~WebLayerInternalsUI() override; - - // Instantiates implementor of the mojom::PageHandler mojo interface - // passing the pending receiver that will be internally bound. - void BindInterface( - mojo::PendingReceiver<weblayer_internals::mojom::PageHandler> - pending_receiver); - - private: - // weblayer_internals::mojom::PageHandler: -#if BUILDFLAG(IS_ANDROID) - void GetRemoteDebuggingEnabled( - GetRemoteDebuggingEnabledCallback callback) override; - void SetRemoteDebuggingEnabled(bool enabled) override; -#endif - - mojo::Receiver<weblayer_internals::mojom::PageHandler> receiver_{this}; - - WEB_UI_CONTROLLER_TYPE_DECL(); -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_WEBUI_WEBLAYER_INTERNALS_UI_H_
diff --git a/weblayer/browser/webui/webui_browsertest.cc b/weblayer/browser/webui/webui_browsertest.cc deleted file mode 100644 index c0f438e..0000000 --- a/weblayer/browser/webui/webui_browsertest.cc +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "build/build_config.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -using WebLayerWebUIBrowserTest = WebLayerBrowserTest; - -IN_PROC_BROWSER_TEST_F(WebLayerWebUIBrowserTest, DISABLED_WebUI) { - NavigateAndWaitForCompletion(GURL("chrome://weblayer"), shell()); - base::RunLoop run_loop; - bool result = - ExecuteScript(shell(), - "document.getElementById('remote-debug-label').hidden", - true /* use_separate_isolate */) - .GetBool(); - // The remote debug checkbox should only be visible on Android. -#if BUILDFLAG(IS_ANDROID) - EXPECT_FALSE(result); -#else - EXPECT_TRUE(result); -#endif -} - -} // namespace weblayer
diff --git a/weblayer/browser/xr/README.md b/weblayer/browser/xr/README.md deleted file mode 100644 index 7f2863d..0000000 --- a/weblayer/browser/xr/README.md +++ /dev/null
@@ -1,22 +0,0 @@ -# WebXR - -WebLayer supports WebAR (with no current plans to support VR). - -## Testing - -Using [a device that supports AR](https://developers.google.com/ar/discover/supported-devices), build and run with - -``` - $ autoninja -C out/Default run_weblayer_shell - $ ./out/Default/run_weblayer_shell https://immersive-web.github.io/webxr-samples/immersive-ar-session.html -``` - -`run_weblayer_shell_webview` and `run_weblayer_shell_trichrome` should also work. - -If [Google Play Services for AR](https://play.google.com/store/apps/details?id=com.google.ar.core) is installed, then -the demo should work. If it is not installed or not up to date, then the demo will silently fail (the button will shake). - -## TODO - -WebLayer should support an [install flow](https://crbug.com/1177948) for handling the case when Play Services for AR is -not up to date.
diff --git a/weblayer/browser/xr/xr_integration_client_impl.cc b/weblayer/browser/xr/xr_integration_client_impl.cc deleted file mode 100644 index e2cd0abe..0000000 --- a/weblayer/browser/xr/xr_integration_client_impl.cc +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/browser/xr/xr_integration_client_impl.h" - -#include <memory> - -#include "components/webxr/android/ar_compositor_delegate_provider.h" -#include "components/webxr/android/arcore_device_provider.h" -#include "content/public/browser/xr_install_helper.h" -#include "device/vr/public/cpp/vr_device_provider.h" -#include "device/vr/public/mojom/vr_service.mojom-shared.h" -#include "weblayer/browser/java/jni/ArCompositorDelegateProviderImpl_jni.h" -#include "weblayer/browser/java/jni/ArCoreVersionUtils_jni.h" - -namespace weblayer { - -namespace { - -// This install helper simply checks if the necessary package (Google Play -// Services for AR, aka arcore) is installed. It doesn't attempt to initiate an -// install or update. -class ArInstallHelper : public content::XrInstallHelper { - public: - explicit ArInstallHelper() = default; - ~ArInstallHelper() override = default; - ArInstallHelper(const ArInstallHelper&) = delete; - ArInstallHelper& operator=(const ArInstallHelper&) = delete; - - // content::XrInstallHelper implementation. - void EnsureInstalled( - int render_process_id, - int render_frame_id, - base::OnceCallback<void(bool)> install_callback) override { - std::move(install_callback) - .Run(Java_ArCoreVersionUtils_isInstalledAndCompatible( - base::android::AttachCurrentThread())); - } -}; - -} // namespace - -bool XrIntegrationClientImpl::IsEnabled() { - return Java_ArCoreVersionUtils_isEnabled( - base::android::AttachCurrentThread()); -} - -std::unique_ptr<content::XrInstallHelper> -XrIntegrationClientImpl::GetInstallHelper(device::mojom::XRDeviceId device_id) { - if (device_id == device::mojom::XRDeviceId::ARCORE_DEVICE_ID) - return std::make_unique<ArInstallHelper>(); - - return nullptr; -} - -content::XRProviderList XrIntegrationClientImpl::GetAdditionalProviders() { - content::XRProviderList providers; - - base::android::ScopedJavaLocalRef<jobject> j_ar_compositor_delegate_provider = - Java_ArCompositorDelegateProviderImpl_Constructor( - base::android::AttachCurrentThread()); - - providers.push_back(std::make_unique<webxr::ArCoreDeviceProvider>( - std::make_unique<webxr::ArCompositorDelegateProvider>( - std::move(j_ar_compositor_delegate_provider)))); - - return providers; -} - -} // namespace weblayer
diff --git a/weblayer/browser/xr/xr_integration_client_impl.h b/weblayer/browser/xr/xr_integration_client_impl.h deleted file mode 100644 index a71fa62..0000000 --- a/weblayer/browser/xr/xr_integration_client_impl.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_XR_XR_INTEGRATION_CLIENT_IMPL_H_ -#define WEBLAYER_BROWSER_XR_XR_INTEGRATION_CLIENT_IMPL_H_ - -#include <memory> - -#include "content/public/browser/xr_integration_client.h" - -namespace weblayer { - -class XrIntegrationClientImpl : public content::XrIntegrationClient { - public: - XrIntegrationClientImpl() = default; - ~XrIntegrationClientImpl() override = default; - XrIntegrationClientImpl(const XrIntegrationClientImpl&) = delete; - XrIntegrationClientImpl& operator=(const XrIntegrationClientImpl&) = delete; - - // Returns whether XR should be enabled. - static bool IsEnabled(); - - // content::XrIntegrationClient: - std::unique_ptr<content::XrInstallHelper> GetInstallHelper( - device::mojom::XRDeviceId device_id) override; - content::XRProviderList GetAdditionalProviders() override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_XR_XR_INTEGRATION_CLIENT_IMPL_H_
diff --git a/weblayer/common/DEPS b/weblayer/common/DEPS deleted file mode 100644 index 04c923da..0000000 --- a/weblayer/common/DEPS +++ /dev/null
@@ -1,7 +0,0 @@ -include_rules = [ - "+components/embedder_support/origin_trials", - "+content/public/common", - "+gpu/config", - "+third_party/blink/public/strings/grit/blink_strings.h", - "+ui/base", -]
diff --git a/weblayer/common/OWNERS b/weblayer/common/OWNERS deleted file mode 100644 index 08850f4..0000000 --- a/weblayer/common/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/weblayer/common/content_client_impl.cc b/weblayer/common/content_client_impl.cc deleted file mode 100644 index cce3c8ef..0000000 --- a/weblayer/common/content_client_impl.cc +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/common/content_client_impl.h" - -#include "build/build_config.h" -#include "components/embedder_support/origin_trials/origin_trial_policy_impl.h" -#include "gpu/config/gpu_info.h" -#include "gpu/config/gpu_util.h" -#include "third_party/blink/public/strings/grit/blink_strings.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" - -#if BUILDFLAG(IS_ANDROID) -#include "content/public/common/url_constants.h" -#endif - -namespace weblayer { - -ContentClientImpl::ContentClientImpl() = default; - -ContentClientImpl::~ContentClientImpl() = default; - -std::u16string ContentClientImpl::GetLocalizedString(int message_id) { - return l10n_util::GetStringUTF16(message_id); -} - -std::u16string ContentClientImpl::GetLocalizedString( - int message_id, - const std::u16string& replacement) { - return l10n_util::GetStringFUTF16(message_id, replacement); -} - -base::StringPiece ContentClientImpl::GetDataResource( - int resource_id, - ui::ResourceScaleFactor scale_factor) { - return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( - resource_id, scale_factor); -} - -base::RefCountedMemory* ContentClientImpl::GetDataResourceBytes( - int resource_id) { - return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( - resource_id); -} - -std::string ContentClientImpl::GetDataResourceString(int resource_id) { - return ui::ResourceBundle::GetSharedInstance().LoadDataResourceString( - resource_id); -} - -void ContentClientImpl::SetGpuInfo(const gpu::GPUInfo& gpu_info) { - gpu::SetKeysForCrashLogging(gpu_info); -} - -gfx::Image& ContentClientImpl::GetNativeImageNamed(int resource_id) { - return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( - resource_id); -} - -blink::OriginTrialPolicy* ContentClientImpl::GetOriginTrialPolicy() { - // Prevent initialization race (see crbug.com/721144). There may be a - // race when the policy is needed for worker startup (which happens on a - // separate worker thread). - base::AutoLock auto_lock(origin_trial_policy_lock_); - if (!origin_trial_policy_) - origin_trial_policy_ = - std::make_unique<embedder_support::OriginTrialPolicyImpl>(); - return origin_trial_policy_.get(); -} - -void ContentClientImpl::AddAdditionalSchemes(Schemes* schemes) { -#if BUILDFLAG(IS_ANDROID) - schemes->standard_schemes.push_back(content::kAndroidAppScheme); - schemes->referrer_schemes.push_back(content::kAndroidAppScheme); -#endif -} - -} // namespace weblayer
diff --git a/weblayer/common/content_client_impl.h b/weblayer/common/content_client_impl.h deleted file mode 100644 index 1ad3a35..0000000 --- a/weblayer/common/content_client_impl.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_COMMON_CONTENT_CLIENT_IMPL_H_ -#define WEBLAYER_COMMON_CONTENT_CLIENT_IMPL_H_ - -#include "base/synchronization/lock.h" -#include "content/public/common/content_client.h" - -namespace embedder_support { -class OriginTrialPolicyImpl; -} - -namespace weblayer { - -class ContentClientImpl : public content::ContentClient { - public: - ContentClientImpl(); - ~ContentClientImpl() override; - - std::u16string GetLocalizedString(int message_id) override; - std::u16string GetLocalizedString(int message_id, - const std::u16string& replacement) override; - base::StringPiece GetDataResource( - int resource_id, - ui::ResourceScaleFactor scale_factor) override; - base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; - std::string GetDataResourceString(int resource_id) override; - void SetGpuInfo(const gpu::GPUInfo& gpu_info) override; - gfx::Image& GetNativeImageNamed(int resource_id) override; - blink::OriginTrialPolicy* GetOriginTrialPolicy() override; - void AddAdditionalSchemes(Schemes* schemes) override; - - private: - // Used to lock when |origin_trial_policy_| is initialized. - base::Lock origin_trial_policy_lock_; - std::unique_ptr<embedder_support::OriginTrialPolicyImpl> origin_trial_policy_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_COMMON_CONTENT_CLIENT_IMPL_H_
diff --git a/weblayer/common/crash_reporter/DEPS b/weblayer/common/crash_reporter/DEPS deleted file mode 100644 index f5d6f994d..0000000 --- a/weblayer/common/crash_reporter/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+components/crash", - "+components/version_info", -]
diff --git a/weblayer/common/crash_reporter/crash_keys.cc b/weblayer/common/crash_reporter/crash_keys.cc deleted file mode 100644 index 23b802ba..0000000 --- a/weblayer/common/crash_reporter/crash_keys.cc +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/common/crash_reporter/crash_keys.h" - -#include "base/android/build_info.h" -#include "base/strings/string_number_conversions.h" -#include "components/crash/core/common/crash_key.h" - -namespace weblayer { -namespace crash_keys { - -const char kAppPackageName[] = "app-package-name"; -const char kAppPackageVersionCode[] = "app-package-version-code"; - -const char kAndroidSdkInt[] = "android-sdk-int"; - -const char kWeblayerWebViewCompatMode[] = "WEBLAYER_WEB_VIEW_COMPAT_MODE"; - -// clang-format off -const char* const kWebLayerCrashKeyAllowList[] = { - kAppPackageName, kAppPackageVersionCode, kAndroidSdkInt, - kWeblayerWebViewCompatMode, - - // process type - "ptype", - - // Java exception stack traces - "exception_info", - - // gpu - "gpu-driver", "gpu-psver", "gpu-vsver", "gpu-gl-vendor", "gpu-gl-renderer", - "oop_read_failure", "gpu-gl-error-message", - - // content/: - "bad_message_reason", "discardable-memory-allocated", - "discardable-memory-free", "mojo-message-error", - "total-discardable-memory-allocated", - - // crash keys needed for recording finch trials - "variations", "num-experiments", - - nullptr}; -// clang-format on - -} // namespace crash_keys - -void SetWebLayerCrashKeys() { - base::android::BuildInfo* android_build_info = - base::android::BuildInfo::GetInstance(); - - static ::crash_reporter::CrashKeyString<64> app_name_key( - crash_keys::kAppPackageName); - app_name_key.Set(android_build_info->host_package_name()); - - static ::crash_reporter::CrashKeyString<64> app_version_key( - crash_keys::kAppPackageVersionCode); - app_version_key.Set(android_build_info->host_version_code()); - - static ::crash_reporter::CrashKeyString<8> sdk_int_key( - crash_keys::kAndroidSdkInt); - sdk_int_key.Set(base::NumberToString(android_build_info->sdk_int())); -} - -} // namespace weblayer
diff --git a/weblayer/common/crash_reporter/crash_keys.h b/weblayer/common/crash_reporter/crash_keys.h deleted file mode 100644 index 213fed9..0000000 --- a/weblayer/common/crash_reporter/crash_keys.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_COMMON_CRASH_REPORTER_CRASH_KEYS_H_ -#define WEBLAYER_COMMON_CRASH_REPORTER_CRASH_KEYS_H_ - -namespace weblayer { -namespace crash_keys { - -// Crash Key Name Constants //////////////////////////////////////////////////// - -// Application information. -extern const char kAppPackageName[]; -extern const char kAppPackageVersionCode[]; - -extern const char kAndroidSdkInt[]; - -extern const char kWeblayerWebViewCompatMode[]; - -extern const char* const kWebLayerCrashKeyAllowList[]; - -} // namespace crash_keys - -void SetWebLayerCrashKeys(); - -} // namespace weblayer - -#endif // WEBLAYER_COMMON_CRASH_REPORTER_CRASH_KEYS_H_
diff --git a/weblayer/common/crash_reporter/crash_reporter_client.cc b/weblayer/common/crash_reporter/crash_reporter_client.cc deleted file mode 100644 index 8fdaf07..0000000 --- a/weblayer/common/crash_reporter/crash_reporter_client.cc +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/common/crash_reporter/crash_reporter_client.h" - -#include <stdint.h> - -#include "base/android/java_exception_reporter.h" -#include "base/android/path_utils.h" -#include "base/base_paths_android.h" -#include "base/files/file_util.h" -#include "base/no_destructor.h" -#include "base/path_service.h" -#include "build/build_config.h" -#include "components/crash/core/app/crash_reporter_client.h" -#include "components/crash/core/app/crashpad.h" -#include "components/version_info/android/channel_getter.h" -#include "components/version_info/version_info.h" -#include "components/version_info/version_info_values.h" -#include "weblayer/common/crash_reporter/crash_keys.h" -#include "weblayer/common/weblayer_paths.h" - -namespace weblayer { - -namespace { - -class CrashReporterClientImpl : public crash_reporter::CrashReporterClient { - public: - CrashReporterClientImpl() = default; - - CrashReporterClientImpl(const CrashReporterClientImpl&) = delete; - CrashReporterClientImpl& operator=(const CrashReporterClientImpl&) = delete; - - // crash_reporter::CrashReporterClient implementation. - bool IsRunningUnattended() override { return false; } - bool GetCollectStatsConsent() override { return false; } - void GetProductNameAndVersion(std::string* product_name, - std::string* version, - std::string* channel) override { - *version = version_info::GetVersionNumber(); - *product_name = "WebLayer"; - *channel = - version_info::GetChannelString(version_info::android::GetChannel()); - } - - bool GetCrashDumpLocation(base::FilePath* crash_dir) override { - return base::PathService::Get(DIR_CRASH_DUMPS, crash_dir); - } - - void GetSanitizationInformation(const char* const** crash_key_allowlist, - void** target_module, - bool* sanitize_stacks) override { - *crash_key_allowlist = crash_keys::kWebLayerCrashKeyAllowList; -#if defined(COMPONENT_BUILD) - *target_module = nullptr; -#else - // The supplied address is used to identify the .so containing WebLayer. - *target_module = reinterpret_cast<void*>(&EnableCrashReporter); -#endif - *sanitize_stacks = true; - } - - static CrashReporterClientImpl* Get() { - static base::NoDestructor<CrashReporterClientImpl> crash_reporter_client; - return crash_reporter_client.get(); - } -}; - -} // namespace - -void EnableCrashReporter(const std::string& process_type) { - static bool enabled = false; - DCHECK(!enabled) << "EnableCrashReporter called more than once"; - - crash_reporter::SetCrashReporterClient(CrashReporterClientImpl::Get()); - crash_reporter::InitializeCrashpad(process_type.empty(), process_type); - if (process_type.empty()) - base::android::InitJavaExceptionReporter(); - else - base::android::InitJavaExceptionReporterForChildProcess(); - enabled = true; -} - -} // namespace weblayer
diff --git a/weblayer/common/crash_reporter/crash_reporter_client.h b/weblayer/common/crash_reporter/crash_reporter_client.h deleted file mode 100644 index 5b9132b9..0000000 --- a/weblayer/common/crash_reporter/crash_reporter_client.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_COMMON_CRASH_REPORTER_CRASH_REPORTER_CLIENT_H_ -#define WEBLAYER_COMMON_CRASH_REPORTER_CRASH_REPORTER_CLIENT_H_ - -#include <string> - -namespace weblayer { - -// Enable the collection of crashes for this process (of type |process_type|) -// via crashpad. This will collect both native crashes and uncaught Java -// exceptions as minidumps plus associated metadata. -void EnableCrashReporter(const std::string& process_type); - -} // namespace weblayer - -#endif // WEBLAYER_COMMON_CRASH_REPORTER_CRASH_REPORTER_CLIENT_H_
diff --git a/weblayer/common/error_page_helper.mojom b/weblayer/common/error_page_helper.mojom deleted file mode 100644 index a17551c..0000000 --- a/weblayer/common/error_page_helper.mojom +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module weblayer.mojom; - -// Used to control the renderer's ErrorPageHelper. -interface ErrorPageHelper { - // Used to disable the ErrorPageHelper for the next error. This is used when - // the embedder injects its own error page. - DisableErrorPageHelperForNextError(); -};
diff --git a/weblayer/common/features.cc b/weblayer/common/features.cc deleted file mode 100644 index 6eea683..0000000 --- a/weblayer/common/features.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/common/features.h" - -namespace weblayer { -namespace features { - -// Weblayer features in alphabetical order. - -// Client side phishing detection support for weblayer -BASE_FEATURE(kWebLayerClientSidePhishingDetection, - "WebLayerClientSidePhishingDetection", - base::FEATURE_DISABLED_BY_DEFAULT); - -// Safebrowsing support for weblayer. -BASE_FEATURE(kWebLayerSafeBrowsing, - "WebLayerSafeBrowsing", - base::FEATURE_ENABLED_BY_DEFAULT); - -} // namespace features -} // namespace weblayer
diff --git a/weblayer/common/features.h b/weblayer/common/features.h deleted file mode 100644 index 44e6e06..0000000 --- a/weblayer/common/features.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_COMMON_FEATURES_H_ -#define WEBLAYER_COMMON_FEATURES_H_ - -#include "base/feature_list.h" - -namespace weblayer { -namespace features { - -// Weblayer features in alphabetical order. - -BASE_DECLARE_FEATURE(kWebLayerClientSidePhishingDetection); -BASE_DECLARE_FEATURE(kWebLayerSafeBrowsing); - -} // namespace features -} // namespace weblayer - -#endif // WEBLAYER_COMMON_FEATURES_H_
diff --git a/weblayer/common/isolated_world_ids.h b/weblayer/common/isolated_world_ids.h deleted file mode 100644 index b01f1d0..0000000 --- a/weblayer/common/isolated_world_ids.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_COMMON_ISOLATED_WORLD_IDS_H_ -#define WEBLAYER_COMMON_ISOLATED_WORLD_IDS_H_ - -#include "content/public/common/isolated_world_ids.h" - -namespace weblayer { - -enum IsolatedWorldIDs { - // Isolated world ID for internal WebLayer features. - ISOLATED_WORLD_ID_WEBLAYER = content::ISOLATED_WORLD_ID_CONTENT_END + 1, - - // Isolated world ID for WebLayer translate. - ISOLATED_WORLD_ID_TRANSLATE, -}; - -} // namespace weblayer - -#endif // WEBLAYER_COMMON_ISOLATED_WORLD_IDS_H_
diff --git a/weblayer/common/renderer_configuration.mojom b/weblayer/common/renderer_configuration.mojom deleted file mode 100644 index 1fcd5e4..0000000 --- a/weblayer/common/renderer_configuration.mojom +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module weblayer.mojom; - -import "components/content_settings/common/content_settings_manager.mojom"; -import "components/content_settings/core/common/content_settings.mojom"; - -// Configures the renderer. -interface RendererConfiguration { - // Configures the renderer with settings that won't change. - // |content_settings_manager| may be sent as an optimization to avoid - // requesting it from the browser process, and may be null. - SetInitialConfiguration( - pending_remote<content_settings.mojom.ContentSettingsManager>? - content_settings_manager); -};
diff --git a/weblayer/common/weblayer_paths.cc b/weblayer/common/weblayer_paths.cc deleted file mode 100644 index cf9e367c..0000000 --- a/weblayer/common/weblayer_paths.cc +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/common/weblayer_paths.h" - -#include "base/environment.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/threading/thread_restrictions.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/path_utils.h" -#include "base/base_paths_android.h" -#endif - -#if BUILDFLAG(IS_WIN) -#include "base/base_paths_win.h" -#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) -#include "base/nix/xdg_util.h" -#endif - -namespace weblayer { - -namespace { - -bool GetDefaultUserDataDirectory(base::FilePath* result) { -#if BUILDFLAG(IS_ANDROID) - // No need to append "weblayer" here. It's done in java with - // PathUtils.setPrivateDataDirectorySuffix. - return base::PathService::Get(base::DIR_ANDROID_APP_DATA, result); -#elif BUILDFLAG(IS_WIN) - if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, result)) - return false; - *result = result->AppendASCII("weblayer"); - return true; -#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) - std::unique_ptr<base::Environment> env(base::Environment::Create()); - base::FilePath config_dir(base::nix::GetXDGDirectory( - env.get(), base::nix::kXdgConfigHomeEnvVar, base::nix::kDotConfigDir)); - *result = config_dir.AppendASCII("weblayer"); - return true; -#else - return false; -#endif -} - -} // namespace - -class WebLayerPathProvider { - public: - static void CreateDir(const base::FilePath& path) { - base::ScopedAllowBlocking allow_io; - if (!base::PathExists(path)) - base::CreateDirectory(path); - } -}; - -bool PathProvider(int key, base::FilePath* result) { - base::FilePath cur; - - switch (key) { - case DIR_USER_DATA: { - bool rv = GetDefaultUserDataDirectory(result); - if (rv) - WebLayerPathProvider::CreateDir(*result); - return rv; - } -#if BUILDFLAG(IS_ANDROID) - case DIR_CRASH_DUMPS: - if (!base::android::GetCacheDirectory(&cur)) - return false; - cur = cur.Append(FILE_PATH_LITERAL("Crashpad")); - WebLayerPathProvider::CreateDir(cur); - *result = cur; - return true; -#endif - default: - return false; - } -} - -void RegisterPathProvider() { - base::PathService::RegisterProvider(PathProvider, PATH_START, PATH_END); -} - -} // namespace weblayer
diff --git a/weblayer/common/weblayer_paths.h b/weblayer/common/weblayer_paths.h deleted file mode 100644 index 398a3cc..0000000 --- a/weblayer/common/weblayer_paths.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_COMMON_WEBLAYER_PATHS_H_ -#define WEBLAYER_COMMON_WEBLAYER_PATHS_H_ - -#include "build/build_config.h" - -// This file declares path keys for weblayer. These can be used with -// the PathService to access various special directories and files. - -namespace weblayer { - -enum { - PATH_START = 1000, - - DIR_USER_DATA = PATH_START, // Directory where user data can be written. - -#if BUILDFLAG(IS_ANDROID) - DIR_CRASH_DUMPS, // Directory where crash dumps are written. -#endif - - PATH_END -}; - -// Call once to register the provider for the path keys defined above. -void RegisterPathProvider(); - -} // namespace weblayer - -#endif // WEBLAYER_COMMON_WEBLAYER_PATHS_H_
diff --git a/weblayer/grit_resources_allowlist.txt b/weblayer/grit_resources_allowlist.txt deleted file mode 100644 index a5db135..0000000 --- a/weblayer/grit_resources_allowlist.txt +++ /dev/null
@@ -1,6 +0,0 @@ -IDR_ANDROID_INFOBAR_BLOCKED_POPUPS -IDR_SAD_PLUGIN -IDR_SAD_WEBVIEW -IDR_SECURITY_INTERSTITIAL_QUIET_HTML -IDR_SSL_ERROR_ASSISTANT_PB -IDR_TRANSLATE_JS
diff --git a/weblayer/grit_strings_allowlist.txt b/weblayer/grit_strings_allowlist.txt deleted file mode 100644 index 5c338e18..0000000 --- a/weblayer/grit_strings_allowlist.txt +++ /dev/null
@@ -1,301 +0,0 @@ -IDS_OK -IDS_RELOAD -IDS_BLOCKED_ADS_PROMPT_EXPLANATION -IDS_ALWAYS_ALLOW_ADS -IDS_BLOCKED_ADS_INFOBAR_MESSAGE -IDS_BLOCKED_ADS_MESSAGE_PRIMARY_TEXT -IDS_ACCESSIBILITY_EVENTS_INFOBAR_TEXT -IDS_ACCESSIBILITY_EVENTS_PERMISSION_FRAGMENT -IDS_AMBIENT_BADGE_INSTALL -IDS_AR_INFOBAR_TEXT -IDS_AR_PERMISSION_FRAGMENT -IDS_BEFORERELOAD_APP_MESSAGEBOX_TITLE -IDS_BEFORERELOAD_MESSAGEBOX_TITLE -IDS_BEFOREUNLOAD_APP_MESSAGEBOX_TITLE -IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE -IDS_BLUETOOTH_DEVICE_AUDIO -IDS_BLUETOOTH_DEVICE_CAR_AUDIO -IDS_BLUETOOTH_DEVICE_COMPUTER -IDS_BLUETOOTH_DEVICE_GAMEPAD -IDS_BLUETOOTH_DEVICE_JOYSTICK -IDS_BLUETOOTH_DEVICE_KEYBOARD -IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO -IDS_BLUETOOTH_DEVICE_MODEM -IDS_BLUETOOTH_DEVICE_MOUSE -IDS_BLUETOOTH_DEVICE_PHONE -IDS_BLUETOOTH_DEVICE_TABLET -IDS_BLUETOOTH_DEVICE_UNKNOWN -IDS_BLUETOOTH_DEVICE_VIDEO -IDS_CANCEL -IDS_CAPTIVE_PORTAL_BUTTON_OPEN_LOGIN_PAGE -IDS_CAPTIVE_PORTAL_HEADING_WIFI -IDS_CAPTIVE_PORTAL_HEADING_WIRED -IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI -IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI_SSID -IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIRED -IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI -IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI_SSID -IDS_CERT_DETAILS_EXTENSIONS -IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION -IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS -IDS_CERT_ERROR_CERTIFICATE_TRANSPARENCY_REQUIRED_DESCRIPTION -IDS_CERT_ERROR_CERTIFICATE_TRANSPARENCY_REQUIRED_DETAILS -IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION -IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS -IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION -IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS -IDS_CERT_ERROR_EXPIRED_DESCRIPTION -IDS_CERT_ERROR_EXPIRED_DETAILS -IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION -IDS_CERT_ERROR_INVALID_CERT_DETAILS -IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DESCRIPTION -IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DETAILS -IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DESCRIPTION -IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DETAILS -IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION -IDS_CERT_ERROR_NOT_YET_VALID_DETAILS -IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION -IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS -IDS_CERT_ERROR_NO_SUBJECT_ALTERNATIVE_NAMES_DETAILS -IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION -IDS_CERT_ERROR_REVOKED_CERT_DETAILS -IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DESCRIPTION -IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DETAILS -IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION -IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS -IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION -IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS -IDS_CERT_ERROR_VALIDITY_TOO_LONG_DESCRIPTION -IDS_CERT_ERROR_VALIDITY_TOO_LONG_DETAILS -IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION -IDS_CERT_ERROR_WEAK_KEY_DETAILS -IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION -IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS -IDS_CERT_INFO_COMMON_NAME_LABEL -IDS_CERT_INFO_EXPIRES_ON_LABEL -IDS_CERT_INFO_FINGERPRINTS_GROUP -IDS_CERT_INFO_ISSUED_ON_LABEL -IDS_CERT_INFO_ISSUER_GROUP -IDS_CERT_INFO_ORGANIZATIONAL_UNIT_LABEL -IDS_CERT_INFO_ORGANIZATION_LABEL -IDS_CERT_INFO_SERIAL_NUMBER_LABEL -IDS_CERT_INFO_SHA256_SPKI_FINGERPRINT_LABEL -IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL -IDS_CERT_INFO_SUBJECT_GROUP -IDS_CERT_INFO_VALIDITY_GROUP -IDS_CERT_X509_SUBJECT_ALT_NAME -IDS_CLIPBOARD_INFOBAR_TEXT -IDS_CLIPBOARD_PERMISSION_FRAGMENT -IDS_CLOCK_ERROR_AHEAD_HEADING -IDS_CLOCK_ERROR_BEHIND_HEADING -IDS_CLOCK_ERROR_EXPLANATION -IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH -IDS_CLOCK_ERROR_TITLE -IDS_CLOCK_ERROR_UPDATE_DATE_AND_TIME -IDS_DEFAULT_ENCODING -IDS_DOWNLOAD_NOTIFICATION_CANCEL_BUTTON -IDS_DOWNLOAD_NOTIFICATION_COMPLETED -IDS_DOWNLOAD_NOTIFICATION_COMPLETED_WITH_SIZE -IDS_DOWNLOAD_NOTIFICATION_FAILED -IDS_DOWNLOAD_NOTIFICATION_PAUSED -IDS_DOWNLOAD_NOTIFICATION_PAUSE_BUTTON -IDS_DOWNLOAD_NOTIFICATION_RESUME_BUTTON -IDS_DOWNLOAD_UI_DETERMINATE_BYTES -IDS_DOWNLOAD_UI_GB -IDS_DOWNLOAD_UI_INDETERMINATE_BYTES -IDS_DOWNLOAD_UI_KB -IDS_DOWNLOAD_UI_MB -IDS_FLASH_PERMISSION_FRAGMENT -IDS_FLASH_PERMISSION_WARNING_FRAGMENT -IDS_GEOLOCATION_INFOBAR_PERMISSION_FRAGMENT -IDS_GEOLOCATION_INFOBAR_TEXT -IDS_GEOLOCATION_INFOBAR_TEXT -IDS_HEAVY_AD_INTERVENTION_BUTTON_DETAILS -IDS_HEAVY_AD_INTERVENTION_HEADING -IDS_HEAVY_AD_INTERVENTION_SUMMARY -IDS_HTTP_POST_WARNING -IDS_HTTP_POST_WARNING_RESEND -IDS_HTTP_POST_WARNING_TITLE -IDS_INSECURE_FORM_TITLE -IDS_INSECURE_FORM_HEADING -IDS_INSECURE_FORM_PRIMARY_PARAGRAPH -IDS_INSECURE_FORM_SUBMIT_BUTTON -IDS_INSECURE_FORM_BACK_BUTTON -IDS_JAVASCRIPT_MESSAGEBOX_TITLE -IDS_JAVASCRIPT_MESSAGEBOX_TITLE_IFRAME -IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL -IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL_IFRAME -IDS_LOGIN_DIALOG_OK_BUTTON_LABEL -IDS_LOGIN_DIALOG_PASSWORD_FIELD -IDS_LOGIN_DIALOG_TITLE -IDS_LOGIN_DIALOG_USERNAME_FIELD -IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_INFOBAR_TEXT -IDS_MEDIA_CAPTURE_AUDIO_ONLY_INFOBAR_TEXT -IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT -IDS_MEDIA_CAPTURE_VIDEO_ONLY_INFOBAR_TEXT -IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT -IDS_MIDI_SYSEX_INFOBAR_TEXT -IDS_MIDI_SYSEX_PERMISSION_FRAGMENT -IDS_NFC_INFOBAR_TEXT -IDS_NOTIFICATIONS_INFOBAR_TEXT -IDS_NOTIFICATION_PERMISSIONS_FRAGMENT -IDS_NOTIFICATION_QUIET_PERMISSION_PROMPT_MESSAGE -IDS_NOTIFICATION_QUIET_PERMISSION_PROMPT_TITLE -IDS_PAGE_INFO_BILLING_DETAILS -IDS_PAGE_INFO_BILLING_SUMMARY -IDS_PAGE_INFO_BLUETOOTH_DEVICE_SECONDARY_LABEL -IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_DEFAULT -IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_USER -IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_DEFAULT -IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_USER -IDS_PAGE_INFO_BUTTON_TEXT_AUTOMATIC_BY_DEFAULT -IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_DEFAULT -IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_USER -IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_DEFAULT -IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_USER -IDS_PAGE_INFO_BUTTON_TEXT_MUTED_BY_DEFAULT -IDS_PAGE_INFO_BUTTON_TEXT_MUTED_BY_USER -IDS_PAGE_INFO_CERT_INFO_BUTTON -IDS_PAGE_INFO_DELETE_BLUETOOTH_DEVICE -IDS_PAGE_INFO_DELETE_SERIAL_PORT -IDS_PAGE_INFO_DELETE_USB_DEVICE -IDS_PAGE_INFO_HELP_CENTER_LINK -IDS_PAGE_INFO_INTERNAL_PAGE -IDS_PAGE_INFO_LEGACY_TLS_DETAILS -IDS_PAGE_INFO_MALWARE_DETAILS -IDS_PAGE_INFO_MALWARE_SUMMARY -IDS_PAGE_INFO_MIXED_CONTENT_DETAILS -IDS_PAGE_INFO_MIXED_CONTENT_SUMMARY -IDS_PAGE_INFO_MIXED_CONTENT_SUMMARY_SHORT -IDS_PAGE_INFO_NOT_SECURE_DETAILS -IDS_PAGE_INFO_NOT_SECURE_SUMMARY -IDS_PAGE_INFO_NOT_SECURE_SUMMARY_SHORT -IDS_PAGE_INFO_PERMISSION_ADS_SUBTITLE -IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_EXTENSION -IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_POLICY -IDS_PAGE_INFO_PERMISSION_ASK_BY_EXTENSION -IDS_PAGE_INFO_PERMISSION_ASK_BY_POLICY -IDS_PAGE_INFO_PERMISSION_AUTOMATICALLY_BLOCKED -IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_EXTENSION -IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_POLICY -IDS_PAGE_INFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON -IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_DESCRIPTION -IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_TITL -IDS_PAGE_INFO_SAFETY_TIP_LOOKALIKE_DESCRIPTION -IDS_PAGE_INFO_SAFETY_TIP_LOOKALIKE_TITLE -IDS_PAGE_INFO_SECURE_DETAILS -IDS_PAGE_INFO_SECURE_IDENTITY_VERIFIED -IDS_PAGE_INFO_SECURE_SUMMARY -IDS_PAGE_INFO_SECURITY_TAB_DEPRECATED_SIGNATURE_ALGORITHM -IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT -IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR -IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING -IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_FORM_WARNING -IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK -IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS -IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD -IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY -IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME -IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT -IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION -IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY -IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT -IDS_PAGE_INFO_SERIAL_PORT_SECONDARY_LABEL -IDS_PAGE_INFO_SOCIAL_ENGINEERING_DETAILS -IDS_PAGE_INFO_SOCIAL_ENGINEERING_SUMMARY -IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS -IDS_PAGE_INFO_UNWANTED_SOFTWARE_SUMMARY -IDS_PAGE_INFO_USB_DEVICE_ALLOWED_BY_POLICY_LABEL -IDS_PAGE_INFO_USB_DEVICE_SECONDARY_LABEL -IDS_PERMISSION_ALLOW -IDS_PERMISSION_DENY -IDS_POPUPS_BLOCKED_INFOBAR_BUTTON_SHOW -IDS_POPUPS_BLOCKED_INFOBAR_TEXT -IDS_PROTECTED_MEDIA_IDENTIFIER_PERMISSION_FRAGMENT -IDS_PROTECTED_MEDIA_IDENTIFIER_PER_ORIGIN_PROVISIONING_INFOBAR_TEXT -IDS_REQUEST_LARGE_QUOTA_INFOBAR_TEXT -IDS_REQUEST_QUOTA_INFOBAR_TEXT -IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT -IDS_SAFE_BROWSING_ENHANCED_PROTECTION_MESSAGE -IDS_SAFE_BROWSING_SCOUT_REPORTING_AGREE -IDS_SITE_SETTINGS_TYPE_ADS -IDS_SITE_SETTINGS_TYPE_ADS_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_AR -IDS_SITE_SETTINGS_TYPE_AR_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS -IDS_SITE_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_BACKGROUND_SYNC -IDS_SITE_SETTINGS_TYPE_BACKGROUND_SYNC_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_BLUETOOTH_DEVICES -IDS_SITE_SETTINGS_TYPE_BLUETOOTH_DEVICES_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_BLUETOOTH_SCANNING -IDS_SITE_SETTINGS_TYPE_BLUETOOTH_SCANNING_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_CAMERA -IDS_SITE_SETTINGS_TYPE_CAMERA_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_CAMERA_PAN_TILT_ZOOM -IDS_SITE_SETTINGS_TYPE_CAMERA_PAN_TILT_ZOOM_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_CLIPBOARD -IDS_SITE_SETTINGS_TYPE_CLIPBOARD_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_IMAGES -IDS_SITE_SETTINGS_TYPE_IMAGES_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_JAVASCRIPT -IDS_SITE_SETTINGS_TYPE_JAVASCRIPT_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_LOCATION -IDS_SITE_SETTINGS_TYPE_LOCATION_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_MIC -IDS_SITE_SETTINGS_TYPE_MIC_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_MIDI_SYSEX -IDS_SITE_SETTINGS_TYPE_MIDI_SYSEX_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_MOTION_SENSORS -IDS_SITE_SETTINGS_TYPE_MOTION_SENSORS_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_FILE_SYSTEM_ACCESS_WRITE -IDS_SITE_SETTINGS_TYPE_FILE_SYSTEM_ACCESS_WRITE_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_NFC -IDS_SITE_SETTINGS_TYPE_NFC_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_NOTIFICATIONS -IDS_SITE_SETTINGS_TYPE_NOTIFICATIONS_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_POPUPS_REDIRECTS -IDS_SITE_SETTINGS_TYPE_POPUPS_REDIRECTS_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_PROTECTED_MEDIA_ID -IDS_SITE_SETTINGS_TYPE_PROTECTED_MEDIA_ID_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_SENSORS -IDS_SITE_SETTINGS_TYPE_SENSORS_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_SERIAL_PORTS -IDS_SITE_SETTINGS_TYPE_SERIAL_PORTS_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_SOUND -IDS_SITE_SETTINGS_TYPE_SOUND_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_USB_DEVICES -IDS_SITE_SETTINGS_TYPE_USB_DEVICES_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_VR -IDS_SITE_SETTINGS_TYPE_VR_MID_SENTENCE -IDS_SITE_SETTINGS_TYPE_WINDOW_MANAGEMENT -IDS_SITE_SETTINGS_TYPE_WINDOW_MANAGEMENT_MID_SENTENCE -IDS_SMS_INFOBAR_BUTTON_OK -IDS_SMS_INFOBAR_STATUS_SMS_RECEIVED -IDS_SMS_INFOBAR_TITLE -IDS_SSL_CLOSE_DETAILS_BUTTON -IDS_SSL_NONOVERRIDABLE_HSTS -IDS_SSL_NONOVERRIDABLE_INVALID -IDS_SSL_NONOVERRIDABLE_MORE -IDS_SSL_NONOVERRIDABLE_PINNED -IDS_SSL_NONOVERRIDABLE_REVOKED -IDS_SSL_OPEN_DETAILS_BUTTON -IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH -IDS_SSL_OVERRIDABLE_SAFETY_BUTTON -IDS_SSL_RELOAD -IDS_SSL_V2_HEADING -IDS_SSL_V2_PRIMARY_PARAGRAPH -IDS_SSL_V2_RECURRENT_ERROR_PARAGRAPH -IDS_SSL_V2_TITLE -IDS_STORAGE_ACCESS_INFOBAR_TEXT -IDS_STORAGE_ACCESS_PERMISSION_FRAGMENT -IDS_TRANSLATE_BUTTON -IDS_TRANSLATE_DETECTED_LANGUAGE -IDS_TRANSLATE_INFOBAR_ERROR -IDS_TRANSLATE_NEVER_TRANSLATE_SITE -IDS_TRANSLATE_OPTION_ALWAYS_TRANSLATE -IDS_TRANSLATE_OPTION_MORE_LANGUAGE -IDS_TRANSLATE_OPTION_NEVER_TRANSLATE -IDS_TRANSLATE_OPTION_NOT_SOURCE_LANGUAGE -IDS_VR_INFOBAR_TEXT -IDS_VR_PERMISSION_FRAGMENT
diff --git a/weblayer/public/OWNERS b/weblayer/public/OWNERS deleted file mode 100644 index 14595c8a..0000000 --- a/weblayer/public/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -set noparent -file://weblayer/API_OWNERS
diff --git a/weblayer/public/README.md b/weblayer/public/README.md deleted file mode 100644 index 169252ab..0000000 --- a/weblayer/public/README.md +++ /dev/null
@@ -1,60 +0,0 @@ -# WebEngine public API - -This directory contains the public API for WebEngine. WebEngine provides both a -C++ and Java API. Note that while WebEngine's implementation builds on top of -//content, its public API does *not* expose the Content API. - -Note: The WebEngine API is still under development and should not be depended -upon directly. It will become available through an Android Jetpack Library. - -## Java API - -In general, the Java API is a thin veneer over the C++ API. For the most part, -functionality should be added to the C++ side with the Java implementation -calling into it. Where the two APIs diverge is for platform specific -functionality. For example, the Java API uses Android Fragments, which do not -apply to the C++ side. - -The public API should follow the Android API guidelines -(https://goto.google.com/android-api-guidelines). This results in naming -differences between the C++ and Java code. For example, NewTabDelegate in C++ -vs NewTabCallback in Java. - -One of the design constraints of WebEngine's Java implementation is that we do -not want embedders to ship their own copy of "//content". Instead, the -implementation is loaded from the WebView APK (not the Chrome APK, because the -WebView APK is available on more devices). This constraint results in the Java -implementation consisting of three distinct parts. - -### Java client library - -Code lives in "//weblayer/public/java". This is the code used by embedders. The -client library contains very little logic, rather it delegates to the Java -implementation over AIDL. - -This code should not have any dependencies on any other code in the chrome repo. - -The embedders can use the API surface defined in the `org.chromium.webengine` -package. It spins up an Android Service running the code in the -`org.chromium.weblayer` package. The Service is responsible for loading the -implementation from the WebView APK. - -### Java AIDL - -This is best thought of as WebEngine's ABI (for Java). - -The client library loads the WebEngine implementation from WebView APK and uses -AIDL for the IPC. The aidl interfaces are defined in -"//weblayer/browser/java/org/chromium/weblayer_private/interfaces". AIDL is used -to enable the implementation to be loaded using a different ClassLoader than -the embedder. - -In general, any interface ending with 'Client' means the interface is from the -implementation side to the client library. An interface without 'Client' is -from the client to the implementation. - -### Java implementation - -This is often referred to as the 'implementation' of the Java API. This is -where the bulk of the Java code lives and sits on top of the C++ API. The code -for this lives in "//weblayer/browser/java".
diff --git a/weblayer/public/browser.cc b/weblayer/public/browser.cc deleted file mode 100644 index 6db95a8..0000000 --- a/weblayer/public/browser.cc +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/public/browser.h" - -namespace weblayer { - -Browser::PersistenceInfo::PersistenceInfo() = default; - -Browser::PersistenceInfo::PersistenceInfo(const PersistenceInfo& other) = - default; - -Browser::PersistenceInfo::~PersistenceInfo() = default; - -} // namespace weblayer
diff --git a/weblayer/public/browser.h b/weblayer/public/browser.h deleted file mode 100644 index bc3c2040..0000000 --- a/weblayer/public/browser.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_BROWSER_H_ -#define WEBLAYER_PUBLIC_BROWSER_H_ - -#include <stddef.h> - -#include <memory> -#include <string> -#include <vector> - -namespace weblayer { - -class BrowserObserver; -class BrowserRestoreObserver; -class Profile; -class Tab; - -// Represents an ordered list of Tabs, with one active. Browser does not own -// the set of Tabs. -class Browser { - public: - struct PersistenceInfo { - PersistenceInfo(); - PersistenceInfo(const PersistenceInfo& other); - ~PersistenceInfo(); - - // Uniquely identifies this browser for session restore, empty is not a - // valid id. - std::string id; - - // Last key used to encrypt incognito profile. - std::vector<uint8_t> last_crypto_key; - }; - - // Creates a new Browser. |persistence_info|, if non-null, is used for saving - // and restoring the state of the browser. - static std::unique_ptr<Browser> Create( - Profile* profile, - const PersistenceInfo* persistence_info); - - virtual ~Browser() {} - - virtual void AddTab(Tab* tab) = 0; - virtual void DestroyTab(Tab* tab) = 0; - virtual void SetActiveTab(Tab* tab) = 0; - virtual Tab* GetActiveTab() = 0; - virtual std::vector<Tab*> GetTabs() = 0; - - // Creates a tab attached to this browser. The returned tab is owned by the - // browser. - virtual Tab* CreateTab() = 0; - - // Called early on in shutdown, before any tabs have been removed. - virtual void PrepareForShutdown() = 0; - - // Returns the id supplied to Create() that is used for persistence. - virtual std::string GetPersistenceId() = 0; - - // Returns true if this Browser is in the process of restoring the previous - // state. - virtual bool IsRestoringPreviousState() = 0; - - virtual void AddObserver(BrowserObserver* observer) = 0; - virtual void RemoveObserver(BrowserObserver* observer) = 0; - - virtual void AddBrowserRestoreObserver(BrowserRestoreObserver* observer) = 0; - virtual void RemoveBrowserRestoreObserver( - BrowserRestoreObserver* observer) = 0; - - virtual void VisibleSecurityStateOfActiveTabChanged() = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_BROWSER_H_
diff --git a/weblayer/public/browser_observer.h b/weblayer/public/browser_observer.h deleted file mode 100644 index 462cb259..0000000 --- a/weblayer/public/browser_observer.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_BROWSER_OBSERVER_H_ -#define WEBLAYER_PUBLIC_BROWSER_OBSERVER_H_ - -#include "base/observer_list_types.h" - -namespace weblayer { - -class Tab; - -class BrowserObserver : public base::CheckedObserver { - public: - // A Tab has been been added to the Browser. - virtual void OnTabAdded(Tab* tab) {} - - // A Tab has been removed from the Browser. |active_tab_changed| indicates - // if the active tab changed as a result. If the active tab changed, - // OnActiveTabChanged() is also called. - virtual void OnTabRemoved(Tab* tab, bool active_tab_changed) {} - - // The tab the user is interacting with has changed. |tab| may be null if no - // tabs are active. - virtual void OnActiveTabChanged(Tab* tab) {} - - protected: - ~BrowserObserver() override {} -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_BROWSER_OBSERVER_H_
diff --git a/weblayer/public/browser_restore_observer.h b/weblayer/public/browser_restore_observer.h deleted file mode 100644 index ac8068e..0000000 --- a/weblayer/public/browser_restore_observer.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_BROWSER_RESTORE_OBSERVER_H_ -#define WEBLAYER_PUBLIC_BROWSER_RESTORE_OBSERVER_H_ - -#include "base/observer_list_types.h" - -namespace weblayer { - -// Used for observing events related to restoring the previous state of a -// Browser. -class BrowserRestoreObserver : public base::CheckedObserver { - public: - // Called when the Browser has completed restoring the previous state. - virtual void OnRestoreCompleted() {} - - protected: - ~BrowserRestoreObserver() override = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_BROWSER_RESTORE_OBSERVER_H_
diff --git a/weblayer/public/common/switches.cc b/weblayer/public/common/switches.cc deleted file mode 100644 index c76310c..0000000 --- a/weblayer/public/common/switches.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/public/common/switches.h" - -namespace weblayer { -namespace switches { - -// Makes WebEngine Shell use the given path for its data directory. -// NOTE: If changing this value, change the corresponding Java-side value in -// WebLayerBrowserTestsActivity.java#getUserDataDirectoryCommandLineSwitch() to -// match. -const char kWebEngineUserDataDir[] = "webengine-user-data-dir"; - -} // namespace switches -} // namespace weblayer
diff --git a/weblayer/public/common/switches.h b/weblayer/public/common/switches.h deleted file mode 100644 index 12fefe3..0000000 --- a/weblayer/public/common/switches.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_COMMON_SWITCHES_H_ -#define WEBLAYER_PUBLIC_COMMON_SWITCHES_H_ - -namespace weblayer { -namespace switches { - -extern const char kWebEngineUserDataDir[]; - -} // namespace switches -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_COMMON_SWITCHES_H_
diff --git a/weblayer/public/cookie_manager.h b/weblayer/public/cookie_manager.h deleted file mode 100644 index 4308da4c..0000000 --- a/weblayer/public/cookie_manager.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_COOKIE_MANAGER_H_ -#define WEBLAYER_PUBLIC_COOKIE_MANAGER_H_ - -#include <string> - -#include "base/callback_list.h" - -class GURL; - -namespace net { -struct CookieChangeInfo; -} - -namespace weblayer { - -class CookieManager { - public: - virtual ~CookieManager() = default; - - // Sets a cookie for the given URL. - using SetCookieCallback = base::OnceCallback<void(bool)>; - virtual void SetCookie(const GURL& url, - const std::string& value, - SetCookieCallback callback) = 0; - - // Gets the cookies for the given URL. - using GetCookieCallback = base::OnceCallback<void(const std::string&)>; - virtual void GetCookie(const GURL& url, GetCookieCallback callback) = 0; - - // Gets the cookies for the given URL in the form of the 'Set-Cookie' HTTP - // response header. - using GetResponseCookiesCallback = - base::OnceCallback<void(const std::vector<std::string>&)>; - virtual void GetResponseCookies(const GURL& url, - GetResponseCookiesCallback callback) = 0; - - // Adds a callback to listen for changes to cookies for the given URL. - using CookieChangedCallbackList = - base::RepeatingCallbackList<void(const net::CookieChangeInfo&)>; - using CookieChangedCallback = CookieChangedCallbackList::CallbackType; - virtual base::CallbackListSubscription AddCookieChangedCallback( - const GURL& url, - const std::string* name, - CookieChangedCallback callback) = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_COOKIE_MANAGER_H_
diff --git a/weblayer/public/download.h b/weblayer/public/download.h deleted file mode 100644 index 7c8c806..0000000 --- a/weblayer/public/download.h +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_DOWNLOAD_H_ -#define WEBLAYER_PUBLIC_DOWNLOAD_H_ - -#include <string> - -namespace base { -class FilePath; -} - -namespace weblayer { - -// These types are sent over IPC and across different versions. Never remove -// or change the order. -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private -// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplDownloadState -enum class DownloadState { - // Download is actively progressing. - kInProgress = 0, - // Download is completely finished. - kComplete = 1, - // Download is paused by the user. - kPaused = 2, - // Download has been cancelled by the user. - kCancelled = 3, - // Download has failed (e.g. server or connection problem). - kFailed = 4, -}; - -// These types are sent over IPC and across different versions. Never remove -// or change the order. -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private -// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplDownloadError -enum class DownloadError { - kNoError = 0, // Download completed successfully. - kServerError = 1, // Server failed, e.g. unauthorized or forbidden, - // server unreachable, - kSSLError = 2, // Certificate error. - kConnectivityError = 3, // A network error occur. e.g. disconnected, timed - // out, invalid request. - kNoSpace = 4, // There isn't enough room in the storage location. - kFileError = 5, // Various errors related to file access. e.g. - // access denied, directory or filename too long, - // file is too large for file system, file in use, - // too many files open at once etc... - kCancelled = 6, // The user cancelled the download. - kOtherError = 7, // An error not listed above occurred. -}; - -// Contains information about a single download that's in progress. -class Download { - public: - virtual ~Download() {} - - virtual DownloadState GetState() = 0; - - // Returns the total number of expected bytes. Returns -1 if the total size is - // not known. - virtual int64_t GetTotalBytes() = 0; - - // Total number of bytes that have been received and written to the download - // file. - virtual int64_t GetReceivedBytes() = 0; - - // Pauses the download. - virtual void Pause() = 0; - - // Resumes the download. - virtual void Resume() = 0; - - // Cancels the download. - virtual void Cancel() = 0; - - // Returns the location of the downloaded file. This may be empty if the - // target path hasn't been determined yet. The file it points to won't be - // available until the download completes successfully. - virtual base::FilePath GetLocation() = 0; - - // Returns the display name for the download. - virtual std::u16string GetFileNameToReportToUser() = 0; - - // Returns the effective MIME type of downloaded content. - virtual std::string GetMimeType() = 0; - - // Return information about the error, if any, that was encountered during the - // download. - virtual DownloadError GetError() = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_DOWNLOAD_H_
diff --git a/weblayer/public/download_delegate.h b/weblayer/public/download_delegate.h deleted file mode 100644 index 070755c..0000000 --- a/weblayer/public/download_delegate.h +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_DOWNLOAD_DELEGATE_H_ -#define WEBLAYER_PUBLIC_DOWNLOAD_DELEGATE_H_ - -#include <string> - -#include "base/functional/callback_forward.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "url/origin.h" - -class GURL; - -namespace weblayer { -class Download; -class Tab; - -using AllowDownloadCallback = base::OnceCallback<void(bool /*allow*/)>; - -// An interface that allows clients to handle download requests originating in -// the browser. The object is safe to hold on to until DownloadCompleted or -// DownloadFailed are called. -class DownloadDelegate { - public: - // Gives the embedder the opportunity to asynchronously allow or disallow the - // given download. The download is paused until the callback is run. It's safe - // to run |callback| synchronously. - virtual void AllowDownload(Tab* tab, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - AllowDownloadCallback callback) = 0; - - // A download of |url| has been requested with the specified details. If - // it returns true the download will be considered intercepted and WebLayer - // won't proceed with it. Note that there are many corner cases where the - // embedder downloading it won't work (e.g. POSTs, one-time URLs, requests - // that depend on cookies or auth state). This is called after AllowDownload. - virtual bool InterceptDownload(const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - int64_t content_length) = 0; - - // A download has started. There will be 0..n calls to - // DownloadProgressChanged, then either a call to DownloadCompleted or - // DownloadFailed. - virtual void DownloadStarted(Download* download) {} - - // The progress percentage of a download has changed. - virtual void DownloadProgressChanged(Download* download) {} - - // A download has completed successfully. - virtual void DownloadCompleted(Download* download) {} - - // A download has failed because the user cancelled it or because of a server - // or network error. - virtual void DownloadFailed(Download* download) {} - - protected: - virtual ~DownloadDelegate() {} -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_DOWNLOAD_DELEGATE_H_
diff --git a/weblayer/public/error_page.h b/weblayer/public/error_page.h deleted file mode 100644 index a86035c6..0000000 --- a/weblayer/public/error_page.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_ERROR_PAGE_H_ -#define WEBLAYER_PUBLIC_ERROR_PAGE_H_ - -#include <string> - -namespace weblayer { - -// Contains the html to show when an error is encountered. -struct ErrorPage { - std::string html; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_ERROR_PAGE_H_
diff --git a/weblayer/public/error_page_delegate.h b/weblayer/public/error_page_delegate.h deleted file mode 100644 index 185bfdf..0000000 --- a/weblayer/public/error_page_delegate.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_ERROR_PAGE_DELEGATE_H_ -#define WEBLAYER_PUBLIC_ERROR_PAGE_DELEGATE_H_ - -#include <memory> - -namespace weblayer { - -struct ErrorPage; -class Navigation; - -// An interface that allows handling of interactions with error pages (such as -// SSL interstitials). If this interface is not used, default actions will be -// taken. -class ErrorPageDelegate { - public: - // The user has pressed "back to safety" on a blocking page. A return value of - // true will cause WebLayer to skip the default action. - virtual bool OnBackToSafety() = 0; - - // Returns the html to shown when an error is encountered. A null return value - // results in showing the default error page. |navigation| is the Navigation - // that encountered the error. - virtual std::unique_ptr<ErrorPage> GetErrorPageContent( - Navigation* navigation) = 0; - - protected: - virtual ~ErrorPageDelegate() = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_ERROR_PAGE_DELEGATE_H_
diff --git a/weblayer/public/favicon_fetcher.h b/weblayer/public/favicon_fetcher.h deleted file mode 100644 index 158e125..0000000 --- a/weblayer/public/favicon_fetcher.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_FAVICON_FETCHER_H_ -#define WEBLAYER_PUBLIC_FAVICON_FETCHER_H_ - -namespace gfx { -class Image; -} - -namespace weblayer { - -// FaviconFetcher is responsible for downloading a favicon for the current -// navigation. FaviconFetcher caches favicons, updating the cache every so -// often to ensure the cache is up to date. -class FaviconFetcher { - public: - virtual ~FaviconFetcher() = default; - - // Returns the favicon for the current navigation, which may be empty. - virtual gfx::Image GetFavicon() = 0; - - protected: - FaviconFetcher() = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_FAVICON_FETCHER_H_
diff --git a/weblayer/public/favicon_fetcher_delegate.h b/weblayer/public/favicon_fetcher_delegate.h deleted file mode 100644 index b881561..0000000 --- a/weblayer/public/favicon_fetcher_delegate.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_FAVICON_FETCHER_DELEGATE_H_ -#define WEBLAYER_PUBLIC_FAVICON_FETCHER_DELEGATE_H_ - -#include "base/observer_list_types.h" - -namespace gfx { -class Image; -} - -namespace weblayer { - -// Notified of interesting events related to FaviconFetcher. -class FaviconFetcherDelegate : public base::CheckedObserver { - public: - // Called when the favicon of the current navigation has changed. This may be - // called multiple times for the same navigation. - virtual void OnFaviconChanged(const gfx::Image& image) = 0; - - protected: - ~FaviconFetcherDelegate() override = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_FAVICON_FETCHER_DELEGATE_H_
diff --git a/weblayer/public/fullscreen_delegate.h b/weblayer/public/fullscreen_delegate.h deleted file mode 100644 index 428b7df0..0000000 --- a/weblayer/public/fullscreen_delegate.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_FULLSCREEN_DELEGATE_H_ -#define WEBLAYER_PUBLIC_FULLSCREEN_DELEGATE_H_ - -#include "base/functional/callback_forward.h" - -namespace weblayer { - -class FullscreenDelegate { - public: - // Called when the page has requested to go fullscreen. - virtual void EnterFullscreen(base::OnceClosure exit_closure) = 0; - - // Informs the delegate the page has exited fullscreen. - virtual void ExitFullscreen() = 0; - - protected: - virtual ~FullscreenDelegate() {} -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_FULLSCREEN_DELEGATE_H_
diff --git a/weblayer/public/google_account_access_token_fetch_delegate.h b/weblayer/public/google_account_access_token_fetch_delegate.h deleted file mode 100644 index 2ba3813..0000000 --- a/weblayer/public/google_account_access_token_fetch_delegate.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_GOOGLE_ACCOUNT_ACCESS_TOKEN_FETCH_DELEGATE_H_ -#define WEBLAYER_PUBLIC_GOOGLE_ACCOUNT_ACCESS_TOKEN_FETCH_DELEGATE_H_ - -#include <set> -#include <string> - -#include "base/functional/callback_forward.h" - -namespace weblayer { - -using OnTokenFetchedCallback = - base::OnceCallback<void(const std::string& token)>; - -// An interface that allows clients to handle access token requests for Google -// accounts originating in the browser. -class GoogleAccountAccessTokenFetchDelegate { - public: - // Called when the WebLayer implementation wants to fetch an access token for - // the embedder's current GAIA account (if any) and the given scopes. The - // client should invoke |onTokenFetchedCallback| when its internal token fetch - // is complete, passing either the fetched access token or the empty string in - // the case of failure (e.g., if there is no current GAIA account or there was - // an error in the token fetch). - // - // NOTE: WebLayer will not perform any caching of the returned token but will - // instead make a new request each time that it needs to use an access token. - // The expectation is that the client will use caching internally to minimize - // latency of these requests. - virtual void FetchAccessToken(const std::set<std::string>& scopes, - OnTokenFetchedCallback callback) = 0; - - // Called when a token previously obtained via a call to - // FetchAccessToken(|scopes|) is identified as invalid, so the embedder can - // take appropriate action (e.g., dropping the token from its cache and/or - // force-fetching a new token). - virtual void OnAccessTokenIdentifiedAsInvalid( - const std::set<std::string>& scopes, - const std::string& token) = 0; - - protected: - virtual ~GoogleAccountAccessTokenFetchDelegate() {} -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_GOOGLE_ACCOUNT_ACCESS_TOKEN_FETCH_DELEGATE_H_
diff --git a/weblayer/public/google_accounts_delegate.h b/weblayer/public/google_accounts_delegate.h deleted file mode 100644 index 3aa9ea9b..0000000 --- a/weblayer/public/google_accounts_delegate.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_GOOGLE_ACCOUNTS_DELEGATE_H_ -#define WEBLAYER_PUBLIC_GOOGLE_ACCOUNTS_DELEGATE_H_ - -#include <string> - -namespace signin { -struct ManageAccountsParams; -} - -namespace weblayer { - -// Used to intercept interaction with GAIA accounts. -class GoogleAccountsDelegate { - public: - // Called when a user wants to change the state of their GAIA account. This - // could be a signin, signout, or any other action. See - // signin::GAIAServiceType for all the possible actions. - virtual void OnGoogleAccountsRequest( - const signin::ManageAccountsParams& params) = 0; - - // The current GAIA ID the user is signed in with, or empty if the user is - // signed out. This can be provided on a best effort basis if the ID is not - // available immediately. - virtual std::string GetGaiaId() = 0; - - protected: - virtual ~GoogleAccountsDelegate() = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_GOOGLE_ACCOUNTS_DELEGATE_H_
diff --git a/weblayer/public/java/AndroidManifest.xml b/weblayer/public/java/AndroidManifest.xml deleted file mode 100644 index 4267326..0000000 --- a/weblayer/public/java/AndroidManifest.xml +++ /dev/null
@@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2019 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chromium.weblayer.client"> - - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - - <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH"/> - <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/> - <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_CONNECT"/> - <!-- - Bluetooth scanning is used to implement the Web Bluetooth API, which is - not intended to allow sites to derive location and so can accept a - filtered view of devices. - --> - <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_SCAN" - android:usesPermissionFlags="neverForLocation"/> - - <uses-permission android:name="android.permission.CAMERA"/> - <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> - <uses-permission android:name="android.permission.NFC"/> - <uses-permission android:name="android.permission.READ_CONTACTS"/> - <uses-permission android:name="android.permission.RECORD_AUDIO"/> - <uses-permission android:name="android.permission.VIBRATE"/> - <uses-permission android:name="android.permission.WAKE_LOCK"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - - <!-- Augmented reality support. - A note to clients: for AR to work, there must be manifest entries present for - com.google.ar.core and com.google.ar.core.min_apk_version. These can be merged - from the arcore client library or added manually. If being added manually, - the following is recommended: - - <meta-data android:name="com.google.ar.core" - android:value="optional" /> - <meta-data android:name="com.google.ar.core.min_apk_version" - android:value="1" /> - --> - <queries> - <package android:name="com.google.ar.core" /> - </queries> - - <application> - <!-- The following service entries exist in order to allow us to - start more than one sandboxed process. --> - - <!-- NOTE: If you change the values of "android:process" for any of the below services, - you also need to update kHelperProcessExecutableName in chrome_constants.cc. --> - {% set num_sandboxed_services = 40 %} - <meta-data android:name="org.chromium.content.browser.NUM_SANDBOXED_SERVICES" - android:value="{{ num_sandboxed_services }}"/> - {% for i in range(num_sandboxed_services) %} - <service android:name="org.chromium.weblayer.ChildProcessService$Sandboxed{{ i }}" - android:process=":sandboxed_process{{ i }}" - android:isolatedProcess="true" - android:exported="false" /> - {% endfor %} - - {% set num_privileged_services = 5 %} - <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES" - android:value="{{ num_privileged_services }}"/> - {% for i in range(num_privileged_services) %} - <service android:name="org.chromium.weblayer.ChildProcessService$Privileged{{ i }}" - android:process=":privileged_process{{ i }}" - android:isolatedProcess="false" - android:exported="false" /> - {% endfor %} - - <provider android:name="org.chromium.weblayer.WebLayerFileProvider" - android:authorities="${applicationId}.org.chromium.weblayer.client.FileProvider" - android:exported="false" - android:grantUriPermissions="true"> - <meta-data android:name="android.support.FILE_PROVIDER_PATHS" - android:resource="@xml/weblayer_file_paths" /> - </provider> - - <activity android:name="org.chromium.weblayer.SettingsActivity" - android:theme="@style/Theme.WebLayer.Settings" - android:exported="false"> - </activity> - - <activity android:name="org.chromium.weblayer.SiteSettingsActivity" - android:theme="@style/Theme.WebLayer.Settings" - android:exported="false"> - </activity> - - <receiver android:name="org.chromium.weblayer.BroadcastReceiver" - android:exported="false"> - <intent-filter> - <!-- these need to be in sync with DownloadImpl.java--> - <action android:name="org.chromium.weblayer.downloads.OPEN"/> - <action android:name="org.chromium.weblayer.downloads.DELETE"/> - <action android:name="org.chromium.weblayer.downloads.PAUSE"/> - <action android:name="org.chromium.weblayer.downloads.RESUME"/> - <action android:name="org.chromium.weblayer.downloads.CANCEL"/> - <!-- this needs to be in sync with IntentUtils.java--> - <action android:name="org.chromium.weblayer.intent_utils.ACTIVATE_TAB"/> - <!-- this needs to be in sync with MediaStreamManager.java--> - <!-- TODO(estade): deprecated, remove in M88. --> - <action android:name="org.chromium.weblayer.webrtc.ACTIVATE_TAB"/> - </intent-filter> - </receiver> - - <service android:name="org.chromium.weblayer.MediaSessionService" - android:exported="false"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON" /> - </intent-filter> - </service> - - <service android:name="org.chromium.weblayer.RemoteMediaService" - android:exported="false"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON" /> - </intent-filter> - </service> - - <!-- Service for decoding images in a sandboxed process. --> - <service - android:name="org.chromium.weblayer.ImageDecoderService" - android:exported="false" - android:isolatedProcess="true" - android:process=":decoder_service" /> - - <!-- Used for GPay Dynamic Update --> - <service - android:name="org.chromium.weblayer.GooglePayDataCallbacksServiceWrapper" - android:permission="com.google.android.gms.permission.BIND_PAYMENTS_CALLBACK_SERVICE" - android:exported="true"> - <intent-filter> - <action android:name="com.google.android.gms.wallet.callback.PAYMENT_DATA_CALLBACKS"/> - </intent-filter> - </service> - - <!-- GooglePay payment app support --> - <meta-data - android:name="com.google.android.gms.wallet.api.enabled" - android:value="true" /> - - <!-- Service used by payment apps to notify the browser about changes in user selected - payment method, shipping address, or shipping option. --> - <service - android:name="org.chromium.weblayer.PaymentDetailsUpdateServiceWrapper" - android:exported="true"> - <intent-filter> - <action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS"/> - </intent-filter> - </service> - - <!-- Cast support --> - <!-- TODO(crbug.com/1148410): remove this. --> - <meta-data - android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" - android:value="org.chromium.components.media_router.caf.CastOptionsProvider"/> - </application> -</manifest>
diff --git a/weblayer/public/java/BUILD.gn b/weblayer/public/java/BUILD.gn deleted file mode 100644 index 6977600..0000000 --- a/weblayer/public/java/BUILD.gn +++ /dev/null
@@ -1,289 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") -import("//build/util/process_version.gni") - -_version_constants_java_file = - "$target_gen_dir/org/chromium/weblayer/WebLayerClientVersionConstants.java" - -weblayer_client_manifest = - "$target_gen_dir/weblayer_client_manifest/AndroidManifest.xml" - -jinja_template("weblayer_client_manifest") { - input = "AndroidManifest.xml" - output = weblayer_client_manifest -} - -android_resources("client_resources") { - sources = [ - "res/values-night/colors.xml", - "res/values-night/values.xml", - "res/values-v27/styles.xml", - "res/values-v28/styles.xml", - "res/values/colors.xml", - "res/values/ids.xml", - "res/values/styles.xml", - "res/values/values.xml", - "res/xml/weblayer_file_paths.xml", - ] - android_manifest = weblayer_client_manifest - android_manifest_dep = ":weblayer_client_manifest" -} - -android_library("java") { - sources = [ - "org/chromium/weblayer/ActionModeCallback.java", - "org/chromium/weblayer/ActionModeItemType.java", - "org/chromium/weblayer/BroadcastReceiver.java", - "org/chromium/weblayer/Browser.java", - "org/chromium/weblayer/BrowsingDataType.java", - "org/chromium/weblayer/Callback.java", - "org/chromium/weblayer/CaptureScreenShotCallback.java", - "org/chromium/weblayer/ChildProcessService.java", - "org/chromium/weblayer/ContextMenuParams.java", - "org/chromium/weblayer/CookieChangeCause.java", - "org/chromium/weblayer/CookieChangedCallback.java", - "org/chromium/weblayer/CookieManager.java", - "org/chromium/weblayer/CookieManagerDelegate.java", - "org/chromium/weblayer/DarkModeStrategy.java", - "org/chromium/weblayer/Download.java", - "org/chromium/weblayer/DownloadCallback.java", - "org/chromium/weblayer/DownloadError.java", - "org/chromium/weblayer/DownloadState.java", - "org/chromium/weblayer/ErrorPage.java", - "org/chromium/weblayer/ErrorPageCallback.java", - "org/chromium/weblayer/ExceptionHelper.java", - "org/chromium/weblayer/ExternalIntentInIncognitoCallback.java", - "org/chromium/weblayer/ExternalIntentInIncognitoUserDecision.java", - "org/chromium/weblayer/FaviconCallback.java", - "org/chromium/weblayer/FaviconFetcher.java", - "org/chromium/weblayer/FindInPageCallback.java", - "org/chromium/weblayer/FindInPageController.java", - "org/chromium/weblayer/FullscreenCallback.java", - "org/chromium/weblayer/FullscreenCallbackDelegate.java", - "org/chromium/weblayer/GoogleAccountAccessTokenFetcher.java", - "org/chromium/weblayer/GoogleAccountServiceType.java", - "org/chromium/weblayer/GoogleAccountsCallback.java", - "org/chromium/weblayer/GoogleAccountsParams.java", - "org/chromium/weblayer/GooglePayDataCallbacksServiceWrapper.java", - "org/chromium/weblayer/ImageDecoderService.java", - "org/chromium/weblayer/LoadError.java", - "org/chromium/weblayer/MediaCaptureCallback.java", - "org/chromium/weblayer/MediaCaptureController.java", - "org/chromium/weblayer/MediaPlaybackBaseService.java", - "org/chromium/weblayer/MediaRouteDialogFragmentEventHandler.java", - "org/chromium/weblayer/MediaSessionService.java", - "org/chromium/weblayer/NavigateParams.java", - "org/chromium/weblayer/Navigation.java", - "org/chromium/weblayer/NavigationCallback.java", - "org/chromium/weblayer/NavigationController.java", - "org/chromium/weblayer/NavigationState.java", - "org/chromium/weblayer/NewTabCallback.java", - "org/chromium/weblayer/NewTabType.java", - "org/chromium/weblayer/ObserverList.java", - "org/chromium/weblayer/OpenUrlCallback.java", - "org/chromium/weblayer/Page.java", - "org/chromium/weblayer/PaymentDetailsUpdateServiceWrapper.java", - "org/chromium/weblayer/PrerenderController.java", - "org/chromium/weblayer/Profile.java", - "org/chromium/weblayer/ProfileManagerDelegate.java", - "org/chromium/weblayer/RemoteFragmentEventHandler.java", - "org/chromium/weblayer/RemoteMediaService.java", - "org/chromium/weblayer/ScrollNotificationType.java", - "org/chromium/weblayer/ScrollOffsetCallback.java", - "org/chromium/weblayer/SettingType.java", - "org/chromium/weblayer/Tab.java", - "org/chromium/weblayer/TabCallback.java", - "org/chromium/weblayer/TabInitializationCallback.java", - "org/chromium/weblayer/TabListCallback.java", - "org/chromium/weblayer/TabManagerDelegate.java", - "org/chromium/weblayer/TabNavigationControllerProxy.java", - "org/chromium/weblayer/TabParams.java", - "org/chromium/weblayer/TabProxy.java", - "org/chromium/weblayer/ThreadCheck.java", - "org/chromium/weblayer/UnsupportedVersionException.java", - "org/chromium/weblayer/UserIdentityCallback.java", - "org/chromium/weblayer/VerifiesOnO.java", - "org/chromium/weblayer/VerifiesOnR.java", - "org/chromium/weblayer/WebEngineDelegate.java", - "org/chromium/weblayer/WebFragmentCreateParams.java", - "org/chromium/weblayer/WebFragmentEventHandler.java", - "org/chromium/weblayer/WebFragmentEventsDelegate.java", - "org/chromium/weblayer/WebFragmentNavigationDelegate.java", - "org/chromium/weblayer/WebFragmentNavigationParams.java", - "org/chromium/weblayer/WebFragmentTabDelegate.java", - "org/chromium/weblayer/WebFragmentTabListDelegate.java", - "org/chromium/weblayer/WebLayer.java", - "org/chromium/weblayer/WebLayerFileProvider.java", - "org/chromium/weblayer/WebViewCompatibilityHelper.java", - _version_constants_java_file, - ] - - resources_package = "org.chromium.weblayer" - deps = [ - ":client_resources", - ":client_version", - ":webengine_interfaces_java", - ":weblayer_client_manifest", - "//base:base_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", - "//weblayer/browser/java:base_module_interfaces_java", - "//weblayer/browser/java:interfaces_java", - - # TODO(rayankans): Figure out why this isn't being inherited from //weblayer/browser/java. - "$google_play_services_package:google_play_services_basement_java", - ] - - proguard_configs = [ "proguard.flags" ] -} - -dist_aar("client_aar") { - deps = [ - ":java", - ":webengine_java", - ":weblayer_client_manifest", - ] - - # The aar should only include weblayer files. The client will provide the - # support library. - jar_included_patterns = [ - "org/chromium/weblayer/*", - "org/chromium/weblayer_private/*", - ] - resource_included_patterns = [ "*/weblayer/public/java/*" ] - - # R files are excluded because they are not used in the client lib and depend - # on other generated chromium R classes. - jar_excluded_patterns = [ - "org/chromium/weblayer/client/R\$*.class", - "org/chromium/weblayer/client/R.class", - ] - - # dist_aar does not take the manifest from libraries in deps, so we have to - # specify again here. - android_manifest = weblayer_client_manifest - output = "$root_build_dir/WebLayerClient.aar" -} - -process_version("client_version") { - process_only = true - template_file = - "org/chromium/weblayer/WebLayerClientVersionConstants.java.version" - output = _version_constants_java_file - sources = [ "//chrome/VERSION" ] -} - -android_aidl("webengine_aidl") { - import_include = [ - ".", - "../../browser/java", - ] - sources = [ - "org/chromium/webengine/interfaces/IBooleanCallback.aidl", - "org/chromium/webengine/interfaces/ICookieManagerDelegate.aidl", - "org/chromium/webengine/interfaces/IFullscreenCallbackDelegate.aidl", - "org/chromium/webengine/interfaces/IFullscreenClient.aidl", - "org/chromium/webengine/interfaces/INavigationObserverDelegate.aidl", - "org/chromium/webengine/interfaces/INavigationParams.aidl", - "org/chromium/webengine/interfaces/IPostMessageCallback.aidl", - "org/chromium/webengine/interfaces/IProfileManagerDelegate.aidl", - "org/chromium/webengine/interfaces/IStringCallback.aidl", - "org/chromium/webengine/interfaces/IStringListCallback.aidl", - "org/chromium/webengine/interfaces/ITabCallback.aidl", - "org/chromium/webengine/interfaces/ITabListObserverDelegate.aidl", - "org/chromium/webengine/interfaces/ITabManagerDelegate.aidl", - "org/chromium/webengine/interfaces/ITabNavigationControllerProxy.aidl", - "org/chromium/webengine/interfaces/ITabObserverDelegate.aidl", - "org/chromium/webengine/interfaces/ITabParams.aidl", - "org/chromium/webengine/interfaces/ITabProxy.aidl", - "org/chromium/webengine/interfaces/IWebEngineDelegate.aidl", - "org/chromium/webengine/interfaces/IWebEngineDelegateClient.aidl", - "org/chromium/webengine/interfaces/IWebEngineParams.aidl", - "org/chromium/webengine/interfaces/IWebFragmentEventsDelegate.aidl", - "org/chromium/webengine/interfaces/IWebFragmentEventsDelegateClient.aidl", - "org/chromium/webengine/interfaces/IWebSandboxCallback.aidl", - "org/chromium/webengine/interfaces/IWebSandboxService.aidl", - ] -} - -android_library("webengine_interfaces_java") { - sources = [ "org/chromium/webengine/interfaces/ExceptionType.java" ] - deps = [ - "//base:base_java", - "//third_party/androidx:androidx_annotation_annotation_jvm_java", - "//weblayer/browser/java:base_module_interfaces_java", - ] - srcjar_deps = [ ":webengine_aidl" ] -} - -android_library("webengine_java") { - sources = [ - "org/chromium/webengine/CookieManager.java", - "org/chromium/webengine/ExceptionHelper.java", - "org/chromium/webengine/FullscreenCallback.java", - "org/chromium/webengine/FullscreenCallbackDelegate.java", - "org/chromium/webengine/FullscreenClient.java", - "org/chromium/webengine/MessageEventListener.java", - "org/chromium/webengine/Navigation.java", - "org/chromium/webengine/NavigationObserver.java", - "org/chromium/webengine/NavigationObserverDelegate.java", - "org/chromium/webengine/ProfileManager.java", - "org/chromium/webengine/RestrictedAPIException.java", - "org/chromium/webengine/Tab.java", - "org/chromium/webengine/TabListObserver.java", - "org/chromium/webengine/TabListObserverDelegate.java", - "org/chromium/webengine/TabManager.java", - "org/chromium/webengine/TabNavigationController.java", - "org/chromium/webengine/TabObserver.java", - "org/chromium/webengine/TabObserverDelegate.java", - "org/chromium/webengine/TabRegistry.java", - "org/chromium/webengine/ThreadCheck.java", - "org/chromium/webengine/WebEngine.java", - "org/chromium/webengine/WebEngineParams.java", - "org/chromium/webengine/WebFragment.java", - "org/chromium/webengine/WebSandbox.java", - ] - - resources_package = "org.chromium.webengine" - deps = [ - ":java", - ":webengine_interfaces_java", - "//base:base_java", - "//third_party/android_deps:com_google_guava_listenablefuture_java", - "//third_party/android_deps:guava_android_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_concurrent_concurrent_futures_java", - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", - "//weblayer/browser/java:base_module_interfaces_java", - ] - - proguard_configs = [ "proguard.flags" ] -} - -android_library("service_provider_java") { - testonly = true - resources_package = "org.chromium.weblayer" - - sources = [ - "org/chromium/weblayer/BrowserInProcessService.java", - "org/chromium/weblayer/BrowserProcessBinder.java", - "org/chromium/weblayer/BrowserSandboxService.java", - ] - deps = [ - ":java", - ":webengine_interfaces_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//weblayer/browser/java:base_module_interfaces_java", - ] -}
diff --git a/weblayer/public/java/PRESUBMIT.py b/weblayer/public/java/PRESUBMIT.py deleted file mode 100644 index afd416c..0000000 --- a/weblayer/public/java/PRESUBMIT.py +++ /dev/null
@@ -1,28 +0,0 @@ -# Copyright 2021 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Presubmit tests for weblayer public API.""" - -import glob -import logging -import os -import shutil -import subprocess -import sys -import tempfile - -_WEBLAYER_PUBLIC_MANIFEST_PATH=os.path.join("weblayer", "public", "java", - "AndroidManifest.xml") - -_MANIFEST_CHANGE_STRING = """You are changing the WebLayer public manifest. -Did you validate this change with WebLayer's internal clients? -If not, you must do so before landing it!""" - -def CheckChangeOnUpload(input_api, output_api): - for f in input_api.AffectedFiles(): - if _WEBLAYER_PUBLIC_MANIFEST_PATH in f.AbsoluteLocalPath(): - return [output_api.PresubmitPromptWarning( - _MANIFEST_CHANGE_STRING)] - - return []
diff --git a/weblayer/public/java/org/chromium/webengine/CookieManager.java b/weblayer/public/java/org/chromium/webengine/CookieManager.java deleted file mode 100644 index 38f0963..0000000 --- a/weblayer/public/java/org/chromium/webengine/CookieManager.java +++ /dev/null
@@ -1,139 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.concurrent.futures.CallbackToFutureAdapter; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.interfaces.ExceptionType; -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.ICookieManagerDelegate; -import org.chromium.webengine.interfaces.IStringCallback; - -import java.util.HashSet; - -/** - * CookieManager allows you to set/get cookies within the context of the WebFragment's - * profile. - */ -public class CookieManager { - @NonNull - private ICookieManagerDelegate mDelegate; - - @NonNull - private HashSet<CallbackToFutureAdapter.Completer<Void>> mPendingSetCompleters = - new HashSet<>(); - - @NonNull - private HashSet<CallbackToFutureAdapter.Completer<String>> mPendingGetCompleters = - new HashSet<>(); - - CookieManager(@NonNull ICookieManagerDelegate delegate) { - mDelegate = delegate; - } - - /** - * Sets a cookie for the given URL. - * - * @param uri the URI for which the cookie is to be set. - * @param value the cookie string, using the format of the 'Set-Cookie' HTTP response header. - */ - @NonNull - public ListenableFuture<Void> setCookie(@NonNull String uri, @NonNull String value) { - ThreadCheck.ensureOnUiThread(); - - if (mDelegate == null) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox has been destroyed")); - } - return CallbackToFutureAdapter.getFuture(completer -> { - mPendingSetCompleters.add(completer); - try { - mDelegate.setCookie(uri, value, new IBooleanCallback.Stub() { - @Override - public void onResult(boolean set) { - if (!set) { - completer.setException( - new IllegalArgumentException("Cookie not set: " + value)); - } - completer.set(null); - mPendingSetCompleters.remove(completer); - } - @Override - public void onException(@ExceptionType int type, String msg) { - completer.setException(ExceptionHelper.createException(type, msg)); - mPendingSetCompleters.remove(completer); - } - }); - } catch (RemoteException e) { - completer.setException(e); - mPendingSetCompleters.remove(completer); - } - // Debug string. - return "CookieManager.setCookie Future"; - }); - } - - /** - * Gets the cookies for the given URL. - * - * @param uri the URI for which the cookie is to be set. - */ - @NonNull - public ListenableFuture<String> getCookie(@NonNull String uri) { - if (mDelegate == null) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox has been destroyed")); - } - return CallbackToFutureAdapter.getFuture(completer -> { - mPendingGetCompleters.add(completer); - try { - mDelegate.getCookie(uri, new IStringCallback.Stub() { - @Override - public void onResult(String result) { - if (result != null) { - completer.set(result); - } else { - // TODO(rayankans): Improve exception reporting. - completer.setException( - new IllegalArgumentException("Failed to get cookie")); - } - mPendingGetCompleters.remove(completer); - } - @Override - public void onException(@ExceptionType int type, String msg) { - completer.setException(ExceptionHelper.createException(type, msg)); - mPendingGetCompleters.remove(completer); - } - }); - } catch (RemoteException e) { - completer.setException(e); - mPendingGetCompleters.remove(completer); - } - - // Debug string. - return "CookieManager.getCookie Future"; - }); - } - - void invalidate() { - mDelegate = null; - for (var completer : mPendingSetCompleters) { - completer.setCancelled(); - } - for (var completer : mPendingGetCompleters) { - completer.setCancelled(); - } - mPendingSetCompleters.clear(); - mPendingGetCompleters.clear(); - } - - // TODO(rayankans): Add a Cookie Observer. -}
diff --git a/weblayer/public/java/org/chromium/webengine/ExceptionHelper.java b/weblayer/public/java/org/chromium/webengine/ExceptionHelper.java deleted file mode 100644 index 38e934b..0000000 --- a/weblayer/public/java/org/chromium/webengine/ExceptionHelper.java +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import org.chromium.webengine.interfaces.ExceptionType; - -class ExceptionHelper { - static Exception createException(@ExceptionType int type, String msg) { - switch (type) { - case ExceptionType.RESTRICTED_API: - return new RestrictedAPIException(msg); - case ExceptionType.INVALID_ARGUMENT: - return new IllegalArgumentException(msg); - case ExceptionType.UNKNOWN: - return new RuntimeException(msg); - } - // Should not happen. - return new RuntimeException(msg); - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/FullscreenCallback.java b/weblayer/public/java/org/chromium/webengine/FullscreenCallback.java deleted file mode 100644 index 508e525..0000000 --- a/weblayer/public/java/org/chromium/webengine/FullscreenCallback.java +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -/** - * Fullscreen callback notifies when fullscreen mode starts and ends. - * It expects an implementation to enter and exit fullscreen mode, e.g. expand the - * FragmentContainerView to full size. - */ -public interface FullscreenCallback { - /** - /** - * Called when the page has requested to go fullscreen. The embedder is responsible for - * putting the system into fullscreen mode. The embedder can exit out of fullscreen by - * running the supplied FullscreenClient by calling fullscreenClient.exitFullscreen(). - * - * NOTE: we expect the WebEngine Fragment to be covering the whole display without any other UI - elements from - * the embedder or Android on screen. Otherwise some web features (e.g. WebXR) might experience - * clipped or misaligned UI elements. - * - * @param webEngine the {@code WebEngine} associated with this event. - * @param tab the {@code Tab} associated with this Event - * @param fullscreenClient the {@code FullscreenClient} used to programmatically exit fullscreen - mode. - */ - public void onEnterFullscreen(WebEngine webEngine, Tab tab, FullscreenClient fullscreenClient); - - /** - * Called when the WebEngine Tab exits fullscreen mode. - * - * @param webEngine the {@code WebEngine} associated with this event. - * @param tab the {@code Tab} associated with this Event - */ - public void onExitFullscreen(WebEngine webEngine, Tab tab); -}
diff --git a/weblayer/public/java/org/chromium/webengine/FullscreenCallbackDelegate.java b/weblayer/public/java/org/chromium/webengine/FullscreenCallbackDelegate.java deleted file mode 100644 index 476533aa..0000000 --- a/weblayer/public/java/org/chromium/webengine/FullscreenCallbackDelegate.java +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.Handler; -import android.os.Looper; - -import org.chromium.webengine.interfaces.IFullscreenCallbackDelegate; -import org.chromium.webengine.interfaces.IFullscreenClient; - -/** - * {@link FullscreenCallbackDelegate} notifies registered {@Link FullscreenCallback} of fullscreen - * events of the Tab. - */ -class FullscreenCallbackDelegate extends IFullscreenCallbackDelegate.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private FullscreenCallback mFullscreenCallback; - private WebEngine mWebEngine; - private Tab mTab; - - public FullscreenCallbackDelegate(WebEngine webEngine, Tab tab) { - mWebEngine = webEngine; - mTab = tab; - } - - public void setFullscreenCallback(FullscreenCallback callback) { - ThreadCheck.ensureOnUiThread(); - mFullscreenCallback = callback; - } - - @Override - public void onEnterFullscreen(IFullscreenClient iFullscreenClient) { - mHandler.post(() -> { - if (mFullscreenCallback != null) { - mFullscreenCallback.onEnterFullscreen( - mWebEngine, mTab, new FullscreenClient(iFullscreenClient)); - } - }); - } - - @Override - public void onExitFullscreen() { - mHandler.post(() -> { - if (mFullscreenCallback != null) { - mFullscreenCallback.onExitFullscreen(mWebEngine, mTab); - } - }); - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/FullscreenClient.java b/weblayer/public/java/org/chromium/webengine/FullscreenClient.java deleted file mode 100644 index 2d5321d..0000000 --- a/weblayer/public/java/org/chromium/webengine/FullscreenClient.java +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.IFullscreenClient; - -/** - * {@link FullscreenClient} is passed in {@link FullscreenCallback#onEnterFullscreen} - * to programmatically exit fullscreen mode. - */ -public class FullscreenClient { - private IFullscreenClient mFullscreenClient; - - FullscreenClient(IFullscreenClient client) { - mFullscreenClient = client; - } - - /** - * Exit fullscreen mode, will do nothing if already closed. - */ - public void exitFullscreen() { - ThreadCheck.ensureOnUiThread(); - try { - mFullscreenClient.exitFullscreen(); - } catch (RemoteException e) { - } - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/MessageEventListener.java b/weblayer/public/java/org/chromium/webengine/MessageEventListener.java deleted file mode 100644 index 954f7735..0000000 --- a/weblayer/public/java/org/chromium/webengine/MessageEventListener.java +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -/** - * An interface for listening to postMessages from the web content. - */ -public interface MessageEventListener { - public abstract void onMessage(Tab source, String message); -}
diff --git a/weblayer/public/java/org/chromium/webengine/Navigation.java b/weblayer/public/java/org/chromium/webengine/Navigation.java deleted file mode 100644 index 7d99af5..0000000 --- a/weblayer/public/java/org/chromium/webengine/Navigation.java +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.net.Uri; - -import androidx.annotation.NonNull; - -import org.chromium.webengine.interfaces.INavigationParams; - -/** - * {@link Navigation} contains information about the current Tab Navigation. - */ -public class Navigation { - @NonNull - private INavigationParams mNavigationParams; - - Navigation(@NonNull INavigationParams navigationParams) { - mNavigationParams = navigationParams; - } - - /** - * The uri the main frame is navigating to. This may change during the navigation when - * encountering a server redirect. - */ - @NonNull - public Uri getUri() { - return mNavigationParams.uri; - } - - /** - * Returns the status code of the navigation. Returns 0 if the navigation hasn't completed yet - * or if a response wasn't received. - */ - public int getStatusCode() { - return mNavigationParams.statusCode; - } - - /** - * Whether the navigation happened without changing document. Examples of same document - * navigations are: - * - reference fragment navigations - * - pushState/replaceState - * - same page history navigation - */ - public boolean isSameDocument() { - return mNavigationParams.isSameDocument; - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/NavigationObserver.java b/weblayer/public/java/org/chromium/webengine/NavigationObserver.java deleted file mode 100644 index f347a72..0000000 --- a/weblayer/public/java/org/chromium/webengine/NavigationObserver.java +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import androidx.annotation.NonNull; - -/** - * An interface for observing changes to a Tab. - */ -public interface NavigationObserver { - /** - * Called when a navigation aborts in the Tab. - * - * Note that |navigation| is a snapshot of the current navigation, content might change over the - * course of the navigation. - * - * @param tab the tab associated with this event. - * @param navigation the unique object for this navigation. - */ - public default void onNavigationFailed(@NonNull Tab tab, @NonNull Navigation navigation) {} - - /** - * Called when a navigation completes successfully in the Tab. - * - * The document load will still be ongoing in the Tab. Use the document loads - * events such as onFirstContentfulPaint and related methods to listen for continued events from - * this Tab. - * - * Note that this is fired by same-document navigations, such as fragment navigations or - * pushState/replaceState, which will not result in a document change. To filter these out, use - * NavigationHandle::IsSameDocument. - * - * Note that |navigation| is a snapshot of the current navigation, content might change over the - * course of the navigation. - * - * @param tab the tab associated with this event. - * @param navigation the unique object for this navigation. - */ - public default void onNavigationCompleted(@NonNull Tab tab, @NonNull Navigation navigation) {} - - /** - * Called when a navigation started in the Tab. |navigation| is unique to a - * specific navigation. - * - * Note that this is only fired by navigations in the main frame. - * - * Note that this is fired by same-document navigations, such as fragment navigations or - * pushState/replaceState, which will not result in a document change. To filter these out, use - * Navigation::IsSameDocument. - * - * Note that |navigation| is a snapshot of the current navigation, content might change over the - * course of the navigation. - * - * Note that there is no guarantee that NavigationCompleted/NavigationFailed will be called for - * any particular navigation before NavigationStarted is called on the next. - * - * @param tab the tab associated with this event. - * @param navigation the unique object for this navigation. - */ - public default void onNavigationStarted(@NonNull Tab tab, @NonNull Navigation navigation) {} - - /** - * Called when a navigation encountered a server redirect. - * - * @param tab the tab associated with this event. - * @param navigation the unique object for this navigation. - */ - public default void onNavigationRedirected(@NonNull Tab tab, @NonNull Navigation navigation) {} - - /** - * The load state of the document has changed. - * - * @param tab the tab associated with this event. - * @param progress The loading progress. - */ - public default void onLoadProgressChanged(@NonNull Tab tab, double progress) {} -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/NavigationObserverDelegate.java b/weblayer/public/java/org/chromium/webengine/NavigationObserverDelegate.java deleted file mode 100644 index a1f9cd63..0000000 --- a/weblayer/public/java/org/chromium/webengine/NavigationObserverDelegate.java +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.Handler; -import android.os.Looper; - -import androidx.annotation.NonNull; - -import org.chromium.base.ObserverList; -import org.chromium.webengine.interfaces.INavigationObserverDelegate; -import org.chromium.webengine.interfaces.INavigationParams; - -/** - * {@link NavigationObserverDelegate} notifies registered {@Link NavigationObserver}s of navigation - * events in a Tab. - */ -class NavigationObserverDelegate extends INavigationObserverDelegate.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - @NonNull - private Tab mTab; - - @NonNull - private ObserverList<NavigationObserver> mNavigationObservers = - new ObserverList<NavigationObserver>(); - - public NavigationObserverDelegate(Tab tab) { - ThreadCheck.ensureOnUiThread(); - - mTab = tab; - } - - /** - * Registers a {@link NavigationObserver}. Call only from the UI thread. - * - * @return true if the observer was added to the list of observers. - */ - boolean registerObserver(NavigationObserver tabObserver) { - ThreadCheck.ensureOnUiThread(); - return mNavigationObservers.addObserver(tabObserver); - } - - /** - * Unregisters a {@link NavigationObserver}. Call only from the UI thread. - * - * @return true if the observer was removed from the list of observers. - */ - boolean unregisterObserver(NavigationObserver tabObserver) { - ThreadCheck.ensureOnUiThread(); - return mNavigationObservers.removeObserver(tabObserver); - } - - @Override - public void notifyNavigationStarted(@NonNull INavigationParams navigation) { - mHandler.post(() -> { - for (NavigationObserver observer : mNavigationObservers) { - observer.onNavigationStarted(mTab, new Navigation(navigation)); - } - }); - } - - @Override - public void notifyNavigationRedirected(@NonNull INavigationParams navigation) { - mHandler.post(() -> { - for (NavigationObserver observer : mNavigationObservers) { - observer.onNavigationRedirected(mTab, new Navigation(navigation)); - } - }); - } - - @Override - public void notifyNavigationCompleted(@NonNull INavigationParams navigation) { - mHandler.post(() -> { - for (NavigationObserver observer : mNavigationObservers) { - observer.onNavigationCompleted(mTab, new Navigation(navigation)); - } - }); - } - - @Override - public void notifyNavigationFailed(@NonNull INavigationParams navigation) { - mHandler.post(() -> { - for (NavigationObserver observer : mNavigationObservers) { - observer.onNavigationFailed(mTab, new Navigation(navigation)); - } - }); - } - - @Override - public void notifyLoadProgressChanged(double progress) { - mHandler.post(() -> { - for (NavigationObserver observer : mNavigationObservers) { - observer.onLoadProgressChanged(mTab, progress); - } - }); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/ProfileManager.java b/weblayer/public/java/org/chromium/webengine/ProfileManager.java deleted file mode 100644 index 4069db6..0000000 --- a/weblayer/public/java/org/chromium/webengine/ProfileManager.java +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import androidx.annotation.NonNull; -import androidx.concurrent.futures.CallbackToFutureAdapter; - -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.interfaces.IProfileManagerDelegate; -import org.chromium.webengine.interfaces.IStringListCallback; - -import java.util.List; - -/** - * Manages Profiles in a WebSandbox. - */ -public class ProfileManager { - @NonNull - private IProfileManagerDelegate mDelegate; - - ProfileManager(IProfileManagerDelegate delegate) { - mDelegate = delegate; - } - - void invalidate() { - mDelegate = null; - } - - /** - * Returns a ListenableFuture that resolves to a List of Profile names. - */ - public ListenableFuture<List<String>> getAllProfileNames() { - ThreadCheck.ensureOnUiThread(); - - return CallbackToFutureAdapter.getFuture(completer -> { - mDelegate.getAllProfileNames(new IStringListCallback.Stub() { - @Override - public void onResult(List<String> profileNames) { - completer.set(profileNames); - } - - @Override - public void onException(int type, String msg) { - completer.setException(ExceptionHelper.createException(type, msg)); - } - }); - - return "Profile Names Future"; - }); - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/RestrictedAPIException.java b/weblayer/public/java/org/chromium/webengine/RestrictedAPIException.java deleted file mode 100644 index 1732396..0000000 --- a/weblayer/public/java/org/chromium/webengine/RestrictedAPIException.java +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -/** - * Error thrown for API access violations. - */ -public class RestrictedAPIException extends RuntimeException { - public RestrictedAPIException(String message) { - super(message); - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/Tab.java b/weblayer/public/java/org/chromium/webengine/Tab.java deleted file mode 100644 index c28e51f1..0000000 --- a/weblayer/public/java/org/chromium/webengine/Tab.java +++ /dev/null
@@ -1,368 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.net.Uri; -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.concurrent.futures.CallbackToFutureAdapter; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.base.ObserverList; -import org.chromium.webengine.interfaces.ExceptionType; -import org.chromium.webengine.interfaces.IPostMessageCallback; -import org.chromium.webengine.interfaces.IStringCallback; -import org.chromium.webengine.interfaces.ITabParams; -import org.chromium.webengine.interfaces.ITabProxy; - -import java.util.List; - -/** - * Tab controls the tab content and state. - */ -public class Tab { - @NonNull - private WebEngine mWebEngine; - - @NonNull - private ITabProxy mTabProxy; - - @NonNull - private TabNavigationController mTabNavigationController; - - @NonNull - private TabObserverDelegate mTabObserverDelegate; - - @NonNull - private String mGuid; - - @NonNull - private Uri mUri; - - @NonNull - private ObserverList<MessageEventListenerProxy> mMessageEventListenerProxies = - new ObserverList<>(); - - private boolean mPostMessageReady; - - @NonNull - private FullscreenCallbackDelegate mFullscreenCallbackDelegate; - - Tab(@NonNull WebEngine webEngine, @NonNull ITabParams tabParams) { - assert tabParams.tabProxy != null; - assert tabParams.tabGuid != null; - assert tabParams.navigationControllerProxy != null; - assert tabParams.uri != null; - - mWebEngine = webEngine; - mTabProxy = tabParams.tabProxy; - mGuid = tabParams.tabGuid; - mUri = Uri.parse(tabParams.uri); - mTabObserverDelegate = new TabObserverDelegate(this); - mTabNavigationController = - new TabNavigationController(this, tabParams.navigationControllerProxy); - mFullscreenCallbackDelegate = new FullscreenCallbackDelegate(mWebEngine, this); - - try { - mTabProxy.setTabObserverDelegate(mTabObserverDelegate); - mTabProxy.setFullscreenCallbackDelegate(mFullscreenCallbackDelegate); - } catch (RemoteException e) { - } - } - - /** - * Returns the WebEngine instance associated with this Tab. - */ - @NonNull - public WebEngine getWebEngine() { - return mWebEngine; - } - - /** - * Returns the URL of the page displayed. - */ - @NonNull - public Uri getDisplayUri() { - return mUri; - } - - void setDisplayUri(Uri uri) { - mUri = uri; - } - - /** - * Returns a unique identifier for the Tab. - */ - @NonNull - public String getGuid() { - return mGuid; - } - - /** - * Sets this Tab to active. - */ - public void setActive() { - // TODO(rayankans): Should we make this return a ListenableFuture that resolves after the - // tab becomes active? - ThreadCheck.ensureOnUiThread(); - - if (mTabProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabProxy.setActive(); - } catch (RemoteException e) { - } - } - - /* - * Closes this Tab. - */ - public void close() { - // TODO(rayankans): Should we make this return a ListenableFuture that resolves after the - // tab is closed? - ThreadCheck.ensureOnUiThread(); - if (mTabProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabProxy.close(); - } catch (RemoteException e) { - } - } - - /** - * Executes the script, and resolves with the result of the execution. - * - * @param useSeparateIsolate If true, runs the script in a separate v8 Isolate. This uses more - * memory, but separates the injected scrips from scripts in the page. This prevents any - * potentially malicious interaction between first-party scripts in the page, and injected - * scripts. Use with caution, only pass false for this argument if you know this isn't an issue - * or you need to interact with first-party scripts. - */ - @NonNull - public ListenableFuture<String> executeScript( - @NonNull String script, boolean useSeparateIsolate) { - ThreadCheck.ensureOnUiThread(); - if (mTabProxy == null) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox has been destroyed")); - } - return CallbackToFutureAdapter.getFuture(completer -> { - try { - mTabProxy.executeScript(script, useSeparateIsolate, new IStringCallback.Stub() { - @Override - public void onResult(String result) { - completer.set(result); - } - @Override - public void onException(@ExceptionType int type, String msg) { - completer.setException(ExceptionHelper.createException(type, msg)); - } - }); - } catch (RemoteException e) { - completer.setException(e); - } - - return "Tab.executeScript Future"; - }); - } - - /** - * Returns the navigation controller for this Tab. - * - * @return The TabNavigationController. - */ - @NonNull - public TabNavigationController getNavigationController() { - return mTabNavigationController; - } - - /** - * Registers a {@link TabObserver} and returns if successful. - * - * @param tabObserver The TabObserver. - * - * @return true if observer was added to the list of observers. - */ - public boolean registerTabObserver(@NonNull TabObserver tabObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabObserverDelegate.registerObserver(tabObserver); - } - - /** - * Unregisters a {@link Tabobserver} and returns if successful. - * - * @param tabObserver The TabObserver to remove. - * - * @return true if observer was removed from the list of observers. - */ - public boolean unregisterTabObserver(@NonNull TabObserver tabObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabObserverDelegate.unregisterObserver(tabObserver); - } - - private class MessageEventListenerProxy { - private MessageEventListener mListener; - private List<String> mAllowedOrigins; - - private MessageEventListenerProxy( - MessageEventListener listener, List<String> allowedOrigins) { - mListener = listener; - mAllowedOrigins = allowedOrigins; - } - - private MessageEventListener getListener() { - return mListener; - } - - private List<String> getAllowedOrigins() { - return mAllowedOrigins; - } - - private void onPostMessage(String message, String origin) { - if (!mAllowedOrigins.contains("*") && !mAllowedOrigins.contains(origin)) { - return; - } - mListener.onMessage(Tab.this, message); - } - } - - /** - * Add an event listener for post messages from the web content. - * @param listener Receives the message events posted for the web content. - * @param allowedOrigins The list of origins to accept messages from. "*" will match all - * origins. - */ - public void addMessageEventListener( - @NonNull MessageEventListener listener, @NonNull List<String> allowedOrigins) { - ThreadCheck.ensureOnUiThread(); - - if (mTabProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - - // TODO(crbug.com/1408811): Validate the list of origins. - - MessageEventListenerProxy proxy = new MessageEventListenerProxy(listener, allowedOrigins); - mMessageEventListenerProxies.addObserver(proxy); - - if (mPostMessageReady) { - // We already created a message event listener in the sandbox. However we need to update - // the list of allowedOrigins in the sandbox. This is done so that a message (with a - // valid listener on this end) is sent over IPC once. - try { - mTabProxy.addMessageEventListener(proxy.getAllowedOrigins()); - } catch (RemoteException e) { - throw new IllegalStateException("Failed to communicate with WebSandbox"); - } - return; - } - - IPostMessageCallback callback = new IPostMessageCallback.Stub() { - @Override - public void onPostMessage(String message, String origin) { - for (MessageEventListenerProxy p : mMessageEventListenerProxies) { - p.onPostMessage(message, origin); - } - } - }; - - try { - mTabProxy.createMessageEventListener(callback, proxy.getAllowedOrigins()); - mPostMessageReady = true; - } catch (RemoteException e) { - throw new IllegalStateException("Failed to communicate with WebSandbox"); - } - } - - /** - * Removes the event listener. - */ - public void removeMessageEventListener(@NonNull MessageEventListener listener) { - ThreadCheck.ensureOnUiThread(); - - MessageEventListenerProxy targetProxy = null; - for (MessageEventListenerProxy proxy : mMessageEventListenerProxies) { - if (proxy.getListener().equals(listener)) { - targetProxy = proxy; - break; - } - } - if (targetProxy == null) { - return; - } - - mMessageEventListenerProxies.removeObserver(targetProxy); - try { - mTabProxy.removeMessageEventListener(targetProxy.getAllowedOrigins()); - } catch (RemoteException e) { - throw new IllegalStateException("Failed to communicate with WebSandbox"); - } - } - - /** - * Sends a post message to the web content. The targetOrigin must also be specified to ensure - * the right receiver gets the message. - * - * To receive the message in the web page, you need to add a "message" event listener to the - * window object. - * - * <pre class="prettyprint"> - * // Web page (in JavaScript): - * window.addEventListener('message', e => { - * // |e.data| contains the payload. - * // |e.origin| contains the host app id, in the format of app://<package_name>. - * console.log('Received message', e.data, 'from', e.origin); - * // |e.ports[0]| can be used to communicate back with the host app. - * e.ports[0].postMessage('Received ' + e.data); - * }); - * </pre> - * - * @param message The message to be sent to the web page. - * @param targetOrigin The origin of the page that should receive the message. If '*' is - * provided, the message will be accepted by a page of any origin. - */ - public void postMessage(@NonNull String message, @NonNull String targetOrigin) { - ThreadCheck.ensureOnUiThread(); - - if (mTabProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabProxy.postMessage(message, targetOrigin); - } catch (RemoteException e) { - } - } - - /** - * Attaches a callback to handle fullscreen events from the web content. - */ - public void setFullscreenCallback(@NonNull FullscreenCallback callback) { - ThreadCheck.ensureOnUiThread(); - mFullscreenCallbackDelegate.setFullscreenCallback(callback); - } - - @Override - public int hashCode() { - return mGuid.hashCode(); - } - - @Override - public boolean equals(final Object obj) { - if (obj instanceof Tab) { - return this == obj || mGuid.equals(((Tab) obj).getGuid()); - } - return false; - } - - void invalidate() { - mTabProxy = null; - mTabNavigationController.invalidate(); - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/TabListObserver.java b/weblayer/public/java/org/chromium/webengine/TabListObserver.java deleted file mode 100644 index 4c2377f..0000000 --- a/weblayer/public/java/org/chromium/webengine/TabListObserver.java +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * An interface for observing changes to the set of Tabs in a WebFragment. - */ -public interface TabListObserver { - /** - * The active tab has changed. - * - * @param webEngine the webEngine associated with this event. - * @param activeTab The newly active tab, null if no tab is active. - */ - public default void onActiveTabChanged(@NonNull WebEngine webEngine, @Nullable Tab activeTab) {} - - /** - * A tab was added to the WebFragment. - * - * @param webEngine the webEngine associated with this event. - * @param tab The tab that was added. - */ - public default void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) {} - - /** - * A tab was removed from the WebFragment. - * - * WARNING: this is *not* called when the WebFragment is destroyed. - * - * @param webEngine the webEngine associated with this event. - * @param tab The tab that was removed. - */ - public default void onTabRemoved(@NonNull WebEngine webEngine, @NonNull Tab tab) {} - - /** - * Called when the WebFragment is about to be destroyed. After this - * call the WebFragment with all Tabs are destroyed and can not be used. - * - * @param webEngine the webEngine associated with this event. - */ - public default void onWillDestroyFragmentAndAllTabs(@NonNull WebEngine webEngine) {} -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/TabListObserverDelegate.java b/weblayer/public/java/org/chromium/webengine/TabListObserverDelegate.java deleted file mode 100644 index c28f8f1..0000000 --- a/weblayer/public/java/org/chromium/webengine/TabListObserverDelegate.java +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.Handler; -import android.os.Looper; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.base.Callback; -import org.chromium.base.ObserverList; -import org.chromium.webengine.interfaces.ITabListObserverDelegate; -import org.chromium.webengine.interfaces.ITabParams; - -/** - * {@link TabListObserverDelegate} notifies {@link TabListObserver}s of events in the Fragment. - */ -class TabListObserverDelegate extends ITabListObserverDelegate.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private WebEngine mWebEngine; - private TabRegistry mTabRegistry; - private ObserverList<TabListObserver> mTabListObservers = new ObserverList<TabListObserver>(); - private Callback<Void> mInitializationFinishedCallback; - - public TabListObserverDelegate(WebEngine webEngine, TabRegistry tabRegistry) { - // Assert on UI thread as ObserverList can only be accessed from one thread. - ThreadCheck.ensureOnUiThread(); - mWebEngine = webEngine; - mTabRegistry = tabRegistry; - } - - void setInitializationFinishedCallback(Callback<Void> initializationFinishedCallback) { - mInitializationFinishedCallback = initializationFinishedCallback; - } - - /** - * Register a TabListObserver. Call only from the UI thread. - * - * @return true if the observer was added to the list of observers. - */ - boolean registerObserver(TabListObserver tabListObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabListObservers.addObserver(tabListObserver); - } - - /** - * Unregister a TabListObserver. Call only from the UI thread. - * - * @return true if the observer was removed from the list of observers. - */ - boolean unregisterObserver(TabListObserver tabListObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabListObservers.removeObserver(tabListObserver); - } - - @Override - public void notifyActiveTabChanged(@Nullable ITabParams tabParams) { - mHandler.post(() -> { - Tab tab = null; - if (tabParams != null) { - tab = mTabRegistry.getOrCreateTab(tabParams); - } - mTabRegistry.setActiveTab(tab); - for (TabListObserver observer : mTabListObservers) { - observer.onActiveTabChanged(mWebEngine, tab); - } - }); - } - - @Override - public void notifyTabAdded(@NonNull ITabParams tabParams) { - mHandler.post(() -> { - Tab tab = mTabRegistry.getOrCreateTab(tabParams); - for (TabListObserver observer : mTabListObservers) { - observer.onTabAdded(mWebEngine, tab); - } - }); - } - - @Override - public void notifyTabRemoved(@NonNull ITabParams tabParams) { - mHandler.post(() -> { - Tab tab = mTabRegistry.getOrCreateTab(tabParams); - mTabRegistry.removeTab(tab); - for (TabListObserver observer : mTabListObservers) { - observer.onTabRemoved(mWebEngine, tab); - } - }); - } - - @Override - public void notifyWillDestroyBrowserAndAllTabs() { - mHandler.post(() -> { - for (TabListObserver observer : mTabListObservers) { - observer.onWillDestroyFragmentAndAllTabs(mWebEngine); - } - }); - } - - @Override - public void onFinishedTabInitialization() { - mHandler.post(() -> { - if (mInitializationFinishedCallback != null) { - mInitializationFinishedCallback.onResult(null); - mInitializationFinishedCallback = null; - } - }); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/TabManager.java b/weblayer/public/java/org/chromium/webengine/TabManager.java deleted file mode 100644 index e9bb25e9..0000000 --- a/weblayer/public/java/org/chromium/webengine/TabManager.java +++ /dev/null
@@ -1,146 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.concurrent.futures.CallbackToFutureAdapter; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.base.Callback; -import org.chromium.webengine.interfaces.ITabCallback; -import org.chromium.webengine.interfaces.ITabManagerDelegate; -import org.chromium.webengine.interfaces.ITabParams; - -import java.util.Set; - -/** - * Class for interaction with WebEngine Tabs. - * Calls into WebEngineDelegate which runs on the Binder thread, and requires - * finished initialization from onCreate on UIThread. - * Access only via ListenableFuture through WebEngine. - */ -public class TabManager { - @NonNull - private ITabManagerDelegate mDelegate; - - @NonNull - private WebEngine mWebEngine; - - @NonNull - private TabRegistry mTabRegistry; - - @NonNull - private final TabListObserverDelegate mTabListObserverDelegate; - - @NonNull - private Callback mInitializedTabsCallback; - - private final class TabCallback extends ITabCallback.Stub { - private CallbackToFutureAdapter.Completer<Tab> mCompleter; - - TabCallback(CallbackToFutureAdapter.Completer<Tab> completer) { - mCompleter = completer; - } - - @Override - public void onResult(@Nullable ITabParams tabParams) { - if (tabParams != null) { - new Handler(Looper.getMainLooper()).post(() -> { - mCompleter.set(mTabRegistry.getOrCreateTab(tabParams)); - }); - return; - } - mCompleter.set(null); - } - }; - - TabManager(ITabManagerDelegate delegate, WebEngine webEngine) { - mDelegate = delegate; - mWebEngine = webEngine; - mTabRegistry = new TabRegistry(mWebEngine); - mTabListObserverDelegate = new TabListObserverDelegate(mWebEngine, mTabRegistry); - try { - mDelegate.setTabListObserverDelegate(mTabListObserverDelegate); - } catch (RemoteException e) { - } - } - - void initialize(Callback<Void> initializedCallback) { - mTabListObserverDelegate.setInitializationFinishedCallback(initializedCallback); - try { - mDelegate.notifyInitialTabs(); - } catch (RemoteException e) { - } - } - - /** - * Registers a tab observer and returns if successful. - * - * @param tabListObserver The TabListObserver. - */ - public boolean registerTabListObserver(@NonNull TabListObserver tabListObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabListObserverDelegate.registerObserver(tabListObserver); - } - - /** - * Unregisters a tab observer and returns if successful. - * - * @param tabListObserver The TabListObserver to remove. - */ - public boolean unregisterTabListObserver(@NonNull TabListObserver tabListObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabListObserverDelegate.unregisterObserver(tabListObserver); - } - - /** - * Returns the currently active Tab or null if no Tab is active. - */ - @Nullable - public Tab getActiveTab() { - return mTabRegistry.getActiveTab(); - } - - /** - * Creates a new Tab and returns it in a ListenableFuture. - */ - @NonNull - public ListenableFuture<Tab> createTab() { - ThreadCheck.ensureOnUiThread(); - if (mDelegate == null) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox has been destroyed")); - } - return CallbackToFutureAdapter.getFuture(completer -> { - try { - mDelegate.createTab(new TabCallback(completer)); - } catch (RemoteException e) { - completer.setException(e); - } - // Debug string. - return "Create Tab Future"; - }); - } - - /** - * Returns a set of all the tabs. - */ - @NonNull - public Set<Tab> getAllTabs() { - return mTabRegistry.getTabs(); - } - - void invalidate() { - mDelegate = null; - mTabRegistry.invalidate(); - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/TabNavigationController.java b/weblayer/public/java/org/chromium/webengine/TabNavigationController.java deleted file mode 100644 index c34f118..0000000 --- a/weblayer/public/java/org/chromium/webengine/TabNavigationController.java +++ /dev/null
@@ -1,191 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.concurrent.futures.CallbackToFutureAdapter; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.interfaces.ExceptionType; -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.ITabNavigationControllerProxy; - -/** - * TabNavigationController controls the navigation in a Tab. - */ -public class TabNavigationController { - @NonNull - private ITabNavigationControllerProxy mTabNavigationControllerProxy; - - @NonNull - private NavigationObserverDelegate mNavigationObserverDelegate; - - private final class RequestNavigationCallback extends IBooleanCallback.Stub { - private CallbackToFutureAdapter.Completer<Boolean> mCompleter; - - RequestNavigationCallback(CallbackToFutureAdapter.Completer<Boolean> completer) { - mCompleter = completer; - } - - @Override - public void onResult(boolean possible) { - mCompleter.set(possible); - } - @Override - public void onException(@ExceptionType int type, String msg) { - mCompleter.setException(ExceptionHelper.createException(type, msg)); - } - }; - - TabNavigationController(Tab tab, ITabNavigationControllerProxy tabNavigationControllerProxy) { - mTabNavigationControllerProxy = tabNavigationControllerProxy; - mNavigationObserverDelegate = new NavigationObserverDelegate(tab); - try { - mTabNavigationControllerProxy.setNavigationObserverDelegate( - mNavigationObserverDelegate); - } catch (RemoteException e) { - } - } - - /** - * Navigates this Tab to the given URI. - * - * @param uri The destination URI. - */ - public void navigate(@NonNull String uri) { - ThreadCheck.ensureOnUiThread(); - if (mTabNavigationControllerProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabNavigationControllerProxy.navigate(uri); - } catch (RemoteException e) { - } - } - - /** - * Navigates to the previous navigation. - */ - public void goBack() { - ThreadCheck.ensureOnUiThread(); - if (mTabNavigationControllerProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabNavigationControllerProxy.goBack(); - } catch (RemoteException e) { - } - } - - /** - * Navigates to the next navigation. - */ - public void goForward() { - ThreadCheck.ensureOnUiThread(); - if (mTabNavigationControllerProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabNavigationControllerProxy.goForward(); - } catch (RemoteException e) { - } - } - - /** - * Reloads this Tab. Does nothing if there are no navigations. - */ - public void reload() { - ThreadCheck.ensureOnUiThread(); - if (mTabNavigationControllerProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabNavigationControllerProxy.reload(); - } catch (RemoteException e) { - } - } - - /** - * Stops in progress loading. Does nothing if not in the process of loading. - */ - public void stop() { - ThreadCheck.ensureOnUiThread(); - if (mTabNavigationControllerProxy == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mTabNavigationControllerProxy.stop(); - } catch (RemoteException e) { - } - } - - /** - * Returns a ListenablePromise that resolves to true if there is a navigation before the current - * one. - */ - @NonNull - public ListenableFuture<Boolean> canGoBack() { - ThreadCheck.ensureOnUiThread(); - if (mTabNavigationControllerProxy == null) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox has been destroyed")); - } - return CallbackToFutureAdapter.getFuture(completer -> { - mTabNavigationControllerProxy.canGoBack(new RequestNavigationCallback(completer)); - - // Debug string. - return "Can navigate back Future"; - }); - } - - /** - * Returns a ListenablePromise that resolves to true if there is a navigation after the current - * one. - */ - @NonNull - public ListenableFuture<Boolean> canGoForward() { - ThreadCheck.ensureOnUiThread(); - if (mTabNavigationControllerProxy == null) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox has been destroyed")); - } - return CallbackToFutureAdapter.getFuture(completer -> { - mTabNavigationControllerProxy.canGoForward(new RequestNavigationCallback(completer)); - - // Debug string. - return "Can navigate forward Future"; - }); - } - - /** - * Registers a {@link NavigationObserver} and returns if successful. - * - * @param navigationObserver The {@link NavigationObserver}. - */ - public boolean registerNavigationObserver(@NonNull NavigationObserver navigationObserver) { - ThreadCheck.ensureOnUiThread(); - return mNavigationObserverDelegate.registerObserver(navigationObserver); - } - - /** - * Unregisters a {@link NavigationObserver} and returns if successful. - * - * @param navigationObserver The TabObserver to remove. - * - * @return true if observer was removed from the list of observers. - */ - public boolean unregisterNavigationObserver(@NonNull NavigationObserver navigationObserver) { - ThreadCheck.ensureOnUiThread(); - return mNavigationObserverDelegate.unregisterObserver(navigationObserver); - } - - void invalidate() { - mTabNavigationControllerProxy = null; - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/TabObserver.java b/weblayer/public/java/org/chromium/webengine/TabObserver.java deleted file mode 100644 index 714fd3b..0000000 --- a/weblayer/public/java/org/chromium/webengine/TabObserver.java +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.graphics.Bitmap; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * An interface for observing changes to a Tab. - */ -public interface TabObserver { - /** - * The Uri that can be displayed in the location-bar has updated. - * - * @param tab the tab associated with this event. - * @param uri The new user-visible uri. - */ - public default void onVisibleUriChanged(@NonNull Tab tab, @NonNull String uri) {} - - /** - * Called when the title of this tab changes. Note before the page sets a title, the title may - * be a portion of the Uri. - * - * @param tab the tab associated with this event. - * @param title New title of this tab. - */ - public default void onTitleUpdated(@NonNull Tab tab, @NonNull String title) {} - - /** - * Called when the favicon of the tab has changed. - * - * @param tab the tab associated with this event. - * @param favicon The favicon associated with the Tab. null if there is no favicon. - */ - public default void onFaviconChanged(@NonNull Tab tab, @Nullable Bitmap favicon) {} - - /** - * Triggered when the render process dies, either due to crash or killed by the system to - * reclaim memory. - * - * @param tab the tab associated with this event. - */ - public default void onRenderProcessGone(@NonNull Tab tab) {} -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/TabObserverDelegate.java b/weblayer/public/java/org/chromium/webengine/TabObserverDelegate.java deleted file mode 100644 index 9430ffa7..0000000 --- a/weblayer/public/java/org/chromium/webengine/TabObserverDelegate.java +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; - -import androidx.annotation.NonNull; - -import org.chromium.base.ObserverList; -import org.chromium.webengine.interfaces.ITabObserverDelegate; - -/** - * {@link TabObserverDelegate} notifies registered {@Link TabObserver}s of events in the Tab. - */ -class TabObserverDelegate extends ITabObserverDelegate.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private Tab mTab; - private ObserverList<TabObserver> mTabObservers = new ObserverList<TabObserver>(); - - public TabObserverDelegate(Tab tab) { - // Assert on UI thread as ObserverList can only be accessed from one thread. - ThreadCheck.ensureOnUiThread(); - mTab = tab; - } - - /** - * Registers a {@link TabObserver}. Call only from the UI thread. - * - * @return true if the observer was added to the list of observers. - */ - boolean registerObserver(TabObserver tabObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabObservers.addObserver(tabObserver); - } - - /** - * Unregisters a {@link TabObserver}. Call only from the UI thread. - * - * @return true if the observer was removed from the list of observers. - */ - boolean unregisterObserver(TabObserver tabObserver) { - ThreadCheck.ensureOnUiThread(); - return mTabObservers.removeObserver(tabObserver); - } - - @Override - public void notifyVisibleUriChanged(@NonNull String uri) { - mHandler.post(() -> { - mTab.setDisplayUri(Uri.parse(uri)); - for (TabObserver observer : mTabObservers) { - observer.onVisibleUriChanged(mTab, uri); - } - }); - } - - @Override - public void notifyTitleUpdated(@NonNull String title) { - mHandler.post(() -> { - for (TabObserver observer : mTabObservers) { - observer.onTitleUpdated(mTab, title); - } - }); - } - - @Override - public void notifyRenderProcessGone() { - mHandler.post(() -> { - for (TabObserver observer : mTabObservers) { - observer.onRenderProcessGone(mTab); - } - }); - } - - @Override - public void notifyFaviconChanged(Bitmap favicon) { - mHandler.post(() -> { - for (TabObserver observer : mTabObservers) { - observer.onFaviconChanged(mTab, favicon); - } - }); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/TabRegistry.java b/weblayer/public/java/org/chromium/webengine/TabRegistry.java deleted file mode 100644 index b70b672..0000000 --- a/weblayer/public/java/org/chromium/webengine/TabRegistry.java +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import androidx.annotation.Nullable; - -import org.chromium.webengine.interfaces.ITabParams; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Tab registry for storing open {@link Tab}s per WebEngine on the webengine side. - * - * For internal use only. - */ -class TabRegistry { - private WebEngine mWebEngine; - private Map<String, Tab> mGuidToTab = new HashMap<String, Tab>(); - - @Nullable - private Tab mActiveTab; - - TabRegistry(WebEngine webEngine) { - mWebEngine = webEngine; - } - - Tab getOrCreateTab(ITabParams tabParams) { - Tab tab = mGuidToTab.get(tabParams.tabGuid); - if (tab == null) { - tab = new Tab(mWebEngine, tabParams); - mGuidToTab.put(tabParams.tabGuid, tab); - } - return tab; - } - - void removeTab(Tab tab) { - mGuidToTab.remove(tab.getGuid()); - } - - void invalidate() { - for (Tab tab : mGuidToTab.values()) { - tab.invalidate(); - } - mGuidToTab.clear(); - } - - Set<Tab> getTabs() { - return new HashSet(mGuidToTab.values()); - } - - void setActiveTab(Tab tab) { - mActiveTab = tab; - } - - Tab getActiveTab() { - return mActiveTab; - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/ThreadCheck.java b/weblayer/public/java/org/chromium/webengine/ThreadCheck.java deleted file mode 100644 index faaf954b..0000000 --- a/weblayer/public/java/org/chromium/webengine/ThreadCheck.java +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.Looper; -import android.util.AndroidRuntimeException; - -class ThreadCheck { - static void ensureOnUiThread() { - if (Looper.getMainLooper() != Looper.myLooper()) { - throw new AndroidRuntimeException("This method needs to be called on the main thread"); - } - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/WebEngine.java b/weblayer/public/java/org/chromium/webengine/WebEngine.java deleted file mode 100644 index 130d311..0000000 --- a/weblayer/public/java/org/chromium/webengine/WebEngine.java +++ /dev/null
@@ -1,189 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.concurrent.futures.CallbackToFutureAdapter; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.base.Callback; -import org.chromium.webengine.interfaces.ExceptionType; -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.ICookieManagerDelegate; -import org.chromium.webengine.interfaces.ITabManagerDelegate; -import org.chromium.webengine.interfaces.IWebEngineDelegate; -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegate; - -/** - * WebEngine is created via the WebSandbox and is used to interact with its content as well as to - * obtain its Fragment. - */ -public class WebEngine { - @NonNull - private WebSandbox mWebSandbox; - - @NonNull - private String mTag; - - @NonNull - private IWebEngineDelegate mDelegate; - - @NonNull - private WebFragment mFragment; - - @NonNull - private TabManager mTabManager; - - @NonNull - private CookieManager mCookieManager; - - private WebEngine(WebSandbox webSandbox, IWebEngineDelegate delegate, - IWebFragmentEventsDelegate fragmentEventsDelegate, - ITabManagerDelegate tabManagerDelegate, ICookieManagerDelegate cookieManagerDelegate, - String tag) { - ThreadCheck.ensureOnUiThread(); - mWebSandbox = webSandbox; - mTag = tag; - - mDelegate = delegate; - mFragment = new WebFragment(); - try { - mFragment.initialize(webSandbox, this, fragmentEventsDelegate); - } catch (RemoteException e) { - } - mTabManager = new TabManager(tabManagerDelegate, this); - mCookieManager = new CookieManager(cookieManagerDelegate); - } - - static WebEngine create(WebSandbox webSandbox, IWebEngineDelegate delegate, - IWebFragmentEventsDelegate fragmentEventsDelegate, - ITabManagerDelegate tabManagerDelegate, ICookieManagerDelegate cookieManagerDelegate, - String tag) { - return new WebEngine(webSandbox, delegate, fragmentEventsDelegate, tabManagerDelegate, - cookieManagerDelegate, tag); - } - - void initializeTabManager(Callback<Void> initializationFinishedCallback) { - mTabManager.initialize(initializationFinishedCallback); - } - - /** - * Returns the TabManager. - */ - @NonNull - public TabManager getTabManager() { - return mTabManager; - } - - /** - * Returns the CookieManager. - */ - @NonNull - public CookieManager getCookieManager() { - return mCookieManager; - } - - void updateFragment(WebFragment fragment) { - mFragment = fragment; - } - - private final class RequestNavigationCallback extends IBooleanCallback.Stub { - private CallbackToFutureAdapter.Completer<Boolean> mCompleter; - - RequestNavigationCallback(CallbackToFutureAdapter.Completer<Boolean> completer) { - mCompleter = completer; - } - - @Override - public void onResult(boolean didNavigate) { - mCompleter.set(didNavigate); - } - @Override - public void onException(@ExceptionType int type, String msg) { - mCompleter.setException(ExceptionHelper.createException(type, msg)); - } - } - - /** - * Tries to navigate back inside the WebEngine session and returns a Future with a Boolean - * which is true if the back navigation was successful. - * - * Only recommended to use if no switching of Tabs is used. - * - * Navigates back inside the currently active tab if possible. If that is not possible, - * checks if any Tab was added to the WebEngine before the currently active Tab, - * if so, the currently active Tab is closed and this Tab is set to active. - */ - @NonNull - public ListenableFuture<Boolean> tryNavigateBack() { - ThreadCheck.ensureOnUiThread(); - if (mDelegate == null) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox has been destroyed")); - } - return CallbackToFutureAdapter.getFuture(completer -> { - mDelegate.tryNavigateBack(new RequestNavigationCallback(completer)); - // Debug string. - return "Did navigate back Future"; - }); - } - - /** - * Returns the WebFragment. - */ - @NonNull - public WebFragment getFragment() { - return mFragment; - } - - /** - * Returns the tag associated with this WebEngine instance. - */ - @NonNull - public String getTag() { - return mTag; - } - - void invalidate() { - ThreadCheck.ensureOnUiThread(); - if (mTabManager != null) { - mTabManager.invalidate(); - mTabManager = null; - } - - if (mCookieManager != null) { - mCookieManager.invalidate(); - mCookieManager = null; - } - if (mFragment != null) { - mFragment.invalidate(); - mFragment = null; - } - - if (mDelegate != null) { - try { - mDelegate.shutdown(); - } catch (RemoteException e) { - } - mDelegate = null; - } - - if (mWebSandbox != null && !mWebSandbox.isShutdown()) { - mWebSandbox.removeWebEngine(mTag, this); - } - mWebSandbox = null; - } - - /** - * Close this WebEngine. - */ - public void close() { - invalidate(); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/WebEngineParams.java b/weblayer/public/java/org/chromium/webengine/WebEngineParams.java deleted file mode 100644 index 2cf7e3e..0000000 --- a/weblayer/public/java/org/chromium/webengine/WebEngineParams.java +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.webengine.interfaces.IWebEngineParams; - -import java.util.ArrayList; - -/** - * Parameters for {@link WebSandbox#createFragment}. - */ -public class WebEngineParams { - @Nullable - private String mProfileName; - - @Nullable - private String mPersistenceId; - - private boolean mIsIncognito; - - private boolean mIsExternalIntentsEnabled = true; - - @Nullable - private ArrayList<String> mAllowedOrigins; - - IWebEngineParams getParcelable() { - IWebEngineParams params = new IWebEngineParams(); - params.profileName = mProfileName; - params.persistenceId = mPersistenceId; - params.isIncognito = mIsIncognito; - params.isExternalIntentsEnabled = mIsExternalIntentsEnabled; - params.allowedOrigins = mAllowedOrigins; - return params; - } - - /** - * A Builder class to help create WebEngineParams. - */ - public static final class Builder { - private WebEngineParams mParams = new WebEngineParams(); - - /** - * Returns the WebEngineParam instance asscoaiated with this Builder. - */ - @NonNull - public WebEngineParams build() { - return mParams; - } - - /** - * Sets the name of the profile. Null or empty string implicitly creates an incognito - * profile. If {@code profile} must only contain alphanumeric and underscore characters - * since it will be used as a directory name in the file system. - * - * @param profileName The name of the profile. - */ - @NonNull - public Builder setProfileName(@Nullable String profileName) { - mParams.mProfileName = profileName; - return this; - } - - /** - * Sets the persistence id, which uniquely identifies the Fragment for saving the set of - * tabs and navigations. A value of null does not save/restore any state. A non-null value - * results in asynchronously restoring the tabs and navigations. Supplying a non-null value - * means the Fragment initially has no tabs (until restore is complete). - * - * @param persistenceId The id for persistence. - */ - @NonNull - public Builder setPersistenceId(@Nullable String persistenceId) { - mParams.mPersistenceId = persistenceId; - return this; - } - - /** - * Sets whether the profile is incognito. - * @param isIncognito Whether the profile should be incognito. - */ - @NonNull - public Builder setIsIncognito(boolean isIncognito) { - mParams.mIsIncognito = isIncognito; - return this; - } - - /** - * Sets whether pages will be able to open native intents. - * @param isExternalIntentsEnabled Whether all pages will have the ability to open intent - * urls. - */ - @NonNull - public Builder setIsExternalIntentsEnabled(boolean isExternalIntentsEnabled) { - mParams.mIsExternalIntentsEnabled = isExternalIntentsEnabled; - return this; - } - - /** - * Sets whether a list of origins are allowed to be navigated to. If this is not set all - * origins will be allowed. - * @param allowedOrigins An ArrayList of origins the WebEngine can navigate to. - * This does not support wild cards; full host strings must be provided. - * - * <pre> - * {@code - * ArrayList<String> allowList = new ArrayList<>(); - * allowList.add("https://www.example.com"); - * allowList.add("http://foo.com"); - * - * new WebEngineParams.Builder() - * .setAllowedOrigins(allowList) - * .build(); - * } - * </pre> - */ - @NonNull - public Builder setAllowedOrigins(@Nullable ArrayList<String> allowedOrigins) { - mParams.mAllowedOrigins = allowedOrigins; - return this; - } - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/WebFragment.java b/weblayer/public/java/org/chromium/webengine/WebFragment.java deleted file mode 100644 index 4b69afc..0000000 --- a/weblayer/public/java/org/chromium/webengine/WebFragment.java +++ /dev/null
@@ -1,322 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.view.LayoutInflater; -import android.view.SurfaceControlViewHost.SurfacePackage; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegate; -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegateClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * Fragment for rendering web content. This is obtained through WebEngine. - */ -public class WebFragment extends Fragment { - @Nullable - private WebSandbox mWebSandbox; - @Nullable - private WebEngine mWebEngine; - @Nullable - private IWebFragmentEventsDelegate mDelegate; - - private final IWebFragmentEventsDelegateClient mClient = - new IWebFragmentEventsDelegateClient.Stub() { - @Override - public void onSurfacePackageReady(SurfacePackage surfacePackage) { - SurfaceView surfaceView = (SurfaceView) WebFragment.super.getView(); - surfaceView.setChildSurfacePackage(surfacePackage); - } - - @Override - public void onContentViewRenderViewReady( - IObjectWrapper wrappedContentViewRenderView) { - LinearLayout layout = (LinearLayout) WebFragment.super.getView(); - layout.addView(ObjectWrapper.unwrap(wrappedContentViewRenderView, View.class)); - } - }; - - private SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { - @Override - public void surfaceCreated(SurfaceHolder holder) { - IBinder hostToken = ((SurfaceView) getView()).getHostToken(); - assert hostToken != null; - try { - mDelegate.attachViewHierarchy(hostToken); - } catch (RemoteException e) { - } - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - resizeSurfaceView(width, height); - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) {} - }; - - /** - * This constructor is for the system FragmentManager only. Please use - * {@link WebSandbox#createFragment}. - */ - public WebFragment() {} - - void initialize(WebSandbox webSandbox, WebEngine webEngine, IWebFragmentEventsDelegate delegate) - throws RemoteException { - mWebSandbox = webSandbox; - mWebEngine = webEngine; - mDelegate = delegate; - } - - /** - * Returns the {@link WebEngine} associated with this Fragment. - */ - @NonNull - public WebEngine getWebEngine() { - return mWebEngine; - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - - WebViewModel model = getViewModel(); - if (model.hasSavedState()) { - // Load from view model. - assert mWebSandbox == null; - - mWebSandbox = model.mWebSandbox; - mWebEngine = model.mWebEngine; - mDelegate = model.mDelegate; - - // Recreating a WebFragment e.g. after rotating the device creates a new WebFragment - // based on the data from the ViewModel. The WebFragment in the WebEngine needs to be - // updated as it needs to have the current instance. - mWebEngine.updateFragment(this); - } else { - // Save to View model. - assert mWebSandbox != null; - - model.mWebSandbox = mWebSandbox; - model.mWebEngine = mWebEngine; - model.mDelegate = mDelegate; - } - - if (mWebSandbox.isShutdown()) { - // This is likely due to an inactive fragment being attached after the Web Sandbox - // has been killed. - invalidate(); - return; - } - - AppCompatDelegate.create(getActivity(), null); - - try { - mDelegate.setClient(mClient); - if (WebSandbox.isInProcessMode(context)) { - // Pass the activity context for the in-process mode. - // This is because the Autofill Manager is only available with activity contexts. - // This will be cleaned up when the fragment is detached. - mDelegate.onAttachWithContext( - ObjectWrapper.wrap(context), ObjectWrapper.wrap((Fragment) this)); - } else { - mDelegate.onAttach(); - } - } catch (RemoteException e) { - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - try { - mDelegate.onCreate(); - } catch (RemoteException e) { - } - } - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - if (WebSandbox.isInProcessMode(getActivity())) { - LinearLayout layout = new LinearLayout(getActivity()); - try { - mDelegate.retrieveContentViewRenderView(); - } catch (RemoteException e) { - } - return layout; - } else { - return new WebSurfaceView(getActivity(), mSurfaceHolderCallback); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - try { - mDelegate.onActivityResult(requestCode, resultCode, ObjectWrapper.wrap(data)); - } catch (RemoteException e) { - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - - try { - mDelegate.onDestroy(); - } catch (RemoteException e) { - } - } - - @Override - public void onDetach() { - super.onDetach(); - - try { - mDelegate.onDetach(); - } catch (RemoteException e) { - } - } - - @Override - public void onStart() { - super.onStart(); - try { - mDelegate.onStart(); - } catch (RemoteException e) { - } - } - - @Override - public void onStop() { - super.onStop(); - try { - mDelegate.onStop(); - } catch (RemoteException e) { - } - } - - @Override - public void onResume() { - super.onResume(); - try { - mDelegate.onResume(); - } catch (RemoteException e) { - } - } - - @Override - public void onPause() { - super.onPause(); - try { - mDelegate.onPause(); - } catch (RemoteException e) { - } - } - - /** - * Returns the Sandbox that created this WebFragment. - */ - @NonNull - public WebSandbox getWebSandbox() { - return mWebSandbox; - } - - private void resizeSurfaceView(int width, int height) { - try { - mDelegate.resizeView(width, height); - } catch (RemoteException e) { - } - } - - private WebViewModel getViewModel() { - return new ViewModelProvider(this).get(WebViewModel.class); - } - - void invalidate() { - try { - // The fragment is synchronously removed so that the shutdown steps can complete. - getParentFragmentManager().beginTransaction().remove(this).commitNow(); - } catch (IllegalStateException e) { - // Fragment already removed from FragmentManager. - return; - } finally { - mDelegate = null; - mWebEngine = null; - mWebSandbox = null; - } - } - - /** - * A custom SurfaceView that registers a SurfaceHolder.Callback. - */ - private class WebSurfaceView extends SurfaceView { - private SurfaceHolder.Callback mSurfaceHolderCallback; - - WebSurfaceView(Context context, SurfaceHolder.Callback surfaceHolderCallback) { - super(context); - mSurfaceHolderCallback = surfaceHolderCallback; - setZOrderOnTop(true); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - getHolder().addCallback(mSurfaceHolderCallback); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - getHolder().removeCallback(mSurfaceHolderCallback); - } - } - - /** - * This class is an implementation detail and not intended for public use. It may change at any - * time in incompatible ways, including being removed. - * - * This class stores WebFragment specific state to a ViewModel so that it can reused if a - * new Fragment is created that should share the same state. - */ - public static final class WebViewModel extends ViewModel { - @Nullable - private WebSandbox mWebSandbox; - @Nullable - private WebEngine mWebEngine; - @Nullable - private IWebFragmentEventsDelegate mDelegate; - - boolean hasSavedState() { - return mWebSandbox != null; - } - - @Override - public void onCleared() { - mWebSandbox = null; - mWebEngine = null; - mDelegate = null; - } - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/WebSandbox.java b/weblayer/public/java/org/chromium/webengine/WebSandbox.java deleted file mode 100644 index d5308ddb..0000000 --- a/weblayer/public/java/org/chromium/webengine/WebSandbox.java +++ /dev/null
@@ -1,517 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.concurrent.futures.CallbackToFutureAdapter; -import androidx.core.content.ContextCompat; - -import com.google.common.util.concurrent.AsyncFunction; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.ICookieManagerDelegate; -import org.chromium.webengine.interfaces.IProfileManagerDelegate; -import org.chromium.webengine.interfaces.IStringCallback; -import org.chromium.webengine.interfaces.ITabManagerDelegate; -import org.chromium.webengine.interfaces.IWebEngineDelegate; -import org.chromium.webengine.interfaces.IWebEngineDelegateClient; -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegate; -import org.chromium.webengine.interfaces.IWebSandboxCallback; -import org.chromium.webengine.interfaces.IWebSandboxService; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * Handle to the browsing sandbox. Must be created asynchronously. - */ -public class WebSandbox { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - // TODO(swestphal): Remove this and its function args and detect which service should be used - // based on android version. - private static final String BROWSER_PROCESS_MODE = - "org.chromium.webengine.shell.BrowserProcessMode"; - - // Use another APK as a placeholder for an actual sandbox, since they are conceptually the - // same thing. - private static final String SANDBOX_BROWSER_SANDBOX_PACKAGE = "org.chromium.webengine.sandbox"; - - private static final String BROWSER_SANDBOX_ACTION = - "org.chromium.weblayer.intent.action.BROWSERSANDBOX"; - private static final String BROWSER_INPROCESS_ACTION = - "org.chromium.weblayer.intent.action.BROWSERINPROCESS"; - - private static final String DEFAULT_PROFILE_NAME = "DefaultProfile"; - - @Nullable - private static WebSandbox sInstance; - - @NonNull - private IWebSandboxService mWebSandboxService; - - @NonNull - private SandboxConnection mConnection; - - @NonNull - private ProfileManager mProfileManager; - - @NonNull - private Map<String, WebEngine> mActiveWebEngines = new HashMap<String, WebEngine>(); - - private static class SandboxConnection implements ServiceConnection { - private static ListenableFuture<SandboxConnection> sSandboxConnectionFuture; - private static SandboxConnection sSandboxConnectionInstance; - - private CallbackToFutureAdapter.Completer<SandboxConnection> mSandboxConnectionCompleter; - private IWebSandboxService mWebSandboxService; - - private Context mContext; - - private static boolean sPendingBrowserProcessInitialization; - - private SandboxConnection( - Context context, CallbackToFutureAdapter.Completer<SandboxConnection> completer) { - mContext = context; - mSandboxConnectionCompleter = completer; - - Intent intent = new Intent( - isInProcessMode(mContext) ? BROWSER_INPROCESS_ACTION : BROWSER_SANDBOX_ACTION); - intent.setPackage(isInProcessMode(mContext) ? mContext.getPackageName() - : SANDBOX_BROWSER_SANDBOX_PACKAGE); - mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); - } - - static ListenableFuture<SandboxConnection> getInstance(Context context) { - if (sSandboxConnectionInstance != null) { - return Futures.immediateFuture(sSandboxConnectionInstance); - } - if (sSandboxConnectionFuture == null) { - sSandboxConnectionFuture = CallbackToFutureAdapter.getFuture(completer -> { - new SandboxConnection(context, completer); - return "SandboxConnection Future"; - }); - } - return sSandboxConnectionFuture; - } - - @Override - public void onServiceConnected(ComponentName className, IBinder service) { - mWebSandboxService = IWebSandboxService.Stub.asInterface(service); - - sSandboxConnectionInstance = this; - sSandboxConnectionFuture = null; - - mSandboxConnectionCompleter.set(sSandboxConnectionInstance); - mSandboxConnectionCompleter = null; - } - - private CallbackToFutureAdapter.Completer<WebSandbox> mCompleter; - - void initializeBrowserProcess(CallbackToFutureAdapter.Completer<WebSandbox> completer) { - assert !sPendingBrowserProcessInitialization - : "SandboxInitialization already in progress"; - - mCompleter = completer; - - sPendingBrowserProcessInitialization = true; - try { - mWebSandboxService.initializeBrowserProcess(new IWebSandboxCallback.Stub() { - @Override - public void onBrowserProcessInitialized( - IProfileManagerDelegate profileManagerDelegate) { - sInstance = new WebSandbox( - SandboxConnection.this, mWebSandboxService, profileManagerDelegate); - - mCompleter.set(sInstance); - mCompleter = null; - - sPendingBrowserProcessInitialization = false; - } - - @Override - public void onBrowserProcessInitializationFailure() { - mCompleter.setException( - new IllegalStateException("Failed to initialize WebSandbox")); - mCompleter = null; - sPendingBrowserProcessInitialization = false; - } - }); - } catch (RemoteException e) { - mCompleter.setException(e); - mCompleter = null; - } - } - - void isAvailable(CallbackToFutureAdapter.Completer<Boolean> completer) - throws RemoteException { - mWebSandboxService.isAvailable(new IBooleanCallback.Stub() { - @Override - public void onResult(boolean isAvailable) { - completer.set(isAvailable); - } - @Override - public void onException(int type, String msg) { - completer.setException(ExceptionHelper.createException(type, msg)); - } - }); - } - - void getVersion(CallbackToFutureAdapter.Completer<String> completer) - throws RemoteException { - mWebSandboxService.getVersion(new IStringCallback.Stub() { - @Override - public void onResult(String version) { - completer.set(version); - } - @Override - public void onException(int type, String msg) { - completer.setException(ExceptionHelper.createException(type, msg)); - } - }); - } - - void getProviderPackageName(CallbackToFutureAdapter.Completer<String> completer) - throws RemoteException { - mWebSandboxService.getProviderPackageName(new IStringCallback.Stub() { - @Override - public void onResult(String providerPackageName) { - completer.set(providerPackageName); - } - @Override - public void onException(int type, String msg) { - completer.setException(ExceptionHelper.createException(type, msg)); - } - }); - } - - void unbind() { - mContext.unbindService(this); - sSandboxConnectionInstance = null; - sInstance = null; - } - - // TODO(rayankans): Actually handle failure / disconnection events. - @Override - public void onServiceDisconnected(ComponentName name) {} - } - - private WebSandbox(SandboxConnection connection, IWebSandboxService service, - IProfileManagerDelegate profileManagerDelegate) { - mConnection = connection; - mWebSandboxService = service; - mProfileManager = new ProfileManager(profileManagerDelegate); - } - - /** - * Asynchronously creates a handle to the web sandbox after initializing the - * browser process. - * @param context The Android Context. - */ - @NonNull - public static ListenableFuture<WebSandbox> create(@NonNull Context context) { - ThreadCheck.ensureOnUiThread(); - if (sInstance != null) { - return Futures.immediateFuture(sInstance); - } - - if (SandboxConnection.sPendingBrowserProcessInitialization) { - return Futures.immediateFailedFuture( - new IllegalStateException("WebSandbox is already being created")); - } - Context applicationContext = context.getApplicationContext(); - ListenableFuture<SandboxConnection> sandboxConnectionFuture = - SandboxConnection.getInstance(applicationContext); - - AsyncFunction<SandboxConnection, WebSandbox> initializeBrowserProcessTask = - sandboxConnection -> { - return CallbackToFutureAdapter.getFuture(completer -> { - sandboxConnection.initializeBrowserProcess(completer); - - // Debug string. - return "WebSandbox Sandbox Future"; - }); - }; - - return Futures.transformAsync(sandboxConnectionFuture, initializeBrowserProcessTask, - ContextCompat.getMainExecutor(applicationContext)); - } - - /** - * Returns a ListenableFuture that resolves to whether a WebSandbox is available. - * @param context The Android Context. - */ - @NonNull - public static ListenableFuture<Boolean> isAvailable(@NonNull Context context) { - ThreadCheck.ensureOnUiThread(); - Context applicationContext = context.getApplicationContext(); - ListenableFuture<SandboxConnection> sandboxConnectionFuture = - SandboxConnection.getInstance(applicationContext); - - AsyncFunction<SandboxConnection, Boolean> isAvailableTask = sandboxConnection -> { - return CallbackToFutureAdapter.getFuture(completer -> { - sandboxConnection.isAvailable(completer); - - // Debug string. - return "Sandbox Available Future"; - }); - }; - - return Futures.transformAsync(sandboxConnectionFuture, isAvailableTask, - ContextCompat.getMainExecutor(applicationContext)); - } - - /** - * Returns a ListenableFuture that resolves to the version of the provider. - * @param context The Android Context. - */ - @NonNull - public static ListenableFuture<String> getVersion(@NonNull Context context) { - ThreadCheck.ensureOnUiThread(); - Context applicationContext = context.getApplicationContext(); - ListenableFuture<SandboxConnection> sandboxConnectionFuture = - SandboxConnection.getInstance(applicationContext); - - AsyncFunction<SandboxConnection, String> getVersionTask = sandboxConnection -> { - return CallbackToFutureAdapter.getFuture(completer -> { - sandboxConnection.getVersion(completer); - - // Debug string. - return "Sandbox Version Future"; - }); - }; - - return Futures.transformAsync(sandboxConnectionFuture, getVersionTask, - ContextCompat.getMainExecutor(applicationContext)); - } - - /** - * Returns a ListenableFuture that resolves to the package name of the provider. - * @param context The Android Context. - */ - @NonNull - public static ListenableFuture<String> getProviderPackageName(@NonNull Context context) { - ThreadCheck.ensureOnUiThread(); - Context applicationContext = context.getApplicationContext(); - ListenableFuture<SandboxConnection> sandboxConnectionFuture = - SandboxConnection.getInstance(applicationContext); - - AsyncFunction<SandboxConnection, String> getProviderPackageNameTask = sandboxConnection -> { - return CallbackToFutureAdapter.getFuture(completer -> { - sandboxConnection.getProviderPackageName(completer); - - // Debug string. - return "Sandbox Provider Package Future"; - }); - }; - - return Futures.transformAsync(sandboxConnectionFuture, getProviderPackageNameTask, - ContextCompat.getMainExecutor(applicationContext)); - } - - private class WebEngineDelegateClient extends IWebEngineDelegateClient.Stub { - private CallbackToFutureAdapter.Completer<WebEngine> mWebEngineCompleter; - private String mTag; - - WebEngineDelegateClient( - CallbackToFutureAdapter.Completer<WebEngine> completer, String tag) { - mWebEngineCompleter = completer; - mTag = tag; - } - - @Override - public void onDelegatesReady(IWebEngineDelegate delegate, - IWebFragmentEventsDelegate fragmentEventsDelegate, - ITabManagerDelegate tabManagerDelegate, - ICookieManagerDelegate cookieManagerDelegate) { - mHandler.post(() -> { - WebEngine engine = WebEngine.create(WebSandbox.this, delegate, - fragmentEventsDelegate, tabManagerDelegate, cookieManagerDelegate, mTag); - engine.initializeTabManager((v) -> { - addWebEngine(mTag, engine); - mWebEngineCompleter.set(engine); - }); - }); - } - } - - private String createNewTag() { - int webEngineIndex = mActiveWebEngines.size(); - String tag = String.format("webengine_%d", webEngineIndex); - - while (mActiveWebEngines.containsKey(tag)) { - ++webEngineIndex; - tag = String.format("webengine_%d", webEngineIndex); - } - return tag; - } - - /** - * Asynchronously creates a new WebEngine with default Profile. - */ - @NonNull - public ListenableFuture<WebEngine> createWebEngine() { - ThreadCheck.ensureOnUiThread(); - return createWebEngine(createNewTag()); - } - - /** - * Asynchronously creates a new WebEngine with default Profile and gives it a {@code tag}. - * - * @param tag The tag to be associated with the WebEngine instance. - */ - @NonNull - public ListenableFuture<WebEngine> createWebEngine(@NonNull String tag) { - ThreadCheck.ensureOnUiThread(); - if (mActiveWebEngines.containsKey(tag)) { - throw new IllegalArgumentException("Tag already associated with a WebEngine"); - } - if (mWebSandboxService == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - WebEngineParams params = - (new WebEngineParams.Builder()).setProfileName(DEFAULT_PROFILE_NAME).build(); - return createWebEngine(params, tag); - } - - /** - * Asynchronously creates a new WebEngine based on {@code params}. - * @param params The configuration parameters for the WebEngine instance. - */ - @NonNull - public ListenableFuture<WebEngine> createWebEngine(@NonNull WebEngineParams params) { - ThreadCheck.ensureOnUiThread(); - return createWebEngine(params, createNewTag()); - } - - /** - * Asynchronously creates a new WebEngine based on {@code params} and gives it a {@code tag}. - * - * @param params The configuration parameters for the WebEngine instance. - * @param tag The tag to be associated with the WebEngine instance. - */ - @NonNull - public ListenableFuture<WebEngine> createWebEngine( - @NonNull WebEngineParams params, @NonNull String tag) { - ThreadCheck.ensureOnUiThread(); - if (mActiveWebEngines.containsKey(tag)) { - throw new IllegalArgumentException("Tag already associated with a WebEngine"); - } - if (mWebSandboxService == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - ListenableFuture<WebEngine> webEngineFuture = - CallbackToFutureAdapter.getFuture(completer -> { - mWebSandboxService.createWebEngineDelegate( - params.getParcelable(), new WebEngineDelegateClient(completer, tag)); - - return "WebEngineClient Future"; - }); - return webEngineFuture; - } - - /** - * Enables or disables DevTools remote debugging. - * - * @param enabled Whether remote debugging should be enabled or not. - */ - public void setRemoteDebuggingEnabled(boolean enabled) { - ThreadCheck.ensureOnUiThread(); - if (mWebSandboxService == null) { - throw new IllegalStateException("WebSandbox has been destroyed"); - } - try { - mWebSandboxService.setRemoteDebuggingEnabled(enabled); - } catch (RemoteException e) { - } - } - - // TODO(swestphal): Remove this again. - static boolean isInProcessMode(Context appContext) { - try { - Bundle metaData = appContext.getPackageManager() - .getApplicationInfo(appContext.getPackageName(), - PackageManager.GET_META_DATA) - .metaData; - if (metaData != null) return metaData.getString(BROWSER_PROCESS_MODE).equals("local"); - } catch (PackageManager.NameNotFoundException e) { - } - return false; - } - - void addWebEngine(String tag, WebEngine webEngine) { - assert !mActiveWebEngines.containsKey(tag) : "Key already associated with a WebEngine"; - mActiveWebEngines.put(tag, webEngine); - } - - void removeWebEngine(String tag, WebEngine webEngine) { - assert webEngine == mActiveWebEngines.get(tag); - mActiveWebEngines.remove(tag); - } - - /** - * Returns the WebEngine with the given tag, or null if no WebEngine exists with this tag. - * - * @param tag the name of the WebEngine. - */ - @Nullable - public WebEngine getWebEngine(String tag) { - return mActiveWebEngines.get(tag); - } - - /** - * Returns all active {@link WebEngine}. - */ - @NonNull - public Collection<WebEngine> getWebEngines() { - return mActiveWebEngines.values(); - } - - boolean isShutdown() { - return mWebSandboxService == null; - } - - /** - * Shuts down the WebEngine and closes the sandbox connection. - */ - public void shutdown() { - if (isShutdown()) { - // WebSandbox was already shut down. - return; - } - mWebSandboxService = null; - - mProfileManager.invalidate(); - mProfileManager = null; - - for (WebEngine engine : mActiveWebEngines.values()) { - // This will shut down the WebEngine, its fragment, and remove {@code engine} from - // {@code mActiveWebEngines}. - engine.invalidate(); - } - mActiveWebEngines.clear(); - - mConnection.unbind(); - } - - @NonNull - public ProfileManager getProfileManager() { - return mProfileManager; - } -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ExceptionType.java b/weblayer/public/java/org/chromium/webengine/interfaces/ExceptionType.java deleted file mode 100644 index 91c3e72cd..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ExceptionType.java +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ExceptionType.RESTRICTED_API, ExceptionType.INVALID_ARGUMENT, ExceptionType.UNKNOWN}) -@Retention(RetentionPolicy.SOURCE) -public @interface ExceptionType { - int RESTRICTED_API = 0; - int INVALID_ARGUMENT = 1; - int UNKNOWN = 2; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IBooleanCallback.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IBooleanCallback.aidl deleted file mode 100644 index 53522e7..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IBooleanCallback.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -oneway interface IBooleanCallback { - void onResult(in boolean result) = 1; - - // TODO(swestphal): Replace parameters with actual Exception when supported to also propagate stacktrace. - void onException(in int type, in String msg) = 2; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ICookieManagerDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ICookieManagerDelegate.aidl deleted file mode 100644 index f5df8f2..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ICookieManagerDelegate.aidl +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.IStringCallback; - -oneway interface ICookieManagerDelegate { - void setCookie(String uri, String value, IBooleanCallback callback) = 1; - void getCookie(String uri, IStringCallback callback) = 2; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IFullscreenCallbackDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IFullscreenCallbackDelegate.aidl deleted file mode 100644 index 5db7667..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IFullscreenCallbackDelegate.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.IFullscreenClient; - -oneway interface IFullscreenCallbackDelegate { - void onEnterFullscreen(IFullscreenClient client) = 0; - void onExitFullscreen() = 1; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IFullscreenClient.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IFullscreenClient.aidl deleted file mode 100644 index 2419b3e..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IFullscreenClient.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -// A FullscreenClient that is passed to the webengine to exit fullscreen -// mode programmatically. -oneway interface IFullscreenClient { - void exitFullscreen() = 0; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/INavigationObserverDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/INavigationObserverDelegate.aidl deleted file mode 100644 index 2d18b41..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/INavigationObserverDelegate.aidl +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.INavigationParams; - -oneway interface INavigationObserverDelegate { - void notifyNavigationStarted(in INavigationParams navigation) = 1; - void notifyNavigationCompleted(in INavigationParams navigation) = 2; - void notifyNavigationFailed(in INavigationParams navigation) = 3; - void notifyLoadProgressChanged(double progress) = 4; - void notifyNavigationRedirected(in INavigationParams navigation) = 5; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/INavigationParams.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/INavigationParams.aidl deleted file mode 100644 index f55d3d1f..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/INavigationParams.aidl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import android.net.Uri; - -import org.chromium.webengine.interfaces.ITabProxy; -import org.chromium.webengine.interfaces.ITabNavigationControllerProxy; - -parcelable INavigationParams { - Uri uri; - int statusCode; - boolean isSameDocument; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IPostMessageCallback.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IPostMessageCallback.aidl deleted file mode 100644 index c7d566bf..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IPostMessageCallback.aidl +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -oneway interface IPostMessageCallback { - void onPostMessage(in String result, in String origin) = 1; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IProfileManagerDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IProfileManagerDelegate.aidl deleted file mode 100644 index 762bec6..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IProfileManagerDelegate.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.IStringListCallback; - -oneway interface IProfileManagerDelegate { - void getAllProfileNames(IStringListCallback callback) = 1; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IStringCallback.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IStringCallback.aidl deleted file mode 100644 index b8a85dd..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IStringCallback.aidl +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -oneway interface IStringCallback { - void onResult(in String result) = 1; - - // TODO(swestphal): Replace parameters with actual Exception when supported to also propagate stacktrace. - void onException(in int type, in String msg) = 2; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IStringListCallback.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IStringListCallback.aidl deleted file mode 100644 index 9587a585..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IStringListCallback.aidl +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -oneway interface IStringListCallback { - void onResult(in List<String> result) = 1; - - // TODO(swestphal): Replace parameters with actual Exception when supported to also propagate - // stacktrace. - void onException(in int type, in String msg) = 2; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ITabCallback.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ITabCallback.aidl deleted file mode 100644 index 7fcd8cf..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ITabCallback.aidl +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.ITabParams; - -oneway interface ITabCallback { - void onResult(in ITabParams tabParams) = 1; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ITabListObserverDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ITabListObserverDelegate.aidl deleted file mode 100644 index 59023ea..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ITabListObserverDelegate.aidl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.ITabParams; - -oneway interface ITabListObserverDelegate { - void notifyActiveTabChanged(in ITabParams tabParams) = 1; - void notifyTabAdded(in ITabParams tabParams) = 2; - void notifyTabRemoved(in ITabParams tabParams) = 3; - void notifyWillDestroyBrowserAndAllTabs() = 4; - - void onFinishedTabInitialization() = 5; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ITabManagerDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ITabManagerDelegate.aidl deleted file mode 100644 index 739e1c7..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ITabManagerDelegate.aidl +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.ITabProxy; -import org.chromium.webengine.interfaces.ITabCallback; -import org.chromium.webengine.interfaces.ITabListObserverDelegate; - -oneway interface ITabManagerDelegate { - - void setTabListObserverDelegate(ITabListObserverDelegate tabListObserverDelegate) = 1; - void notifyInitialTabs() = 2; - - void getActiveTab(ITabCallback callback) = 3; - void createTab(ITabCallback callback) = 4; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ITabNavigationControllerProxy.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ITabNavigationControllerProxy.aidl deleted file mode 100644 index d717dce..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ITabNavigationControllerProxy.aidl +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.INavigationObserverDelegate; - -oneway interface ITabNavigationControllerProxy { - void navigate(in String uri) = 1; - void goBack() = 2; - void goForward() = 3; - void canGoBack(IBooleanCallback callback) = 4; - void canGoForward(IBooleanCallback callback) = 5; - void reload() = 7; - void stop() = 8; - - void setNavigationObserverDelegate(INavigationObserverDelegate tabNavigationDelegate) = 6; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ITabObserverDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ITabObserverDelegate.aidl deleted file mode 100644 index 2aeeebf..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ITabObserverDelegate.aidl +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import android.graphics.Bitmap; - -import org.chromium.webengine.interfaces.ITabParams; - -oneway interface ITabObserverDelegate { - void notifyTitleUpdated(in String title) = 1; - void notifyVisibleUriChanged(in String uri) = 2; - void notifyRenderProcessGone() = 3; - void notifyFaviconChanged(in Bitmap favicon) = 4; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ITabParams.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ITabParams.aidl deleted file mode 100644 index b1fed26..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ITabParams.aidl +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.ITabProxy; -import org.chromium.webengine.interfaces.ITabNavigationControllerProxy; - -parcelable ITabParams { - ITabProxy tabProxy; - String tabGuid; - String uri; - ITabNavigationControllerProxy navigationControllerProxy; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/ITabProxy.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/ITabProxy.aidl deleted file mode 100644 index 4676dd1..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/ITabProxy.aidl +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.IFullscreenCallbackDelegate; -import org.chromium.webengine.interfaces.IPostMessageCallback; -import org.chromium.webengine.interfaces.IStringCallback; -import org.chromium.webengine.interfaces.ITabObserverDelegate; - -import java.util.List; - -oneway interface ITabProxy { - void setActive() = 1; - void close() = 2; - void executeScript(in String script, in boolean useSeparateIsolate, in IStringCallback callback) = 3; - - void setTabObserverDelegate(ITabObserverDelegate tabObserverDelegate) = 6; - - // PostMessage: - void postMessage(in String message, in String targetOrigin) = 7; - void createMessageEventListener(in IPostMessageCallback callback, in List<String> allowedOrigins) = 8; - void addMessageEventListener(in List<String> allowedOrigins) = 9; - void removeMessageEventListener(in List<String> allowedOrigins) = 10; - - // Fullscreen mode: - void setFullscreenCallbackDelegate(in IFullscreenCallbackDelegate fullscreenCallbackDelegate) = 11; - - // Reserved Tags: 4, 5 -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineDelegate.aidl deleted file mode 100644 index 675e714..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineDelegate.aidl +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.ITabListObserverDelegate; - -oneway interface IWebEngineDelegate { - void shutdown() = 1; - void tryNavigateBack(IBooleanCallback callback) = 2; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineDelegateClient.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineDelegateClient.aidl deleted file mode 100644 index 47d1a27..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineDelegateClient.aidl +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.ICookieManagerDelegate; -import org.chromium.webengine.interfaces.ITabManagerDelegate; -import org.chromium.webengine.interfaces.IWebEngineDelegate; -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegate; - -oneway interface IWebEngineDelegateClient { - void onDelegatesReady( - IWebEngineDelegate delegate, - IWebFragmentEventsDelegate fragmentEventsDelegate, - ITabManagerDelegate tabManagerDelegate, - ICookieManagerDelegate cookieManagerDelegate) = 1; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineParams.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineParams.aidl deleted file mode 100644 index 0e38f0b..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IWebEngineParams.aidl +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -parcelable IWebEngineParams { - String profileName; - String persistenceId; - boolean isIncognito; - boolean isExternalIntentsEnabled; - @nullable List<String> allowedOrigins; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IWebFragmentEventsDelegate.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IWebFragmentEventsDelegate.aidl deleted file mode 100644 index 2b0b851..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IWebFragmentEventsDelegate.aidl +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import android.os.Bundle; - -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegateClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -// Next value: 16 -oneway interface IWebFragmentEventsDelegate { - void setClient(in IWebFragmentEventsDelegateClient client) = 1; - - // Fragment events. - void onCreate() = 2; - void onStart() = 3; - void onAttach() = 4; - void onDetach() = 5; - void onPause() = 6; - void onStop() = 7; - void onResume() = 8; - void onDestroy() = 9; - - // Fragment operations. - void resizeView(in int width, in int height) = 10; - void setMinimumSurfaceSize(int width, int height) = 11; - - // Out of process operations. - void attachViewHierarchy(in IBinder hostToken) = 12; - - // In process operations. - void onAttachWithContext(IObjectWrapper context, IObjectWrapper fragment) = 13; - void retrieveContentViewRenderView() = 14; - void onActivityResult(int requestCode, int resultCode, IObjectWrapper intent) = 15; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IWebFragmentEventsDelegateClient.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IWebFragmentEventsDelegateClient.aidl deleted file mode 100644 index 4669693..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IWebFragmentEventsDelegateClient.aidl +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import android.view.SurfaceControlViewHost.SurfacePackage; - -import org.chromium.weblayer_private.interfaces.IObjectWrapper; - -oneway interface IWebFragmentEventsDelegateClient { - void onSurfacePackageReady(in SurfacePackage surfacePackage) = 1; - - // Pre-U/T -devices cannot create an out-of-process Service with privileges needed - // to run the Browser process. - // On those devices we run BrowserFragment in-process but with the same API. - // The ObjectWrapper is only needed to pass the View-object (ContentViewRenderView) - // to the connecting client as the SurfaceControlViewHost is also not available on - // older versions. - void onContentViewRenderViewReady(in IObjectWrapper contentViewRenderView) = 2; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IWebSandboxCallback.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IWebSandboxCallback.aidl deleted file mode 100644 index 59690cff..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IWebSandboxCallback.aidl +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import android.view.SurfaceControlViewHost.SurfacePackage; -import org.chromium.webengine.interfaces.IProfileManagerDelegate; - -oneway interface IWebSandboxCallback { - void onBrowserProcessInitialized(in IProfileManagerDelegate delegate) = 1; - void onBrowserProcessInitializationFailure() = 2; -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/IWebSandboxService.aidl b/weblayer/public/java/org/chromium/webengine/interfaces/IWebSandboxService.aidl deleted file mode 100644 index 37d50a4..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/IWebSandboxService.aidl +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.interfaces; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.IStringCallback; -import org.chromium.webengine.interfaces.IWebEngineParams; -import org.chromium.webengine.interfaces.IWebEngineDelegateClient; -import org.chromium.webengine.interfaces.IWebSandboxCallback; - -oneway interface IWebSandboxService { - void isAvailable(IBooleanCallback callback) = 1; - void getVersion(IStringCallback callback) = 2; - void getProviderPackageName(IStringCallback callback) = 3; - - void initializeBrowserProcess(in IWebSandboxCallback callback) = 4; - void createWebEngineDelegate(in IWebEngineParams params, IWebEngineDelegateClient fragmentClient) = 5; - - void setRemoteDebuggingEnabled(in boolean enabled) = 6; -}
diff --git a/weblayer/public/java/org/chromium/webengine/interfaces/OWNERS b/weblayer/public/java/org/chromium/webengine/interfaces/OWNERS deleted file mode 100644 index 8f094e0..0000000 --- a/weblayer/public/java/org/chromium/webengine/interfaces/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *.aidl=set noparent -per-file *.aidl=file://ipc/SECURITY_OWNERS
diff --git a/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java b/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java deleted file mode 100644 index b21f1751..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * Used to override floating some action mode menu items. - * - * @since 88 - */ -abstract class ActionModeCallback { - /** - * Called when an overridden item type is clicked. The action mode is closed after this returns. - * @param selectedText the raw selected text. Client is responsible for trimming it to fit into - * some use cases as the text can be very large. - */ - public void onActionItemClicked(@ActionModeItemType int item, String selectedText) {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java b/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java deleted file mode 100644 index 6b85acf..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ActionModeItemType.SHARE, ActionModeItemType.WEB_SEARCH}) -@Retention(RetentionPolicy.SOURCE) -@interface ActionModeItemType { - int SHARE = org.chromium.weblayer_private.interfaces.ActionModeItemType.SHARE; - int WEB_SEARCH = org.chromium.weblayer_private.interfaces.ActionModeItemType.WEB_SEARCH; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/BroadcastReceiver.java b/weblayer/public/java/org/chromium/weblayer/BroadcastReceiver.java deleted file mode 100644 index f4ad7cb..0000000 --- a/weblayer/public/java/org/chromium/weblayer/BroadcastReceiver.java +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.content.Intent; -import android.os.RemoteException; - -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * Listens to events from WebLayer-spawned notifications. - */ -public class BroadcastReceiver extends android.content.BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - try { - WebLayer.loadAsync(context, webLayer -> { - try { - webLayer.getImpl().onReceivedBroadcast(ObjectWrapper.wrap(context), intent); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - }); - } catch (UnsupportedVersionException e) { - throw new RuntimeException(e); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/Browser.java b/weblayer/public/java/org/chromium/weblayer/Browser.java deleted file mode 100644 index e178a0bc..0000000 --- a/weblayer/public/java/org/chromium/weblayer/Browser.java +++ /dev/null
@@ -1,481 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IBrowserClient; -import org.chromium.weblayer_private.interfaces.IMediaRouteDialogFragment; -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.util.Set; - -/** - * Browser contains any number of Tabs, with one active Tab. The active Tab is visible to the user, - * all other Tabs are hidden. - * - * Newly created Browsers have a single active Tab. - * - * Browser provides for two distinct ways to save state, which impacts the state of the Browser at - * various points in the lifecycle. - * - * Asynchronously to the file system. This is used if a {@link persistenceId} was supplied when the - * Browser was created. The {@link persistenceId} uniquely identifies the Browser for saving the - * set of tabs and navigations. This is intended for long term persistence. - * - * For Browsers created with a {@link persistenceId}, restore happens asynchronously. As a result, - * the Browser will not have any tabs until restore completes (which may be after the Fragment has - * started). - * - * If a {@link persistenceId} is not supplied, then a minimal amount of state is saved to the - * fragment (instance state). During recreation, if instance state is available, the state is - * restored in {@link onStart}. Restore happens during start so that callbacks can be attached. As - * a result of this, the Browser has no tabs until the Fragment is started. - */ -class Browser { - // Set to null once destroyed (or for tests). - private IBrowser mImpl; - private final ObserverList<TabListCallback> mTabListCallbacks; - - private final ObserverList<TabInitializationCallback> mTabInitializationCallbacks; - - private static int sMaxNavigationsPerTabForInstanceState; - - /** - * Sets the maximum number of navigations saved when persisting a Browsers instance state. The - * max applies to each Tab in the Browser. For example, if a value of 6 is supplied and the - * Browser has 4 tabs, then up to 24 navigation entries may be saved. The supplied value is - * a recommendation, for various reasons it may not be honored. A value of 0 results in - * using the default. - * - * @param value The maximum number of navigations to persist. - * - * @throws IllegalArgumentException If {@code value} is less than 0. - * - * @since 98 - */ - public static void setMaxNavigationsPerTabForInstanceState(int value) { - ThreadCheck.ensureOnUiThread(); - if (value < 0) throw new IllegalArgumentException("Max must be >= 0"); - sMaxNavigationsPerTabForInstanceState = value; - } - - static int getMaxNavigationsPerTabForInstanceState() { - return sMaxNavigationsPerTabForInstanceState; - } - - // Constructor for test mocking. - protected Browser() { - mImpl = null; - mTabListCallbacks = null; - mTabInitializationCallbacks = null; - } - - // Constructor for browserfragment to inject the {@code tabListCallback} on startup. - Browser(IBrowser impl) { - mImpl = impl; - mTabListCallbacks = new ObserverList<TabListCallback>(); - mTabInitializationCallbacks = new ObserverList<TabInitializationCallback>(); - } - - void initializeState() { - try { - mImpl.setClient(new BrowserClientImpl()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - private void throwIfDestroyed() { - if (mImpl == null) { - throw new IllegalStateException("Browser can not be used once destroyed"); - } - } - - IBrowser getIBrowser() { - return mImpl; - } - - /** - * Returns remote counterpart for the BrowserFragment: an {@link IRemoteFragment}. - */ - IRemoteFragment connectFragment() { - try { - return mImpl.createBrowserFragmentImpl(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the remote counterpart of MediaRouteDialogFragment. - */ - /* package */ IMediaRouteDialogFragment createMediaRouteDialogFragment() { - try { - return mImpl.createMediaRouteDialogFragmentImpl(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns true if this Browser has been destroyed. - */ - public boolean isDestroyed() { - ThreadCheck.ensureOnUiThread(); - return mImpl == null; - } - - // Called prior to notifying IBrowser of destroy(). - void prepareForDestroy() { - for (TabListCallback callback : mTabListCallbacks) { - callback.onWillDestroyBrowserAndAllTabs(); - } - } - - // Called after the browser was destroyed. - void onDestroyed() { - mImpl = null; - } - - /** - * Sets the active (visible) Tab. Only one Tab is visible at a time. - * - * @param tab The Tab to make active. - * - * @throws IllegalStateException if {@link tab} was not added to this - * Browser. - * - * @see #addTab() - */ - public void setActiveTab(@NonNull Tab tab) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - if (getActiveTab() != tab && !mImpl.setActiveTab(tab.getITab())) { - throw new IllegalStateException("attachTab() must be called before " - + "setActiveTab"); - } - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Adds a tab to this Browser. If {link tab} is the active Tab of another Browser, then the - * other Browser's active tab is set to null. This does nothing if {@link tab} is already - * contained in this Browser. - * - * @param tab The Tab to add. - */ - public void addTab(@NonNull Tab tab) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - if (tab.getBrowser() == this) return; - try { - mImpl.addTab(tab.getITab()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the active (visible) Tab associated with this - * Browser. - * - * @return The Tab. - */ - @Nullable - public Tab getActiveTab() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - Tab tab = Tab.getTabById(mImpl.getActiveTabId()); - assert tab == null || tab.getBrowser() == this; - return tab; - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the set of Tabs contained in this Browser. - * - * @return The Tabs - */ - @NonNull - public Set<Tab> getTabs() { - ThreadCheck.ensureOnUiThread(); - return Tab.getTabsInBrowser(this); - } - - /** - * Returns a List of Tabs as saved in the native Browser. - * - * @return The Tabs. - */ - @NonNull - private int[] getTabIds() { - ThreadCheck.ensureOnUiThread(); - try { - return mImpl.getTabIds(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Disposes a Tab. If {@link tab} is the active Tab, no Tab is made active. After this call - * {@link tab} should not be used. - * - * Note this will skip any beforeunload handlers. To run those first, use - * {@link Tab#dispatchBeforeUnloadAndClose} instead. - * - * @param tab The Tab to dispose. - * - * @throws IllegalStateException is {@link tab} is not in this Browser. - */ - public void destroyTab(@NonNull Tab tab) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - if (tab.getBrowser() != this) { - throw new IllegalStateException("destroyTab() must be called on a Tab in the Browser"); - } - try { - mImpl.destroyTab(tab.getITab()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Navigates to the previous navigation across all tabs according to tabs in native Browser. - */ - void tryNavigateBack(@NonNull Callback<Boolean> callback) { - Tab activeTab = getActiveTab(); - if (activeTab == null) { - callback.onResult(false); - return; - } - if (activeTab.dismissTransientUi()) { - callback.onResult(true); - return; - } - NavigationController controller = activeTab.getNavigationController(); - if (controller.canGoBack()) { - controller.goBack(); - callback.onResult(true); - return; - } - int[] tabIds = getTabIds(); - if (tabIds.length > 1) { - Tab previousTab = null; - int activeTabId = activeTab.getId(); - int prevId = -1; - for (int id : tabIds) { - if (id == activeTabId) { - previousTab = Tab.getTabById(prevId); - break; - } - prevId = id; - } - if (previousTab != null) { - activeTab.dispatchBeforeUnloadAndClose(); - setActiveTab(previousTab); - callback.onResult(true); - return; - } - } - callback.onResult(false); - } - - /** - * Adds a TabListCallback. - * - * @param callback The TabListCallback. - */ - public void registerTabListCallback(@NonNull TabListCallback callback) { - ThreadCheck.ensureOnUiThread(); - mTabListCallbacks.addObserver(callback); - } - - /** - * Removes a TabListCallback. - * - * @param callback The TabListCallback. - */ - public void unregisterTabListCallback(@NonNull TabListCallback callback) { - ThreadCheck.ensureOnUiThread(); - mTabListCallbacks.removeObserver(callback); - } - - /** - * Returns true if this Browser is in the process of restoring the previous state. - * - * @param True if restoring previous state. - */ - public boolean isRestoringPreviousState() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - return mImpl.isRestoringPreviousState(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Adds a TabInitializationCallback. - * - * @param callback The TabInitializationCallback. - */ - public void registerTabInitializationCallback(@NonNull TabInitializationCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - mTabInitializationCallbacks.addObserver(callback); - } - - /** - * Removes a TabInitializationCallback. - * - * @param callback The TabInitializationCallback. - */ - public void unregisterTabInitializationCallback(@NonNull TabInitializationCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - mTabInitializationCallbacks.removeObserver(callback); - } - - /** - * Creates a new tab attached to this browser. This will call {@link TabListCallback#onTabAdded} - * with the new tab. - */ - public @NonNull Tab createTab() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - ITab iTab = mImpl.createTab(); - Tab tab = Tab.getTabById(iTab.getId()); - assert tab != null; - return tab; - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Controls how sites are themed when WebLayer is in dark mode. WebLayer considers itself to be - * in dark mode if the UI_MODE_NIGHT_YES flag of its Resources' Configuration's uiMode field is - * set, which is typically controlled with AppCompatDelegate#setDefaultNightMode. By default - * pages will only be rendered in dark mode if WebLayer is in dark mode and they provide a dark - * theme in CSS. See DarkModeStrategy for other possible configurations. - * - * @see DarkModeStrategy - * @param strategy See {@link DarkModeStrategy}. - * - * @since 90 - */ - public void setDarkModeStrategy(@DarkModeStrategy int strategy) { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - throwIfDestroyed(); - try { - mImpl.setDarkModeStrategy(strategy); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns {@link Profile} associated with this Browser Fragment. Multiple fragments can share - * the same Profile. - */ - @NonNull - public Profile getProfile() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - return Profile.of(mImpl.getProfile()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public void shutdown() { - try { - mImpl.shutdown(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - private final class BrowserClientImpl extends IBrowserClient.Stub { - @Override - public void onActiveTabChanged(int activeTabId) { - StrictModeWorkaround.apply(); - Tab tab = Tab.getTabById(activeTabId); - for (TabListCallback callback : mTabListCallbacks) { - callback.onActiveTabChanged(tab); - } - } - - @Override - public void onTabAdded(ITab iTab) { - StrictModeWorkaround.apply(); - int id = 0; - try { - id = iTab.getId(); - } catch (RemoteException e) { - throw new APICallException(e); - } - Tab tab = Tab.getTabById(id); - if (tab == null) { - tab = new Tab(iTab, Browser.this); - } else { - tab.setBrowser(Browser.this); - } - for (TabListCallback callback : mTabListCallbacks) { - callback.onTabAdded(tab); - } - } - - @Override - public void onTabRemoved(int tabId) { - StrictModeWorkaround.apply(); - Tab tab = Tab.getTabById(tabId); - // This should only be called with a previously created tab. - assert tab != null; - // And this should only be called for tabs attached to this browser. - assert tab.getBrowser() == Browser.this; - - tab.setBrowser(null); - for (TabListCallback callback : mTabListCallbacks) { - callback.onTabRemoved(tab); - } - } - - @Override - public IRemoteFragment createMediaRouteDialogFragment() { - StrictModeWorkaround.apply(); - return new MediaRouteDialogFragmentEventHandler().getRemoteFragment(); - } - - @Override - public void onTabInitializationCompleted() { - for (TabInitializationCallback callback : mTabInitializationCallbacks) { - callback.onTabInitializationCompleted(); - } - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserInProcessService.java b/weblayer/public/java/org/chromium/weblayer/BrowserInProcessService.java deleted file mode 100644 index 5279b3f..0000000 --- a/weblayer/public/java/org/chromium/weblayer/BrowserInProcessService.java +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; - -/** - * Service running the browser process for a BrowserFragment inside the hosting - * application's process. - */ -public class BrowserInProcessService extends Service { - private final IBinder mBinder = new BrowserProcessBinder(this); - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserProcessBinder.java b/weblayer/public/java/org/chromium/weblayer/BrowserProcessBinder.java deleted file mode 100644 index 877a24b..0000000 --- a/weblayer/public/java/org/chromium/weblayer/BrowserProcessBinder.java +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.IStringCallback; -import org.chromium.webengine.interfaces.IWebEngineDelegateClient; -import org.chromium.webengine.interfaces.IWebEngineParams; -import org.chromium.webengine.interfaces.IWebSandboxCallback; -import org.chromium.webengine.interfaces.IWebSandboxService; - -/** - * Implementation of IWebSandboxService.Stub to be used in in-process and out-of-process - * browser process services. - */ -class BrowserProcessBinder extends IWebSandboxService.Stub { - private final Context mContext; - private WebLayer mWebLayer; - - BrowserProcessBinder(Context context) { - mContext = context; - } - - @Override - public void isAvailable(IBooleanCallback callback) { - new Handler(Looper.getMainLooper()).post(() -> { - try { - callback.onResult(WebLayer.isAvailable(mContext)); - } catch (RemoteException e) { - } - }); - } - - @Override - public void getVersion(IStringCallback callback) { - new Handler(Looper.getMainLooper()).post(() -> { - try { - callback.onResult(WebLayer.getSupportedFullVersion(mContext)); - } catch (RemoteException e) { - } - }); - } - - @Override - public void getProviderPackageName(IStringCallback callback) { - new Handler(Looper.getMainLooper()).post(() -> { - try { - callback.onResult(WebLayer.getProviderPackageName(mContext)); - } catch (RemoteException e) { - } - }); - } - - @Override - public void initializeBrowserProcess(IWebSandboxCallback callback) { - new Handler(Looper.getMainLooper()).post(() -> { - try { - WebLayer.loadAsync(mContext, (webLayer) -> onWebLayerReady(webLayer, callback)); - } catch (Exception e) { - try { - callback.onBrowserProcessInitializationFailure(); - } catch (RemoteException re) { - } - } - }); - } - - private void onWebLayerReady(WebLayer webLayer, IWebSandboxCallback callback) { - mWebLayer = webLayer; - try { - callback.onBrowserProcessInitialized(new ProfileManagerDelegate(webLayer)); - } catch (RemoteException e) { - } - } - - @Override - public void createWebEngineDelegate( - IWebEngineParams params, IWebEngineDelegateClient webEngineClient) { - assert mWebLayer != null; - - WebEngineDelegate.create(mContext, mWebLayer, params, webEngineClient); - } - - @Override - public void setRemoteDebuggingEnabled(boolean enabled) { - assert mWebLayer != null; - mWebLayer.setRemoteDebuggingEnabled(enabled); - } -}; \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowserSandboxService.java b/weblayer/public/java/org/chromium/weblayer/BrowserSandboxService.java deleted file mode 100644 index 50b7b837..0000000 --- a/weblayer/public/java/org/chromium/weblayer/BrowserSandboxService.java +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; - -/** - * Service running the browser process for a BrowserFragment outside of the hosting - * application's process. - */ -public class BrowserSandboxService extends Service { - private IBinder mBinder = new BrowserProcessBinder(this); - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/BrowsingDataType.java b/weblayer/public/java/org/chromium/weblayer/BrowsingDataType.java deleted file mode 100644 index 01d8b252..0000000 --- a/weblayer/public/java/org/chromium/weblayer/BrowsingDataType.java +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({BrowsingDataType.COOKIES_AND_SITE_DATA, BrowsingDataType.CACHE, - BrowsingDataType.SITE_SETTINGS}) -@Retention(RetentionPolicy.SOURCE) -@interface BrowsingDataType { - int COOKIES_AND_SITE_DATA = - org.chromium.weblayer_private.interfaces.BrowsingDataType.COOKIES_AND_SITE_DATA; - int CACHE = org.chromium.weblayer_private.interfaces.BrowsingDataType.CACHE; - int SITE_SETTINGS = org.chromium.weblayer_private.interfaces.BrowsingDataType.SITE_SETTINGS; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/Callback.java b/weblayer/public/java/org/chromium/weblayer/Callback.java deleted file mode 100644 index 002f6f5e..0000000 --- a/weblayer/public/java/org/chromium/weblayer/Callback.java +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * Simple callback that takes a generic value. - * @param <T> The type of value passed into the callback. - */ -interface Callback<T> { - void onResult(T result); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/CaptureScreenShotCallback.java b/weblayer/public/java/org/chromium/weblayer/CaptureScreenShotCallback.java deleted file mode 100644 index ba86f79..0000000 --- a/weblayer/public/java/org/chromium/weblayer/CaptureScreenShotCallback.java +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; - -import androidx.annotation.Nullable; - -/** - * Callback for capturing screenshots. - */ -interface CaptureScreenShotCallback { - /** - * @param bitmap The result bitmap. May be null on failure - * @param errorCode An opaque error code value for debugging. 0 indicates success. - */ - void onScreenShotCaptured(@Nullable Bitmap bitmap, int errorCode); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ChildProcessService.java b/weblayer/public/java/org/chromium/weblayer/ChildProcessService.java deleted file mode 100644 index ddac3453..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ChildProcessService.java +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.IBinder; -import android.os.RemoteException; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IChildProcessService; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * Delegates service calls to the chrome service implementation. - */ -@SuppressWarnings("JavadocType") -public abstract class ChildProcessService extends Service { - private IChildProcessService mImpl; - - public ChildProcessService() {} - - @Override - public void onCreate() { - super.onCreate(); - try { - WebLayer.disableWebViewCompatibilityMode(); - Context appContext = getApplicationContext(); - Context remoteContext = WebLayer.getOrCreateRemoteContext(appContext); - mImpl = IChildProcessService.Stub.asInterface( - (IBinder) WebLayer - .loadRemoteClass(appContext, - "org.chromium.weblayer_private.ChildProcessServiceImpl") - .getMethod("create", Service.class, Context.class, Context.class) - .invoke(null, this, appContext, remoteContext)); - mImpl.onCreate(); - } catch (Exception e) { - throw new APICallException(e); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - try { - mImpl.onDestroy(); - mImpl = null; - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @Override - public IBinder onBind(Intent intent) { - try { - return ObjectWrapper.unwrap(mImpl.onBind(ObjectWrapper.wrap(intent)), IBinder.class); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public static class Privileged extends ChildProcessService {} - public static final class Privileged0 extends Privileged {} - public static final class Privileged1 extends Privileged {} - public static final class Privileged2 extends Privileged {} - public static final class Privileged3 extends Privileged {} - public static final class Privileged4 extends Privileged {} - - public static class Sandboxed extends ChildProcessService {} - public static final class Sandboxed0 extends Sandboxed {} - public static final class Sandboxed1 extends Sandboxed {} - public static final class Sandboxed2 extends Sandboxed {} - public static final class Sandboxed3 extends Sandboxed {} - public static final class Sandboxed4 extends Sandboxed {} - public static final class Sandboxed5 extends Sandboxed {} - public static final class Sandboxed6 extends Sandboxed {} - public static final class Sandboxed7 extends Sandboxed {} - public static final class Sandboxed8 extends Sandboxed {} - public static final class Sandboxed9 extends Sandboxed {} - public static final class Sandboxed10 extends Sandboxed {} - public static final class Sandboxed11 extends Sandboxed {} - public static final class Sandboxed12 extends Sandboxed {} - public static final class Sandboxed13 extends Sandboxed {} - public static final class Sandboxed14 extends Sandboxed {} - public static final class Sandboxed15 extends Sandboxed {} - public static final class Sandboxed16 extends Sandboxed {} - public static final class Sandboxed17 extends Sandboxed {} - public static final class Sandboxed18 extends Sandboxed {} - public static final class Sandboxed19 extends Sandboxed {} - public static final class Sandboxed20 extends Sandboxed {} - public static final class Sandboxed21 extends Sandboxed {} - public static final class Sandboxed22 extends Sandboxed {} - public static final class Sandboxed23 extends Sandboxed {} - public static final class Sandboxed24 extends Sandboxed {} - public static final class Sandboxed25 extends Sandboxed {} - public static final class Sandboxed26 extends Sandboxed {} - public static final class Sandboxed27 extends Sandboxed {} - public static final class Sandboxed28 extends Sandboxed {} - public static final class Sandboxed29 extends Sandboxed {} - public static final class Sandboxed30 extends Sandboxed {} - public static final class Sandboxed31 extends Sandboxed {} - public static final class Sandboxed32 extends Sandboxed {} - public static final class Sandboxed33 extends Sandboxed {} - public static final class Sandboxed34 extends Sandboxed {} - public static final class Sandboxed35 extends Sandboxed {} - public static final class Sandboxed36 extends Sandboxed {} - public static final class Sandboxed37 extends Sandboxed {} - public static final class Sandboxed38 extends Sandboxed {} - public static final class Sandboxed39 extends Sandboxed {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java b/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java deleted file mode 100644 index 6949d28f..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.IContextMenuParams; - -/** - * Parameters for constructing context menu. - */ -class ContextMenuParams { - /** - * The Uri associated with the main frame of the page that triggered the context menu. - */ - @NonNull - public final Uri pageUri; - - /** - * The link Uri, if any. - */ - @Nullable - public final Uri linkUri; - - /** - * The link text, if any. - */ - @Nullable - public final String linkText; - - /** - * The title or alt attribute (if title is not available). - */ - @Nullable - public final String titleOrAltText; - - /** - * This is the source Uri for the element that the context menu was - * invoked on. Example of elements with source URLs are img, audio, and - * video. - */ - @Nullable - public final Uri srcUri; - - /** - * Whether srcUri points to an image. - * - * @since 88 - */ - public final boolean isImage; - - /** - * Whether srcUri points to a video. - * - * @since 88 - */ - public final boolean isVideo; - - /** - * Whether this link or image/video can be downloaded. Only if this is true can - * {@link Tab.download} be called. - * - * @since 88 - */ - public final boolean canDownload; - - final IContextMenuParams mContextMenuParams; - - protected ContextMenuParams( - Uri pageUri, Uri linkUri, String linkText, String titleOrAltText, Uri srcUri) { - this(pageUri, linkUri, linkText, titleOrAltText, srcUri, false, false, false, null); - } - - protected ContextMenuParams(Uri pageUri, Uri linkUri, String linkText, String titleOrAltText, - Uri srcUri, boolean isImage, boolean isVideo, boolean canDownload, - IContextMenuParams contextMenuParams) { - this.pageUri = pageUri; - this.linkUri = linkUri; - this.linkText = linkText; - this.titleOrAltText = titleOrAltText; - this.srcUri = srcUri; - this.isImage = isImage; - this.isVideo = isVideo; - this.canDownload = canDownload; - this.mContextMenuParams = contextMenuParams; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/CookieChangeCause.java b/weblayer/public/java/org/chromium/weblayer/CookieChangeCause.java deleted file mode 100644 index 367c3cd..0000000 --- a/weblayer/public/java/org/chromium/weblayer/CookieChangeCause.java +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({CookieChangeCause.INSERTED, CookieChangeCause.EXPLICIT, CookieChangeCause.UNKNOWN_DELETION, - CookieChangeCause.OVERWRITE, CookieChangeCause.EXPIRED, CookieChangeCause.EVICTED, - CookieChangeCause.EXPIRED_OVERWRITE}) -@Retention(RetentionPolicy.SOURCE) -@interface CookieChangeCause { - /** The cookie was inserted. */ - int INSERTED = org.chromium.weblayer_private.interfaces.CookieChangeCause.INSERTED; - /** The cookie was changed directly by a consumer's action. */ - int EXPLICIT = org.chromium.weblayer_private.interfaces.CookieChangeCause.EXPLICIT; - /** The cookie was deleted, but no more details are known. */ - int UNKNOWN_DELETION = - org.chromium.weblayer_private.interfaces.CookieChangeCause.UNKNOWN_DELETION; - /** The cookie was automatically removed due to an insert operation that overwrote it. */ - int OVERWRITE = org.chromium.weblayer_private.interfaces.CookieChangeCause.OVERWRITE; - /** The cookie was automatically removed as it expired. */ - int EXPIRED = org.chromium.weblayer_private.interfaces.CookieChangeCause.EXPIRED; - /** The cookie was automatically evicted during garbage collection. */ - int EVICTED = org.chromium.weblayer_private.interfaces.CookieChangeCause.EVICTED; - /** The cookie was overwritten with an already-expired expiration date. */ - int EXPIRED_OVERWRITE = - org.chromium.weblayer_private.interfaces.CookieChangeCause.EXPIRED_OVERWRITE; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/CookieChangedCallback.java b/weblayer/public/java/org/chromium/weblayer/CookieChangedCallback.java deleted file mode 100644 index ffdeaddb..0000000 --- a/weblayer/public/java/org/chromium/weblayer/CookieChangedCallback.java +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -/** - * Callback used to listen for cookie changes. - */ -abstract class CookieChangedCallback { - public abstract void onCookieChanged(@NonNull String cookie, @CookieChangeCause int cause); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/CookieManager.java b/weblayer/public/java/org/chromium/weblayer/CookieManager.java deleted file mode 100644 index 43b1ac0..0000000 --- a/weblayer/public/java/org/chromium/weblayer/CookieManager.java +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IBooleanCallback; -import org.chromium.weblayer_private.interfaces.ICookieChangedCallbackClient; -import org.chromium.weblayer_private.interfaces.ICookieManager; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.IStringCallback; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.util.List; - -/** - * Manages cookies for a WebLayer profile. - */ -class CookieManager { - private final ICookieManager mImpl; - - static CookieManager create(IProfile profile) { - try { - return new CookieManager(profile.getCookieManager()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - // Constructor for test mocking. - protected CookieManager() { - mImpl = null; - } - - private CookieManager(ICookieManager impl) { - mImpl = impl; - } - - /** - * Sets a cookie for the given URL. - * - * @param uri the URI for which the cookie is to be set. - * @param value the cookie string, using the format of the 'Set-Cookie' HTTP response header. - * @param callback a callback to be executed when the cookie has been set, or on failure. Called - * with true if the cookie is set successfully, and false if the cookie is not set for - * security reasons. - * - * @throws IllegalArgumentException if the cookie is invalid. - */ - public void setCookie( - @NonNull Uri uri, @NonNull String value, @NonNull IBooleanCallback callback) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.setCookie(uri.toString(), value, callback); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Gets the cookies for the given URL. - * - * @param uri the URI to get cookies for. - * @param callback a callback to be executed with the cookie value in the format of the 'Cookie' - * HTTP request header. If there is no cookie, this will be called with an empty string. - */ - public void getCookie(@NonNull Uri uri, @NonNull IStringCallback callback) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.getCookie(uri.toString(), callback); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Gets the cookies for the given URL in the form of the 'Set-Cookie' HTTP response header. - * - * @param uri the URI to get cookies for. - * @param callback a callback to be executed with a list of cookie strings in the format of the - * 'Set-Cookie' HTTP response header. - * @since 101 - */ - public void getResponseCookies(@NonNull Uri uri, @NonNull Callback<List<String>> callback) { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 101) { - throw new UnsupportedOperationException(); - } - try { - ValueCallback<List<String>> valueCallback = (List<String> result) -> { - callback.onResult(result); - }; - mImpl.getResponseCookies(uri.toString(), ObjectWrapper.wrap(valueCallback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Adds a callback to listen for changes to cookies for the given URI. - * - * @param uri the URI to listen to cookie changes on. - * @param name the name of the cookie to listen for changes on. Can be null to listen for - * changes on all cookies. - * @param callback a callback that will be notified on cookie changes. - * @return a Runnable which will unregister the callback from listening to cookie changes. - * @throws IllegalArgumentException if the cookie name is an empty string. - */ - @NonNull - public Runnable addCookieChangedCallback( - @NonNull Uri uri, @Nullable String name, @NonNull CookieChangedCallback callback) { - ThreadCheck.ensureOnUiThread(); - if (name != null && name.isEmpty()) { - throw new IllegalArgumentException( - "Name cannot be empty, use null to listen for all cookie changes."); - } - try { - return ObjectWrapper.unwrap(mImpl.addCookieChangedCallback(uri.toString(), name, - new CookieChangedCallbackClientImpl(callback)), - Runnable.class); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - private static final class CookieChangedCallbackClientImpl - extends ICookieChangedCallbackClient.Stub { - private final CookieChangedCallback mCallback; - - CookieChangedCallbackClientImpl(CookieChangedCallback callback) { - mCallback = callback; - } - - @Override - public void onCookieChanged(String cookie, @CookieChangeCause int cause) { - StrictModeWorkaround.apply(); - mCallback.onCookieChanged(cookie, cause); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/CookieManagerDelegate.java b/weblayer/public/java/org/chromium/weblayer/CookieManagerDelegate.java deleted file mode 100644 index b69ed0cb..0000000 --- a/weblayer/public/java/org/chromium/weblayer/CookieManagerDelegate.java +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.ExceptionType; -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.ICookieManagerDelegate; -import org.chromium.webengine.interfaces.IStringCallback; -import org.chromium.weblayer_private.interfaces.APICallException; - -/** - * This class acts as a proxy between the embedding app's WebFragment and - * the WebLayer implementation. - */ -class CookieManagerDelegate extends ICookieManagerDelegate.Stub { - private CookieManager mCookieManager; - private Handler mHandler = new Handler(Looper.getMainLooper()); - - CookieManagerDelegate(CookieManager cookieManager) { - mCookieManager = cookieManager; - } - - @Override - public void setCookie(String uri, String value, IBooleanCallback callback) { - mHandler.post(() -> { - try { - mCookieManager.setCookie(Uri.parse(uri), value, - new org.chromium.weblayer_private.interfaces.IBooleanCallback.Stub() { - @Override - public void onResult(boolean result) { - try { - callback.onResult(result); - } catch (RemoteException e) { - } - } - @Override - public void onException(@ExceptionType int type, String msg) { - try { - callback.onException(ExceptionHelper.convertType(type), msg); - } catch (RemoteException e) { - } - } - }); - } catch (APICallException e) { - try { - callback.onException(ExceptionType.UNKNOWN, e.getMessage()); - } catch (RemoteException re) { - } - } - }); - } - - @Override - public void getCookie(String uri, IStringCallback callback) { - mHandler.post(() -> { - try { - mCookieManager.getCookie(Uri.parse(uri), - new org.chromium.weblayer_private.interfaces.IStringCallback.Stub() { - @Override - public void onResult(String result) { - try { - callback.onResult(result); - } catch (RemoteException e) { - } - } - @Override - public void onException(@ExceptionType int type, String msg) { - try { - callback.onException(ExceptionHelper.convertType(type), msg); - } catch (RemoteException e) { - } - } - }); - } catch (APICallException e) { - try { - callback.onException(ExceptionType.UNKNOWN, e.getMessage()); - } catch (RemoteException re) { - } - } - }); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/DarkModeStrategy.java b/weblayer/public/java/org/chromium/weblayer/DarkModeStrategy.java deleted file mode 100644 index 0f597ff..0000000 --- a/weblayer/public/java/org/chromium/weblayer/DarkModeStrategy.java +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({DarkModeStrategy.PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING, - DarkModeStrategy.WEB_THEME_DARKENING_ONLY, DarkModeStrategy.USER_AGENT_DARKENING_ONLY}) -@Retention(RetentionPolicy.SOURCE) -@interface DarkModeStrategy { - /** - * Only render pages in dark mode if they provide a dark theme in their CSS. If no theme is - * provided, the page will render with its default styling, which could be a light theme. - */ - int WEB_THEME_DARKENING_ONLY = - org.chromium.weblayer_private.interfaces.DarkModeStrategy.WEB_THEME_DARKENING_ONLY; - - /** - * Always apply automatic user-agent darkening to pages, ignoring any dark theme that the - * site provides. All pages will appear dark in this mode. - */ - int USER_AGENT_DARKENING_ONLY = - org.chromium.weblayer_private.interfaces.DarkModeStrategy.USER_AGENT_DARKENING_ONLY; - - /** - * Render pages using their specified dark theme if available, otherwise fall back on automatic - * user-agent darkening. All pages will appear dark in this mode. - */ - int PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = - org.chromium.weblayer_private.interfaces.DarkModeStrategy - .PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/Download.java b/weblayer/public/java/org/chromium/weblayer/Download.java deleted file mode 100644 index 9e32c17c..0000000 --- a/weblayer/public/java/org/chromium/weblayer/Download.java +++ /dev/null
@@ -1,167 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IClientDownload; -import org.chromium.weblayer_private.interfaces.IDownload; - -import java.io.File; - -/** - * Contains information about a single download that's in progress. - */ -class Download extends IClientDownload.Stub { - private final IDownload mDownloadImpl; - - // Constructor for test mocking. - protected Download() { - mDownloadImpl = null; - } - - Download(IDownload impl) { - mDownloadImpl = impl; - } - - /** - * By default downloads will show a system notification. Call this to disable it. - */ - public void disableNotification() { - ThreadCheck.ensureOnUiThread(); - try { - mDownloadImpl.disableNotification(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @DownloadState - public int getState() { - ThreadCheck.ensureOnUiThread(); - try { - return mDownloadImpl.getState(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the total number of expected bytes. Returns -1 if the total size is not known. - */ - public long getTotalBytes() { - ThreadCheck.ensureOnUiThread(); - try { - return mDownloadImpl.getTotalBytes(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Total number of bytes that have been received and written to the download file. - */ - public long getReceivedBytes() { - ThreadCheck.ensureOnUiThread(); - try { - return mDownloadImpl.getReceivedBytes(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Pauses the download. - */ - public void pause() { - ThreadCheck.ensureOnUiThread(); - try { - mDownloadImpl.pause(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Resumes the download. - */ - public void resume() { - ThreadCheck.ensureOnUiThread(); - try { - mDownloadImpl.resume(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Cancels the download. - */ - public void cancel() { - ThreadCheck.ensureOnUiThread(); - try { - mDownloadImpl.cancel(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the location of the downloaded file. This may be empty if the target path hasn't been - * determined yet. The file it points to won't be available until the download completes - * successfully. - */ - @NonNull - public File getLocation() { - ThreadCheck.ensureOnUiThread(); - try { - return new File(mDownloadImpl.getLocation()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the file name for the download that should be displayed to the user. - */ - @NonNull - public File getFileNameToReportToUser() { - ThreadCheck.ensureOnUiThread(); - try { - return new File(mDownloadImpl.getFileNameToReportToUser()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the effective MIME type of downloaded content. - */ - @NonNull - public String getMimeType() { - ThreadCheck.ensureOnUiThread(); - try { - return mDownloadImpl.getMimeType(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Return information about the error, if any, that was encountered during the download. - */ - @DownloadError - public int getError() { - ThreadCheck.ensureOnUiThread(); - try { - return mDownloadImpl.getError(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/DownloadCallback.java b/weblayer/public/java/org/chromium/weblayer/DownloadCallback.java deleted file mode 100644 index 42bc6c1..0000000 --- a/weblayer/public/java/org/chromium/weblayer/DownloadCallback.java +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * An interface that allows clients to handle download requests originating in the browser. - */ -abstract class DownloadCallback { - /** - * A download of has been requested with the specified details. If it returns true the download - * will be considered intercepted and WebLayer won't proceed with it. Note that there are many - * corner cases where the embedder downloading it won't work (e.g. POSTs, one-time URLs, - * requests that depend on cookies or auth state). This is called after AllowDownload. - * - * @param uri the target that should be downloaded - * @param userAgent the user agent to be used for the download - * @param contentDisposition content-disposition http header, if present - * @param mimetype the mimetype of the content reported by the server - * @param contentLength the file size reported by the server - */ - public abstract boolean onInterceptDownload(@NonNull Uri uri, @NonNull String userAgent, - @NonNull String contentDisposition, @NonNull String mimetype, long contentLength); - - /** - * Gives the embedder the opportunity to asynchronously allow or disallow the - * given download. It's safe to run |callback| synchronously. - * - * @param uri the target that is being downloaded - * @param requestMethod the method (GET/POST etc...) of the download - * @param requestInitiator the initiating Uri, if present - * @param callback a callback to allow or disallow the download. Must be called to avoid leaks, - * and must be called on the UI thread. - */ - public abstract void allowDownload(@NonNull Uri uri, @NonNull String requestMethod, - @Nullable Uri requestInitiator, @NonNull ValueCallback<Boolean> callback); - - /** - * A download has started. There will be 0..n calls to DownloadProgressChanged, then either a - * call to DownloadCompleted or DownloadFailed. The same |download| will be provided on - * subsequent calls to those methods when related to this download. Observers should clear any - * references to |download| in onDownloadCompleted or onDownloadFailed, just before it is - * destroyed. - * - * @param download the unique object for this download. - */ - public void onDownloadStarted(@NonNull Download download) {} - - /** - * The download progress has changed. - * - * @param download the unique object for this download. - */ - public void onDownloadProgressChanged(@NonNull Download download) {} - - /** - * The download has completed successfully. - * - * Note that |download| will be destroyed at the end of this call, so do not keep a reference - * to it afterward. - * - * @param download the unique object for this download. - */ - public void onDownloadCompleted(@NonNull Download download) {} - - /** - * The download has failed because the user cancelled it or because of a server or network - * error. - * - * Note that |download| will be destroyed at the end of this call, so do not keep a reference - * to it afterward. - * - * @param download the unique object for this download. - */ - public void onDownloadFailed(@NonNull Download download) {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/DownloadError.java b/weblayer/public/java/org/chromium/weblayer/DownloadError.java deleted file mode 100644 index ea00adc..0000000 --- a/weblayer/public/java/org/chromium/weblayer/DownloadError.java +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({DownloadError.NO_ERROR, DownloadError.SERVER_ERROR, DownloadError.SSL_ERROR, - DownloadError.CONNECTIVITY_ERROR, DownloadError.NO_SPACE, DownloadError.FILE_ERROR, - DownloadError.CANCELLED, DownloadError.OTHER_ERROR}) -@Retention(RetentionPolicy.SOURCE) -@interface DownloadError { - int NO_ERROR = org.chromium.weblayer_private.interfaces.DownloadError.NO_ERROR; - int SERVER_ERROR = org.chromium.weblayer_private.interfaces.DownloadError.SERVER_ERROR; - int SSL_ERROR = org.chromium.weblayer_private.interfaces.DownloadError.SSL_ERROR; - int CONNECTIVITY_ERROR = - org.chromium.weblayer_private.interfaces.DownloadError.CONNECTIVITY_ERROR; - int NO_SPACE = org.chromium.weblayer_private.interfaces.DownloadError.NO_SPACE; - int FILE_ERROR = org.chromium.weblayer_private.interfaces.DownloadError.FILE_ERROR; - int CANCELLED = org.chromium.weblayer_private.interfaces.DownloadError.CANCELLED; - int OTHER_ERROR = org.chromium.weblayer_private.interfaces.DownloadError.OTHER_ERROR; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/DownloadState.java b/weblayer/public/java/org/chromium/weblayer/DownloadState.java deleted file mode 100644 index d129e00..0000000 --- a/weblayer/public/java/org/chromium/weblayer/DownloadState.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({DownloadState.IN_PROGRESS, DownloadState.COMPLETE, DownloadState.PAUSED, - DownloadState.CANCELLED, DownloadState.FAILED}) -@Retention(RetentionPolicy.SOURCE) -@interface DownloadState { - int IN_PROGRESS = org.chromium.weblayer_private.interfaces.DownloadState.IN_PROGRESS; - int COMPLETE = org.chromium.weblayer_private.interfaces.DownloadState.COMPLETE; - int PAUSED = org.chromium.weblayer_private.interfaces.DownloadState.PAUSED; - int CANCELLED = org.chromium.weblayer_private.interfaces.DownloadState.CANCELLED; - int FAILED = org.chromium.weblayer_private.interfaces.DownloadState.FAILED; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ErrorPage.java b/weblayer/public/java/org/chromium/weblayer/ErrorPage.java deleted file mode 100644 index 7419c1e..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ErrorPage.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -/** - * ErrorPage contains the html to show when an error is encountered. - */ -class ErrorPage { - public final String htmlContent; - - /** - * Creates an ErrorPage. - * - * @param htmlContent The html to show. - * - */ - public ErrorPage(@NonNull String htmlContent) { - this.htmlContent = htmlContent; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ErrorPageCallback.java b/weblayer/public/java/org/chromium/weblayer/ErrorPageCallback.java deleted file mode 100644 index 0eff7621..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ErrorPageCallback.java +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * An interface that allows clients to handle error page interactions. - */ -abstract class ErrorPageCallback { - /** - * The user has attempted to back out of an error page, such as one warning of an SSL error. - * - * @return true if the action was overridden and WebLayer should skip default handling. - */ - public abstract boolean onBackToSafety(); - - /** - * Called when an error is encountered. A null return value results in a default error page - * being shown, a non-null return value results in showing the content of the returned - * {@link ErrorPage}. - * - * @param navigation The navigation that encountered the error. - * - * @return The error page. - */ - public @Nullable ErrorPage getErrorPage(@NonNull Navigation navigation) { - return null; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ExceptionHelper.java b/weblayer/public/java/org/chromium/weblayer/ExceptionHelper.java deleted file mode 100644 index a3fd522..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ExceptionHelper.java +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import org.chromium.weblayer_private.interfaces.ExceptionType; - -class ExceptionHelper { - static @ExceptionType int convertType(@ExceptionType int type) { - switch (type) { - case ExceptionType.RESTRICTED_API: - return org.chromium.webengine.interfaces.ExceptionType.RESTRICTED_API; - case ExceptionType.UNKNOWN: - return org.chromium.webengine.interfaces.ExceptionType.UNKNOWN; - } - assert false : "Unexpected ExceptionType: " + String.valueOf(type); - return org.chromium.webengine.interfaces.ExceptionType.UNKNOWN; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ExternalIntentInIncognitoCallback.java b/weblayer/public/java/org/chromium/weblayer/ExternalIntentInIncognitoCallback.java deleted file mode 100644 index 3caa631..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ExternalIntentInIncognitoCallback.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -/** - * Allows the embedder to present a custom warning dialog gating external intent launch in - * incognito mode rather than WebLayer's default dialog being used. - * See {@link Tab#setExternalIntentInIncognitoCallback()}. - * @since 93 - */ -abstract class ExternalIntentInIncognitoCallback { - /* Invoked when the user initiates a launch of an intent in incognito mode. The embedder's - * implementation should present a modal dialog warning the user that they are leaving - * incognito and asking if they wish to continue; it should then invoke onUserDecision() with - * the user's decision once obtained (passing the value as an Integer wrapping an - * @ExternalIntentInIncognitoUserDecision). - * NOTE: The dialog presented *must* be modal, as confusion of state can otherwise occur. */ - public abstract void onExternalIntentInIncognito( - @NonNull Callback<Integer> onUserDecisionCallback); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ExternalIntentInIncognitoUserDecision.java b/weblayer/public/java/org/chromium/weblayer/ExternalIntentInIncognitoUserDecision.java deleted file mode 100644 index 2a70820..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ExternalIntentInIncognitoUserDecision.java +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@IntDef({ExternalIntentInIncognitoUserDecision.ALLOW, ExternalIntentInIncognitoUserDecision.DENY}) -@Retention(RetentionPolicy.SOURCE) -@interface ExternalIntentInIncognitoUserDecision { - int ALLOW = - org.chromium.weblayer_private.interfaces.ExternalIntentInIncognitoUserDecision.ALLOW; - int DENY = org.chromium.weblayer_private.interfaces.ExternalIntentInIncognitoUserDecision.DENY; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/FaviconCallback.java b/weblayer/public/java/org/chromium/weblayer/FaviconCallback.java deleted file mode 100644 index 42aba9f..0000000 --- a/weblayer/public/java/org/chromium/weblayer/FaviconCallback.java +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; - -import androidx.annotation.Nullable; - -/** - * Informed of changes to the favicon of the current navigation. - */ -abstract class FaviconCallback { - /** - * Called when the favicon of the current navigation has changed. This is called with null when - * a navigation is started. - * - * @param favicon The favicon. - */ - public void onFaviconChanged(@Nullable Bitmap favicon) {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/FaviconFetcher.java b/weblayer/public/java/org/chromium/weblayer/FaviconFetcher.java deleted file mode 100644 index 1eca26f6..0000000 --- a/weblayer/public/java/org/chromium/weblayer/FaviconFetcher.java +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; -import android.os.RemoteException; - -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IFaviconFetcher; -import org.chromium.weblayer_private.interfaces.IFaviconFetcherClient; -import org.chromium.weblayer_private.interfaces.ITab; - -/** - * {@link FaviconFetcher} is responsible for downloading a favicon for the current navigation. - * {@link FaviconFetcher} maintains an on disk cache of favicons downloading favicons as necessary. - */ -class FaviconFetcher { - private final FaviconCallback mCallback; - private IFaviconFetcher mImpl; - private @Nullable Bitmap mBitmap; - - // Constructor for test mocking. - protected FaviconFetcher() { - mCallback = null; - } - - FaviconFetcher(ITab iTab, FaviconCallback callback) { - mCallback = callback; - try { - mImpl = iTab.createFaviconFetcher(new FaviconFetcherClientImpl()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Destroys this FaviconFetcher. The callback will no longer be notified. This is implicitly - * called when the Tab is destroyed. - */ - public void destroy() { - ThreadCheck.ensureOnUiThread(); - // As the implementation may implicitly destroy this, allow destroy() to be called multiple - // times. - if (mImpl == null) return; - try { - mImpl.destroy(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the favicon for the current navigation. This returns a null Bitmap if the favicon - * isn't available yet (which includes no navigation). - * - * @return The favicon. - */ - public @Nullable Bitmap getFaviconForCurrentNavigation() { - ThreadCheck.ensureOnUiThread(); - return mBitmap; - } - - private final class FaviconFetcherClientImpl extends IFaviconFetcherClient.Stub { - @Override - public void onDestroyed() { - mImpl = null; - } - - @Override - public void onFaviconChanged(Bitmap bitmap) { - mBitmap = bitmap; - mCallback.onFaviconChanged(bitmap); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/FindInPageCallback.java b/weblayer/public/java/org/chromium/weblayer/FindInPageCallback.java deleted file mode 100644 index 355553d..0000000 --- a/weblayer/public/java/org/chromium/weblayer/FindInPageCallback.java +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * Informed of find in page results. - */ -abstract class FindInPageCallback { - /** - * Called when incremental results from a find operation are ready. - * - * @param numberOfMatches The total number of matches found thus far. - * @param activeMatchIndex The index of the currently highlighted match. - * @param finalUpdate Whether this is the last find result that can be expected for the current - * find operation. - */ - public void onFindResult(int numberOfMatches, int activeMatchIndex, boolean finalUpdate) {} - - /** - * Called when WebLayer has ended the find session, for example due to the Tab losing active - * status. This will not be invoked when the client ends a find session via {@link - * FindInPageController#setFindInPageCallback} with a {@code null} value. - */ - public void onFindEnded() {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/FindInPageController.java b/weblayer/public/java/org/chromium/weblayer/FindInPageController.java deleted file mode 100644 index 30f4e68..0000000 --- a/weblayer/public/java/org/chromium/weblayer/FindInPageController.java +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IFindInPageCallbackClient; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -/** - * Initiates find-in-page operations. - * - * There is one FindInPageController per {@link Tab}, and only the active tab may have an active - * find session. - */ -class FindInPageController { - private final ITab mTab; - - protected FindInPageController() { - mTab = null; - } - - FindInPageController(ITab tab) { - mTab = tab; - } - - /** - * Starts or ends a find session. - * - * When called with a non-null parameter, this starts a find session and displays a find result - * bar over the affected web page. When called with a null parameter, the find session will end - * and the result bar will be removed. - * - * @param callback The object that will be notified of find results, or null to end the find - * session. - * @return True if the operation succeeded. Ending a find session will always succeed, but - * starting one may fail, for example if the tab is not active or a find session is - * already started. - */ - public boolean setFindInPageCallback(@Nullable FindInPageCallback callback) { - ThreadCheck.ensureOnUiThread(); - try { - FindInPageCallbackClientImpl callbackClient = null; - if (callback != null) { - callbackClient = new FindInPageCallbackClientImpl(callback); - } - return mTab.setFindInPageCallbackClient(callbackClient); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Called to initiate an in-page text search for the given string. - * - * Results will be highlighted in context, with additional attention drawn to the "active" - * result. The position of results will also be displayed on the find result bar. - * This has no effect if there is no active find session. - * - * @param searchText The {@link String} to search for. Any pre-existing search results will be - * cleared. - * @param forward The direction to move the "active" result. This only applies when the search - * text matches that of the last search. - */ - public void find(@NonNull String searchText, boolean forward) { - ThreadCheck.ensureOnUiThread(); - try { - mTab.findInPage(searchText, forward); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - private static final class FindInPageCallbackClientImpl extends IFindInPageCallbackClient.Stub { - private final FindInPageCallback mCallback; - - FindInPageCallbackClientImpl(FindInPageCallback callback) { - mCallback = callback; - } - - public FindInPageCallback getCallback() { - return mCallback; - } - - @Override - public void onFindResult(int numberOfMatches, int activeMatchOrdinal, boolean finalUpdate) { - StrictModeWorkaround.apply(); - mCallback.onFindResult(numberOfMatches, activeMatchOrdinal, finalUpdate); - } - - @Override - public void onFindEnded() { - StrictModeWorkaround.apply(); - mCallback.onFindEnded(); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/FullscreenCallback.java b/weblayer/public/java/org/chromium/weblayer/FullscreenCallback.java deleted file mode 100644 index cebdb3a..0000000 --- a/weblayer/public/java/org/chromium/weblayer/FullscreenCallback.java +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -/** - * Used to configure fullscreen related state. HTML fullscreen support is only enabled if a - * FullscreenCallback is set. - */ -abstract class FullscreenCallback { - /** - * Called when the page has requested to go fullscreen. The delegate is responsible for - * putting the system into fullscreen mode. The delegate can exit out of fullscreen by - * running the supplied Runnable (calling exitFullscreenRunner.Run() results in calling - * exitFullscreen()). - * - * NOTE: we expect WebLayer to be covering the whole display without any other UI elements from - * the embedder or Android on screen. Otherwise some web features (e.g. WebXR) might experience - * clipped or misaligned UI elements. - * - * NOTE: the Runnable must not be used synchronously, and must be run on the UI thread. - */ - public abstract void onEnterFullscreen(@NonNull Runnable exitFullscreenRunner); - - /** - * The page has exited fullscreen mode and the system should be moved out of fullscreen mode. - */ - public abstract void onExitFullscreen(); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/FullscreenCallbackDelegate.java b/weblayer/public/java/org/chromium/weblayer/FullscreenCallbackDelegate.java deleted file mode 100644 index 82b30c8..0000000 --- a/weblayer/public/java/org/chromium/weblayer/FullscreenCallbackDelegate.java +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import org.chromium.webengine.interfaces.IFullscreenCallbackDelegate; -import org.chromium.webengine.interfaces.IFullscreenClient; - -/** - * This class acts as a proxy between the Fullscreen events happening in - * weblayer and the FullscreenCallbackDelegate in webengine. - */ -class FullscreenCallbackDelegate extends FullscreenCallback { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private IFullscreenCallbackDelegate mFullscreenCallbackDelegate; - - void setDelegate(IFullscreenCallbackDelegate delegate) { - mFullscreenCallbackDelegate = delegate; - } - - @Override - public void onEnterFullscreen(@NonNull Runnable exitFullscreenRunner) { - if (mFullscreenCallbackDelegate != null) { - try { - mFullscreenCallbackDelegate.onEnterFullscreen(new IFullscreenClient.Stub() { - @Override - public void exitFullscreen() { - mHandler.post(() -> { exitFullscreenRunner.run(); }); - } - }); - } catch (RemoteException e) { - } - } - } - - @Override - public void onExitFullscreen() { - if (mFullscreenCallbackDelegate != null) { - try { - mFullscreenCallbackDelegate.onExitFullscreen(); - } catch (RemoteException e) { - } - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/GoogleAccountAccessTokenFetcher.java b/weblayer/public/java/org/chromium/weblayer/GoogleAccountAccessTokenFetcher.java deleted file mode 100644 index da70da2..0000000 --- a/weblayer/public/java/org/chromium/weblayer/GoogleAccountAccessTokenFetcher.java +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -import java.util.Set; - -/** - * Used to fetch OAuth2 access tokens for the user's current GAIA account. - * @since 89 - */ -abstract class GoogleAccountAccessTokenFetcher { - /** - * Called when the WebLayer implementation wants to fetch an access token for the embedder's - * current GAIA account (if any) and the given scopes. The client should invoke - * |onTokenFetchedCallback| when its internal token fetch is complete, passing either the - * fetched access token or the empty string in the case of failure (e.g., if there is no current - * GAIA account or there was an error in the token fetch). - * - * NOTE: WebLayer will not perform any caching of the returned token but will instead make a new - * request each time that it needs to use an access token. The expectation is that the client - * will use caching internally to minimize latency of these requests. - */ - public abstract void fetchAccessToken( - @NonNull Set<String> scopes, @NonNull Callback<String> onTokenFetchedCallback); - - /** - * Called when a token previously obtained via a call to fetchAccessToken(|scopes|) is - * identified as invalid, so the embedder can take appropriate action (e.g., dropping the token - * from its cache and/or force-fetching a new token). - */ - public abstract void onAccessTokenIdentifiedAsInvalid( - @NonNull Set<String> scopes, @NonNull String token); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/GoogleAccountServiceType.java b/weblayer/public/java/org/chromium/weblayer/GoogleAccountServiceType.java deleted file mode 100644 index 5242b5f..0000000 --- a/weblayer/public/java/org/chromium/weblayer/GoogleAccountServiceType.java +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({GoogleAccountServiceType.SIGNOUT, GoogleAccountServiceType.ADD_SESSION, - GoogleAccountServiceType.DEFAULT}) -@Retention(RetentionPolicy.SOURCE) -@interface GoogleAccountServiceType { - /** - * Logout all existing sessions. - */ - int SIGNOUT = org.chromium.weblayer_private.interfaces.GoogleAccountServiceType.SIGNOUT; - - /** - * Add or re-authenticate an account. - */ - int ADD_SESSION = org.chromium.weblayer_private.interfaces.GoogleAccountServiceType.ADD_SESSION; - - /** - * All other cases. - */ - int DEFAULT = org.chromium.weblayer_private.interfaces.GoogleAccountServiceType.DEFAULT; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/GoogleAccountsCallback.java b/weblayer/public/java/org/chromium/weblayer/GoogleAccountsCallback.java deleted file mode 100644 index 3259cb8b..0000000 --- a/weblayer/public/java/org/chromium/weblayer/GoogleAccountsCallback.java +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -/** - * Used to intercept interaction with GAIA accounts. - */ -abstract class GoogleAccountsCallback { - /** - * Called when a user wants to change the state of their GAIA account. This could be a signin, - * signout, or any other action. See {@link GoogleAccountServiceType} for all the possible - * actions. - */ - public abstract void onGoogleAccountsRequest(@NonNull GoogleAccountsParams params); - - /** - * The current GAIA ID the user is signed in with, or empty if the user is signed out. This can - * be provided on a best effort basis if the ID is not available immediately. - */ - public abstract @NonNull String getGaiaId(); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/GoogleAccountsParams.java b/weblayer/public/java/org/chromium/weblayer/GoogleAccountsParams.java deleted file mode 100644 index a50f239..0000000 --- a/weblayer/public/java/org/chromium/weblayer/GoogleAccountsParams.java +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; - -import androidx.annotation.NonNull; - -/** - * Params passed to {@link GoogleAccountsCallback#onGoogleAccountsRequest}. - */ -class GoogleAccountsParams { - /** - * The requested service type such as "ADD_SESSION". - */ - public final @GoogleAccountServiceType int serviceType; - - /** - * The prefilled email. May be empty. - */ - public final @NonNull String email; - - /** - * The continue URL after the requested service is completed successfully. May be empty. - */ - public final @NonNull Uri continueUri; - - /** - * Whether the continue URL should be loaded in the same tab. - */ - public final boolean isSameTab; - - public GoogleAccountsParams(@GoogleAccountServiceType int serviceType, String email, - Uri continueUri, boolean isSameTab) { - this.serviceType = serviceType; - this.email = email; - this.continueUri = continueUri; - this.isSameTab = isSameTab; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/GooglePayDataCallbacksServiceWrapper.java b/weblayer/public/java/org/chromium/weblayer/GooglePayDataCallbacksServiceWrapper.java deleted file mode 100644 index 76a9a40..0000000 --- a/weblayer/public/java/org/chromium/weblayer/GooglePayDataCallbacksServiceWrapper.java +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; -import android.os.RemoteException; - -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IWebLayer; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * A wrapper service of GooglePayDataCallbacksService. The wrapping is necessary because - * WebLayer's internal parts are not allowed to interact with the external apps directly. - * - * @since 90 - */ -class GooglePayDataCallbacksServiceWrapper extends Service { - @Nullable - private Service mService; - - @Override - public void onCreate() { - ThreadCheck.ensureOnUiThread(); - Service service = createService(); - if (service == null) { - stopSelf(); - return; - } - mService = service; - mService.onCreate(); - } - - @Nullable - private Service createService() { - if (WebLayer.getSupportedMajorVersionInternal() < 90) return null; - if (!WebLayer.hasWebLayerInitializationStarted()) return null; - WebLayer webLayer = WebLayer.getLoadedWebLayer(this); - if (webLayer == null) return null; - IWebLayer iWebLayer = webLayer.getImpl(); - if (iWebLayer == null) return null; - IObjectWrapper objectWrapper; - try { - objectWrapper = iWebLayer.createGooglePayDataCallbacksService(); - } catch (RemoteException e) { - throw new APICallException(e); - } - if (objectWrapper == null) return null; - return ObjectWrapper.unwrap(objectWrapper, Service.class); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - if (mService == null) return null; - try { - return mService.onBind(intent); - } catch (Exception e) { - throw new APICallException(e); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ImageDecoderService.java b/weblayer/public/java/org/chromium/weblayer/ImageDecoderService.java deleted file mode 100644 index 7b7459e..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ImageDecoderService.java +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * A service used internally by WebLayer for decoding images on the local device. - */ -class ImageDecoderService extends Service { - private IBinder mImageDecoder; - - @Override - public void onCreate() { - try { - mImageDecoder = - WebLayer.getIWebLayer(this).initializeImageDecoder(ObjectWrapper.wrap(this), - ObjectWrapper.wrap(WebLayer.getOrCreateRemoteContext(this))); - } catch (Exception e) { - throw new APICallException(e); - } - } - - @Override - public IBinder onBind(Intent intent) { - return mImageDecoder; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/LoadError.java b/weblayer/public/java/org/chromium/weblayer/LoadError.java deleted file mode 100644 index 28e61a7..0000000 --- a/weblayer/public/java/org/chromium/weblayer/LoadError.java +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({LoadError.NO_ERROR, LoadError.HTTP_CLIENT_ERROR, LoadError.HTTP_SERVER_ERROR, - LoadError.SSL_ERROR, LoadError.CONNECTIVITY_ERROR, LoadError.OTHER_ERROR}) -@Retention(RetentionPolicy.SOURCE) -@interface LoadError { - /** - * Navigation completed successfully. - */ - int NO_ERROR = org.chromium.weblayer_private.interfaces.LoadError.NO_ERROR; - - /** - * Server responded with 4xx status code. - */ - int HTTP_CLIENT_ERROR = org.chromium.weblayer_private.interfaces.LoadError.HTTP_CLIENT_ERROR; - /** - * Server responded with 5xx status code. - */ - int HTTP_SERVER_ERROR = org.chromium.weblayer_private.interfaces.LoadError.HTTP_SERVER_ERROR; - - /** - * Certificate error. - */ - int SSL_ERROR = org.chromium.weblayer_private.interfaces.LoadError.SSL_ERROR; - - /** - * Problem connecting to server. - */ - int CONNECTIVITY_ERROR = org.chromium.weblayer_private.interfaces.LoadError.CONNECTIVITY_ERROR; - - /** - * An error not listed above or below occurred. - */ - int OTHER_ERROR = org.chromium.weblayer_private.interfaces.LoadError.OTHER_ERROR; - - /** - * Safe browsing error. - * - * @since 88 - */ - int SAFE_BROWSING_ERROR = - org.chromium.weblayer_private.interfaces.LoadError.SAFE_BROWSING_ERROR; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/MediaCaptureCallback.java b/weblayer/public/java/org/chromium/weblayer/MediaCaptureCallback.java deleted file mode 100644 index 15034e05..0000000 --- a/weblayer/public/java/org/chromium/weblayer/MediaCaptureCallback.java +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.webkit.ValueCallback; - -/** - * Used along with {@link MediaCaptureController} to control and observe Media Capture and Streams - * usage. - */ -abstract class MediaCaptureCallback { - /** - * Called when a site in a Tab requests to start capturing media from the user's device. - * - * This will be called only if the app already has the requisite permissions and the user has - * granted permissions to the site that is making the request. - * - * At least one of the two boolean parameters will be true. Note that a single tab can have more - * than one concurrent active stream, and these parameters only represent the state of the new - * stream. - * - * @param audio if true, the new stream includes audio from a microphone. - * @param video if true, the new stream includes video from a camera. - * @param requestResult a callback to be run with true if and when the stream can start, or - * false if the stream should not start. Must be run on the UI thread. - */ - public void onMediaCaptureRequested( - boolean audio, boolean video, ValueCallback<Boolean> requestResult) {} - - /** - * Called when media streaming state will change in the Tab. - * - * A site will receive audio/video from the device’s hardware. This - * may be called with both parameters false to indicate all streaming - * has stopped, or multiple times in a row with different parameter - * values as streaming state changes to include or exclude hardware. - * - * @param audio if true, the stream includes audio from a microphone. - * @param video if true, the stream includes video from a camera. - */ - public void onMediaCaptureStateChanged(boolean audio, boolean video) {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/MediaCaptureController.java b/weblayer/public/java/org/chromium/weblayer/MediaCaptureController.java deleted file mode 100644 index 3fea249..0000000 --- a/weblayer/public/java/org/chromium/weblayer/MediaCaptureController.java +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IMediaCaptureCallbackClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -/** - * Used to control Media Capture and Streams Web API operations. - * - * The Web API is used by sites to record video and audio from the user's device, e.g. for voice - * recognition or video conferencing. There is one MediaCaptureController per {@link Tab}. - */ -class MediaCaptureController { - private final ITab mTab; - - protected MediaCaptureController() { - mTab = null; - } - - MediaCaptureController(ITab tab) { - mTab = tab; - } - - /** - * Sets the callback for the tab. - * @param MediaCaptureCallback the callback to use, or null. If null, capture requests will be - * allowed (assuming the system and user granted permission). - */ - public void setMediaCaptureCallback(@Nullable MediaCaptureCallback callback) { - ThreadCheck.ensureOnUiThread(); - try { - MediaCaptureCallbackClientImpl callbackClient = null; - if (callback != null) { - callbackClient = new MediaCaptureCallbackClientImpl(callback); - } - mTab.setMediaCaptureCallbackClient(callbackClient); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Called to stop the active media stream(s) in a tab. - */ - public void stopMediaCapturing() { - ThreadCheck.ensureOnUiThread(); - try { - mTab.stopMediaCapturing(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - private static final class MediaCaptureCallbackClientImpl - extends IMediaCaptureCallbackClient.Stub { - private final MediaCaptureCallback mCallback; - - MediaCaptureCallbackClientImpl(MediaCaptureCallback callback) { - mCallback = callback; - } - - public MediaCaptureCallback getCallback() { - return mCallback; - } - - @Override - public void onMediaCaptureRequested( - boolean audio, boolean video, IObjectWrapper callbackWrapper) { - StrictModeWorkaround.apply(); - ValueCallback<Boolean> requestResultCallback = - (ValueCallback<Boolean>) ObjectWrapper.unwrap( - callbackWrapper, ValueCallback.class); - mCallback.onMediaCaptureRequested(audio, video, requestResultCallback); - } - - @Override - public void onMediaCaptureStateChanged(boolean audio, boolean video) { - StrictModeWorkaround.apply(); - mCallback.onMediaCaptureStateChanged(audio, video); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java b/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java deleted file mode 100644 index f350725..0000000 --- a/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Base class that provides common functionality for media playback services that are associated - * with an active media session and Android notification. - */ -abstract class MediaPlaybackBaseService extends Service { - // True when the start command has been forwarded to the impl. - boolean mStarted; - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public void onCreate() { - super.onCreate(); - - if (!WebLayer.hasWebLayerInitializationStarted()) { - stopSelf(); - return; - } - - init(); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - WebLayer webLayer = getWebLayer(); - if (webLayer == null) { - stopSelf(); - } else { - try { - forwardStartCommandToImpl(webLayer, intent); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - mStarted = true; - } - - return START_NOT_STICKY; - } - - @Override - public void onDestroy() { - super.onDestroy(); - - if (!mStarted) return; - - try { - forwardDestroyToImpl(); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Called to do initialization when the service is created. */ - void init() {} - - /** - * Called to forward {@link onStartCommand()} to the WebLayer implementation. - * - * @param webLayer the implementation. - * @param intent the intent that started the service. - */ - abstract void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent) - throws RemoteException; - - /** - * Called to forward {@link onDestroy()} to the WebLayer implementation. - * - * This will only be called if {@link forwardStartCommandToImpl()} was previously called, and - * there should always be a loaded {@link WebLayer} available via {@link getWebLayer()}. - */ - abstract void forwardDestroyToImpl() throws RemoteException; - - /** Returns the loaded {@link WebLayer}, or null if none is loaded. */ - @Nullable - WebLayer getWebLayer() { - WebLayer webLayer; - try { - webLayer = WebLayer.getLoadedWebLayer(getApplication()); - } catch (UnsupportedVersionException e) { - throw new RuntimeException(e); - } - return webLayer; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragmentEventHandler.java b/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragmentEventHandler.java deleted file mode 100644 index 75ee7d8b..0000000 --- a/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragmentEventHandler.java +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * This class handles dialog fragments for casting, such as a {@link - * MediaRouteChooserDialogFragment} or a {@link MediaRouteControllerDialogFragment}. - * - * TODO(rayankans): Expose MediaRouteDialog to the client side. - */ -class MediaRouteDialogFragmentEventHandler extends RemoteFragmentEventHandler { - MediaRouteDialogFragmentEventHandler() { - super(null /* args */); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java b/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java deleted file mode 100644 index 3749d73..0000000 --- a/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.media.AudioManager; -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import org.chromium.base.ContextUtils; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * A foreground {@link Service} for the Web MediaSession API. - * This class is a thin wrapper that forwards lifecycle events to the WebLayer implementation, which - * in turn manages a system notification and {@link MediaSession}. This service will be in the - * foreground when the MediaSession is active. - */ -public class MediaSessionService extends MediaPlaybackBaseService { - // A helper to automatically pause the media session when a user removes headphones. - private BroadcastReceiver mAudioBecomingNoisyReceiver; - - @Override - public void onDestroy() { - super.onDestroy(); - if (mAudioBecomingNoisyReceiver != null) { - unregisterReceiver(mAudioBecomingNoisyReceiver); - } - } - - @Override - void init() { - mAudioBecomingNoisyReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (!AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) { - return; - } - - Intent i = new Intent(getApplication(), MediaSessionService.class); - i.setAction(intent.getAction()); - getApplication().startService(i); - } - }; - - IntentFilter filter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY); - ContextUtils.registerProtectedBroadcastReceiver(this, mAudioBecomingNoisyReceiver, filter); - } - - @Override - void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent) - throws RemoteException { - webLayer.getImpl().onMediaSessionServiceStarted(ObjectWrapper.wrap(this), intent); - } - - @Override - void forwardDestroyToImpl() throws RemoteException { - getWebLayer().getImpl().onMediaSessionServiceDestroyed(); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/NavigateParams.java b/weblayer/public/java/org/chromium/weblayer/NavigateParams.java deleted file mode 100644 index 34011d84..0000000 --- a/weblayer/public/java/org/chromium/weblayer/NavigateParams.java +++ /dev/null
@@ -1,184 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.webkit.WebResourceResponse; - -import androidx.annotation.NonNull; - -/** - * Parameters for {@link NavigationController#navigate}. - */ -class NavigateParams { - private boolean mShouldReplaceCurrentEntry; - private boolean mIntentProcessingDisabled; - private boolean mIntentLaunchesAllowedInBackground; - private boolean mNetworkErrorAutoReloadDisabled; - private boolean mAutoPlayEnabled; - private WebResourceResponse mResponse; - - /** - * A Builder class to help create NavigateParams. - */ - public static final class Builder { - private NavigateParams mParams; - - /** - * Constructs a new Builder. - */ - public Builder() { - mParams = new NavigateParams(); - } - - /** - * Builds the NavigateParams. - */ - @NonNull - public NavigateParams build() { - return mParams; - } - - /** - * @param replace Indicates whether the navigation should replace the current navigation - * entry in the history stack. False by default. - */ - @NonNull - public Builder setShouldReplaceCurrentEntry(boolean replace) { - mParams.mShouldReplaceCurrentEntry = replace; - return this; - } - - /** - * Disables lookup and launching of an Intent that matches the uri being navigated to. If - * this is not called, WebLayer may look for a matching intent-filter, and if one is found, - * create and launch an Intent. The exact heuristics of when Intent matching is performed - * depends upon a wide range of state (such as the uri being navigated to, navigation - * stack...). - */ - @NonNull - public Builder disableIntentProcessing() { - mParams.mIntentProcessingDisabled = true; - return this; - } - - /** - * Enables intent launching to occur for this navigation even if it is being executed in a - * background (i.e., non-visible) tab (by default, intent launches are disallowed in - * background tabs). - * - * @since 89 - */ - @NonNull - public Builder allowIntentLaunchesInBackground() { - if (WebLayer.shouldPerformVersionChecks() - && WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - - mParams.mIntentLaunchesAllowedInBackground = true; - return this; - } - - /** - * Disables auto-reload for this navigation if the network is down and comes back later. - * Auto-reload is enabled by default. This is deprecated as of 88, instead use - * {@link Navigation#disableNetworkErrorAutoReload} which works for both embedder-initiated - * navigations and also user-initiated navigations (such as back or forward). Auto-reload - * is disabled if either method is called. - */ - @NonNull - public Builder disableNetworkErrorAutoReload() { - mParams.mNetworkErrorAutoReloadDisabled = true; - return this; - } - - /** - * Enable auto-play for videos in this navigation. Auto-play is disabled by default. - */ - @NonNull - public Builder enableAutoPlay() { - mParams.mAutoPlayEnabled = true; - return this; - } - - /** - * @param response If the embedder has already fetched the data for a navigation it can - * supply it via a WebResourceResponse. The navigation will be committed at the - * Uri given to NavigationController.navigate(). - * Caveats: - * -ensure proper cache headers are set if you don't want it to be reloaded. - * Depending on the device available memory a back navigation might hit - * the network if the headers don't indicate it's cacheable and the - * page wasn't in the back-forward cache. An example to cache for 1 minute: - * Cache-Control: private, max-age=60 - * -since this isn't fetched by WebLayer it won't have the necessary certificate - * information to show the security padlock or certificate data. - */ - @NonNull - public Builder setResponse(@NonNull WebResourceResponse response) { - mParams.mResponse = response; - return this; - } - } - - /** - * Returns true if the current navigation will be replaced, false otherwise. - */ - public boolean getShouldReplaceCurrentEntry() { - return mShouldReplaceCurrentEntry; - } - - /** - * Returns true if intent processing is disabled. - * - * @return Whether intent processing is disabled. - */ - public boolean isIntentProcessingDisabled() { - return mIntentProcessingDisabled; - } - - /** - * Returns true if intent launches are allowed in the background. - * - * @return Whether intent launches are allowed in the background. - * - * @since 89 - */ - public boolean areIntentLaunchesAllowedInBackground() { - if (WebLayer.shouldPerformVersionChecks() - && WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - - return mIntentLaunchesAllowedInBackground; - } - - /** - * Returns true if auto reload for network errors is disabled. - * - * @return Whether auto reload for network errors is disabled. - */ - public boolean isNetworkErrorAutoReloadDisabled() { - return mNetworkErrorAutoReloadDisabled; - } - - /** - * Returns true if auto play for videos is enabled. - * - * @return Whether auto play for videos is enabled. - */ - public boolean isAutoPlayEnabled() { - return mAutoPlayEnabled; - } - - /** - * Returns a response of the html to use. - * - * @return WebResourceResponse of html to use. - */ - public WebResourceResponse getResponse() { - return mResponse; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/Navigation.java b/weblayer/public/java/org/chromium/weblayer/Navigation.java deleted file mode 100644 index 57114dd..0000000 --- a/weblayer/public/java/org/chromium/weblayer/Navigation.java +++ /dev/null
@@ -1,514 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IClientNavigation; -import org.chromium.weblayer_private.interfaces.INavigation; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Information about a navigation. Each time there is a new navigation, a new - * Navigation object will be created and that same object will be used in all - * of the NavigationCallback methods. - */ -class Navigation extends IClientNavigation.Stub { - private final INavigation mNavigationImpl; - - // Constructor for test mocking. - protected Navigation() { - mNavigationImpl = null; - } - - Navigation(INavigation impl) { - mNavigationImpl = impl; - } - - @NavigationState - public int getState() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.getState(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * The uri the main frame is navigating to. This may change during the navigation when - * encountering a server redirect. - */ - @NonNull - public Uri getUri() { - ThreadCheck.ensureOnUiThread(); - try { - return Uri.parse(mNavigationImpl.getUri()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the redirects that occurred on the way to the current page. The current page is the - * last one in the list (so even when there's no redirect, there will be one entry in the list). - */ - @NonNull - public List<Uri> getRedirectChain() { - ThreadCheck.ensureOnUiThread(); - try { - List<Uri> redirects = new ArrayList<Uri>(); - for (String r : mNavigationImpl.getRedirectChain()) redirects.add(Uri.parse(r)); - return redirects; - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the status code of the navigation. Returns 0 if the navigation hasn't completed yet - * or if a response wasn't received. - */ - public int getHttpStatusCode() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.getHttpStatusCode(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /* - * Returns the HTTP response headers. Returns an empty map if the navigation hasn't completed - * yet or if a response wasn't received. - * - * @since 91 - */ - public Map<String, String> getResponseHeaders() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 91) { - throw new UnsupportedOperationException(); - } - try { - Map<String, String> headers = new HashMap<String, String>(); - List<String> array = mNavigationImpl.getResponseHeaders(); - for (int i = 0; i < array.size(); i += 2) { - headers.put(array.get(i), array.get(i + 1)); - } - - return headers; - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether the navigation happened without changing document. Examples of same document - * navigations are: - * - reference fragment navigations - * - pushState/replaceState - * - same page history navigation - */ - public boolean isSameDocument() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.isSameDocument(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether the navigation resulted in an error page (e.g. interstitial). Note that if an error - * page reloads, this will return true even though GetNetErrorCode will be kNoError. - */ - public boolean isErrorPage() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.isErrorPage(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Return information about the error, if any, that was encountered while loading the page. - */ - @LoadError - public int getLoadError() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.getLoadError(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether this navigation resulted in a download. Returns false if this navigation did not - * result in a download, or if download status is not yet known for this navigation. Download - * status is determined for a navigation when processing final (post redirect) HTTP response - * headers. This means the only time the embedder can know if it's a download is in - * NavigationCallback.onNavigationFailed. - */ - public boolean isDownload() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.isDownload(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether the target URL can be handled by the browser's internal protocol handlers, i.e., has - * a scheme that the browser knows how to process internally. Examples of such URLs are - * http(s) URLs, data URLs, and file URLs. A typical example of a URL for which there is no - * internal protocol handler (and for which this method would return also) is an intent:// URL. - * - * @return Whether the target URL of the navigation has a known protocol. - * - * @since 89 - */ - public boolean isKnownProtocol() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - try { - return mNavigationImpl.isKnownProtocol(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether this navigation resulted in an external intent being launched. Returns false if this - * navigation did not do so, or if that status is not yet known for this navigation. This - * status is determined for a navigation when processing final (post redirect) HTTP response - * headers. This means the only time the embedder can know if the navigation resulted in an - * external intent being launched is in NavigationCallback.onNavigationFailed. - * - * @return Whether an intent was launched for the navigation. - * - * @since 89 - */ - public boolean wasIntentLaunched() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - try { - return mNavigationImpl.wasIntentLaunched(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether this navigation resulted in the user deciding whether an external intent should be - * launched (e.g., via a dialog). Returns false if this navigation did not resolve to such a - * user decision, or if that status is not yet known for this navigation. This status is - * determined for a navigation when processing final (post redirect) HTTP response headers. This - * means the only time the embedder can know this status definitively is in - * NavigationCallback.onNavigationFailed. - * - * @return Whether this navigation resulted in a user decision guarding external intent launch. - * - * @since 89 - */ - public boolean isUserDecidingIntentLaunch() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - try { - return mNavigationImpl.isUserDecidingIntentLaunch(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether this navigation was stopped before it could complete because - * NavigationController.stop() was called. - */ - public boolean wasStopCalled() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.wasStopCalled(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Sets a header for a network request. If a header with the specified name exists it is - * overwritten. This method can only be called at two times, from - * {@link NavigationCallback.onNavigationStarted} and {@link - * NavigationCallback.onNavigationRedirected}. When called during start, the header applies to - * both the initial network request as well as redirects. - * - * This method may be used to set the referer. If the referer is set in navigation start, it is - * reset during the redirect. In other words, if you need to set a referer that applies to - * redirects, then this must be called from {@link onNavigationRedirected}. - * - * Note that any headers that are set here won't be sent again if the frame html is fetched - * again due to a user reloading the page, navigating back and forth etc... when this fetch - * couldn't be cached (either in the disk cache or in the back-forward cache). - * - * @param name The name of the header. The name must be rfc 2616 compliant. - * @param value The value of the header. The value must not contain '\0', '\n' or '\r'. - * - * @throws IllegalArgumentException If supplied invalid values. - * @throws IllegalStateException If not called during start or a redirect. - */ - public void setRequestHeader(@NonNull String name, @NonNull String value) { - ThreadCheck.ensureOnUiThread(); - try { - mNavigationImpl.setRequestHeader(name, value); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Disables auto-reload for this navigation if the network is down and comes back later. - * Auto-reload is enabled by default. This method may only be called from - * {@link NavigationCallback.onNavigationStarted}. - * - * @throws IllegalStateException If not called during start. - * - * @since 88 - */ - public void disableNetworkErrorAutoReload() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.shouldPerformVersionChecks() - && WebLayer.getSupportedMajorVersionInternal() < 88) { - throw new UnsupportedOperationException(); - } - try { - mNavigationImpl.disableNetworkErrorAutoReload(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Disables intent processing for the lifetime of this navigation (including following - * redirects). This method may only be called from - * {@link NavigationCallback.onNavigationStarted}. - * - * @throws IllegalStateException If not called during start. - * - * @since 97 - */ - public void disableIntentProcessing() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.shouldPerformVersionChecks() - && WebLayer.getSupportedMajorVersionInternal() < 97) { - throw new UnsupportedOperationException(); - } - try { - mNavigationImpl.disableIntentProcessing(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Sets the user-agent string that applies to the current navigation. This user-agent is not - * sticky, it applies to this navigation only (and any redirects or resources that are loaded). - * This method may only be called from {@link NavigationCallback.onNavigationStarted}. Setting - * this to a non empty string will cause will cause the User-Agent Client Hint header values and - * the values returned by `navigator.userAgentData` to be empty for requests this override is - * applied to. - * - * Note that this user agent won't be sent again if the frame html is fetched again due to a - * user reloading the page, navigating back and forth etc... when this fetch couldn't be cached - * (either in the disk cache or in the back-forward cache). - * - * @param value The user-agent string. The value must not contain '\0', '\n' or '\r'. An empty - * string results in the default user-agent string. - * - * @throws IllegalArgumentException If supplied an invalid value. - * @throws IllegalStateException If not called during start or if {@link - * Tab.setDesktopUserAgent} was called with a value of true. - */ - public void setUserAgentString(@NonNull String value) { - ThreadCheck.ensureOnUiThread(); - try { - mNavigationImpl.setUserAgentString(value); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns whether the navigation was initiated by the page. Examples of page-initiated - * navigations: - * * Clicking <a> links. - * * changing window.location.href - * * redirect via the <meta http-equiv="refresh"> tag - * * using window.history.pushState - * * window.history.forward() or window.history.back() - * - * This method returns false for navigations initiated by the WebLayer API. - * - * @return Whether the navigation was initiated by the page. - */ - public boolean isPageInitiated() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.isPageInitiated(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether the navigation is a reload. Examples of reloads include: - * * embedder-specified through NavigationController::Reload - * * page-initiated reloads, e.g. location.reload() - * * reloads when the network interface is reconnected - */ - public boolean isReload() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationImpl.isReload(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Whether the navigation is restoring a page from back-forward cache (see - * https://web.dev/bfcache/). Since a previously loaded page is being reused, there are some - * things embedders have to keep in mind such as: - * * there will be no NavigationObserver::onFirstContentfulPaint callbacks - * * if an embedder injects code using Tab::ExecuteScript there is no need to reinject scripts - * - * @since 89 - */ - public boolean isServedFromBackForwardCache() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - try { - return mNavigationImpl.isServedFromBackForwardCache(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns true if this navigation was initiated by a form submission. - * - * @since 89 - */ - public boolean isFormSubmission() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89 - || WebLayer.getVersion().equals("89.0.4389.69") - || WebLayer.getVersion().equals("89.0.4389.72")) { - throw new UnsupportedOperationException(); - } - try { - return mNavigationImpl.isFormSubmission(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the referrer for this request. - * - * @since 89 - */ - @NonNull - public Uri getReferrer() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89 - || WebLayer.getVersion().equals("89.0.4389.69") - || WebLayer.getVersion().equals("89.0.4389.72")) { - throw new UnsupportedOperationException(); - } - try { - return Uri.parse(mNavigationImpl.getReferrer()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the Page object this navigation is occurring for. - * This method may only be called in (1) {@link NavigationCallback.onNavigationCompleted} or - * (2) {@link NavigationCallback.onNavigationFailed} when {@link Navigation#isErrorPage} - * returns true. It will return a non-null object in these cases. - * - * @throws IllegalStateException if called outside the above circumstances. - * - * @since 90 - */ - @NonNull - public Page getPage() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 90) { - throw new UnsupportedOperationException(); - } - try { - return (Page) mNavigationImpl.getPage(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the offset between the indices of the previous last committed and the newly committed - * navigation entries, for example -1 for back navigations, 0 for reloads, 1 for forward - * navigations or new navigations. Note that the return value can be less than -1 or greater - * than 1 if the navigation goes back/forward multiple entries. This may not cover all corner - * cases, and can be incorrect in cases like main frame client redirects. - * - * @since 92 - */ - public int getNavigationEntryOffset() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 92) { - throw new UnsupportedOperationException(); - } - try { - return mNavigationImpl.getNavigationEntryOffset(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns true if the navigation response was fetched from the cache. - * - * @since 102 - */ - public boolean wasFetchedFromCache() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 102) { - throw new UnsupportedOperationException(); - } - try { - return mNavigationImpl.wasFetchedFromCache(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java b/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java deleted file mode 100644 index ec120282..0000000 --- a/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java +++ /dev/null
@@ -1,153 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; - -import androidx.annotation.NonNull; - -/** - * Informed of interesting events that happen during the lifetime of NavigationController. This - * interface is only notified of main frame navigations. - * - * The lifecycle of a navigation: - * 1) navigationStarted() - * 2) 0 or more navigationRedirected() - * 3) navigationCompleted() or navigationFailed() - * 4) onFirstContentfulPaint(). - */ -abstract class NavigationCallback { - /** - * Called when a navigation started in the Tab. |navigation| is unique to a - * specific navigation. The same |navigation| will be provided on subsequent calls to - * NavigationRedirected, NavigationCommitted, NavigationCompleted and NavigationFailed when - * related to this navigation. Observers should clear any references to |navigation| in - * NavigationCompleted or NavigationFailed, just before it is destroyed. - * - * Note that this is only fired by navigations in the main frame. - * - * Note that this is fired by same-document navigations, such as fragment navigations or - * pushState/replaceState, which will not result in a document change. To filter these out, use - * Navigation::IsSameDocument. - * - * Note that more than one navigation can be ongoing in the Tab at the same time. - * Each will get its own Navigation object. - * - * Note that there is no guarantee that NavigationCompleted/NavigationFailed will be called for - * any particular navigation before NavigationStarted is called on the next. - * - * @param navigation the unique object for this navigation. - */ - public void onNavigationStarted(@NonNull Navigation navigation) {} - - /** - * Called when a navigation encountered a server redirect. - * - * @param navigation the unique object for this navigation. - */ - public void onNavigationRedirected(@NonNull Navigation navigation) {} - - /** - * Called when a navigation completes successfully in the Tab. - * - * The document load will still be ongoing in the Tab. Use the document loads - * events such as onFirstContentfulPaint and related methods to listen for continued events from - * this Tab. - * - * Note that this is fired by same-document navigations, such as fragment navigations or - * pushState/replaceState, which will not result in a document change. To filter these out, use - * NavigationHandle::IsSameDocument. - * - * Note that |navigation| will be destroyed at the end of this call, so do not keep a reference - * to it afterward. - * - * @param navigation the unique object for this navigation. - */ - public void onNavigationCompleted(@NonNull Navigation navigation) {} - - /** - * Called when a navigation aborts in the Tab. - * - * Note that |navigation| will be destroyed at the end of this call, so do not keep a reference - * to it afterward. - * - * @param navigation the unique object for this navigation. - */ - public void onNavigationFailed(@NonNull Navigation navigation) {} - - /** - * The load state of the document has changed. - * - * @param isLoading Whether any resource is loading. - * @param shouldShowLoadingUi True if the navigation is expected to show navigation-in-progress - * UI (if any exists). Only valid when |isLoading| is true. - */ - public void onLoadStateChanged(boolean isLoading, boolean shouldShowLoadingUi) {} - - /** - * The progress of loading the main frame in the document has changed. - * - * @param progress A value in the range of 0.0-1.0. - */ - public void onLoadProgressChanged(double progress) {} - - /** - * This is fired after each navigation has completed to indicate that the first paint after a - * non-empty layout has finished. This is *not* called for same-document navigations or when the - * page is loaded from the back-forward cache; see {@link - * Navigation#isServedFromBackForwardCache}. - */ - public void onFirstContentfulPaint() {} - - /** - * Similar to onFirstContentfulPaint but contains timing information from the renderer process - * to better align with the Navigation Timing API. - * - * @param navigationStartMs the absolute navigation start time in milliseconds since boot, - * not counting time spent in deep sleep. This comes from SystemClock.uptimeMillis(). - * @param firstContentfulPaintDurationMs the number of milliseconds to first contentful paint - * from navigation start. - * @since 88 - */ - public void onFirstContentfulPaint( - long navigationStartMs, long firstContentfulPaintDurationMs) {} - - /** - * This is fired when the largest contentful paint metric is available. - * - * @param navigationStartMs the absolute navigation start time in milliseconds since boot, - * not counting time spent in deep sleep. This comes from SystemClock.uptimeMillis(). - * @param largestContentfulPaintDurationMs the number of milliseconds to largest contentful - * paint - * from navigation start. - * @since 88 - */ - public void onLargestContentfulPaint( - long navigationStartMs, long largestContentfulPaintDurationMs) {} - - /** - * Called after each navigation to indicate that the old page is no longer - * being rendered. Note this is not ordered with respect to onFirstContentfulPaint. - * @param newNavigationUri Uri of the new navigation. - */ - public void onOldPageNoLongerRendered(@NonNull Uri newNavigationUri) {} - - /* Called when a Page is destroyed. For the common case, this is called when the user navigates - * away from a page to a new one or when the Tab is destroyed. However there are situations when - * a page is alive when it's not visible, e.g. when it goes into the back-forward cache. In that - * case this method will either be called when the back-forward cache entry is evicted or if it - * is used then this cycle repeats. - * @since 90 - */ - public void onPageDestroyed(@NonNull Page page) {} - - /* - * Called when the source language for |page| has been determined to be |language|. - * Note: |language| is an ISO 639 language code (two letters, except for Chinese where a - * localization is necessary). - * @since 93 - */ - public void onPageLanguageDetermined(@NonNull Page page, @NonNull String language) {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/NavigationController.java b/weblayer/public/java/org/chromium/weblayer/NavigationController.java deleted file mode 100644 index 1665a8a..0000000 --- a/weblayer/public/java/org/chromium/weblayer/NavigationController.java +++ /dev/null
@@ -1,406 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IClientNavigation; -import org.chromium.weblayer_private.interfaces.IClientPage; -import org.chromium.weblayer_private.interfaces.INavigateParams; -import org.chromium.weblayer_private.interfaces.INavigation; -import org.chromium.weblayer_private.interfaces.INavigationController; -import org.chromium.weblayer_private.interfaces.INavigationControllerClient; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -/** - * Provides methods to control navigation, along with maintaining the current list of navigations. - */ -class NavigationController { - private INavigationController mNavigationController; - private final ObserverList<NavigationCallback> mCallbacks; - - static NavigationController create(ITab tab) { - NavigationController navigationController = new NavigationController(); - try { - navigationController.mNavigationController = tab.createNavigationController( - navigationController.new NavigationControllerClientImpl()); - } catch (RemoteException e) { - throw new APICallException(e); - } - return navigationController; - } - - // Constructor protected for test mocking. - protected NavigationController() { - mCallbacks = new ObserverList<NavigationCallback>(); - } - - public void navigate(@NonNull Uri uri) { - navigate(uri, null); - } - - /** - * Navigates to the given URI, with optional settings. - * - * @param uri the destination URI. - * @param params extra parameters for the navigation. - * - */ - public void navigate(@NonNull Uri uri, @Nullable NavigateParams params) { - ThreadCheck.ensureOnUiThread(); - try { - INavigateParams iparams = mNavigationController.createNavigateParams(); - if (params != null) { - if (params.getShouldReplaceCurrentEntry()) iparams.replaceCurrentEntry(); - if (params.isIntentProcessingDisabled()) iparams.disableIntentProcessing(); - if (WebLayer.getSupportedMajorVersionInternal() >= 89 - && params.areIntentLaunchesAllowedInBackground()) { - iparams.allowIntentLaunchesInBackground(); - } - if (params.isNetworkErrorAutoReloadDisabled()) { - iparams.disableNetworkErrorAutoReload(); - } - if (params.isAutoPlayEnabled()) iparams.enableAutoPlay(); - if (params.getResponse() != null) { - iparams.setResponse(ObjectWrapper.wrap(params.getResponse())); - } - } - mNavigationController.navigate3(uri.toString(), iparams); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Navigates to the previous navigation. - * - * Note: this may go back more than a single navigation entry, see {@link - * isNavigationEntrySkippable} for more details. - * - * @throws IndexOutOfBoundsException If {@link #canGoBack} returns false. - */ - public void goBack() throws IndexOutOfBoundsException { - ThreadCheck.ensureOnUiThread(); - if (!canGoBack()) { - throw new IndexOutOfBoundsException(); - } - try { - mNavigationController.goBack(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Navigates to the next navigation. - * - * @throws IndexOutOfBoundsException If {@link #canGoForward} returns false. - */ - public void goForward() throws IndexOutOfBoundsException { - ThreadCheck.ensureOnUiThread(); - if (!canGoForward()) { - throw new IndexOutOfBoundsException(); - } - try { - mNavigationController.goForward(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns true if there is a navigation before the current one. - * - * Note: this may return false even if the current index is not 0, see {@link - * isNavigationEntrySkippable} for more details. - * - * @return Whether there is a navigation before the current one. - */ - public boolean canGoBack() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationController.canGoBack(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns true if there is a navigation after the current one. - * - * @return Whether there is a navigation after the current one. - */ - public boolean canGoForward() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationController.canGoForward(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Navigates to the entry at {@link index}. - * - * @throws IndexOutOfBoundsException If index is negative or is not less than {@link - * getNavigationListSize}. - */ - public void goToIndex(int index) throws IndexOutOfBoundsException { - ThreadCheck.ensureOnUiThread(); - checkNavigationIndex(index); - try { - mNavigationController.goToIndex(index); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Reloads the current entry. Does nothing if there are no navigations. - */ - public void reload() { - ThreadCheck.ensureOnUiThread(); - try { - mNavigationController.reload(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Stops in progress loading. Does nothing if not in the process of loading. - */ - public void stop() { - ThreadCheck.ensureOnUiThread(); - try { - mNavigationController.stop(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the number of navigations entries. - * - * @return The number of navigation entries, 0 if empty. - */ - public int getNavigationListSize() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationController.getNavigationListSize(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the index of the current navigation, -1 if there are no navigations. - * - * @return The index of the current navigation. - */ - public int getNavigationListCurrentIndex() { - ThreadCheck.ensureOnUiThread(); - try { - return mNavigationController.getNavigationListCurrentIndex(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the uri to display for the navigation at index. - * - * @param index The index of the navigation. - * @throws IndexOutOfBoundsException If index is negative or is not less than {@link - * getNavigationListSize}. - */ - @NonNull - public Uri getNavigationEntryDisplayUri(int index) throws IndexOutOfBoundsException { - ThreadCheck.ensureOnUiThread(); - checkNavigationIndex(index); - try { - return Uri.parse(mNavigationController.getNavigationEntryDisplayUri(index)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the title of the navigation entry at the supplied index. - * - * @throws IndexOutOfBoundsException If index is negative or is not less than {@link - * getNavigationListSize}. - */ - @NonNull - public String getNavigationEntryTitle(int index) throws IndexOutOfBoundsException { - ThreadCheck.ensureOnUiThread(); - checkNavigationIndex(index); - try { - return mNavigationController.getNavigationEntryTitle(index); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns whether this entry will be skipped on a call to {@link goBack} or {@link goForward}. - * This will be true for certain navigations, such as certain client side redirects and - * history.pushState navigations done without user interaction. - * - * @throws IndexOutOfBoundsException If index is negative or is not less than {@link - * getNavigationListSize}. - */ - public boolean isNavigationEntrySkippable(int index) throws IndexOutOfBoundsException { - ThreadCheck.ensureOnUiThread(); - checkNavigationIndex(index); - try { - return mNavigationController.isNavigationEntrySkippable(index); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public void registerNavigationCallback(@NonNull NavigationCallback callback) { - ThreadCheck.ensureOnUiThread(); - mCallbacks.addObserver(callback); - } - - public void unregisterNavigationCallback(@NonNull NavigationCallback callback) { - ThreadCheck.ensureOnUiThread(); - mCallbacks.removeObserver(callback); - } - - private void checkNavigationIndex(int index) throws IndexOutOfBoundsException { - if (index < 0 || index >= getNavigationListSize()) { - throw new IndexOutOfBoundsException(); - } - } - - private final class NavigationControllerClientImpl extends INavigationControllerClient.Stub { - @Override - public IClientNavigation createClientNavigation(INavigation navigationImpl) { - StrictModeWorkaround.apply(); - return new Navigation(navigationImpl); - } - - @Override - public void navigationStarted(IClientNavigation navigation) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onNavigationStarted((Navigation) navigation); - } - } - - @Override - public void navigationRedirected(IClientNavigation navigation) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onNavigationRedirected((Navigation) navigation); - } - } - - @Override - public void readyToCommitNavigation(IClientNavigation navigation) { - StrictModeWorkaround.apply(); - // Functionality removed from NavigationCallback in M90. See crbug.com/1174193 - } - - @Override - public void navigationCompleted(IClientNavigation navigation) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onNavigationCompleted((Navigation) navigation); - } - } - - @Override - public void navigationFailed(IClientNavigation navigation) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onNavigationFailed((Navigation) navigation); - } - } - - @Override - public void loadStateChanged(boolean isLoading, boolean shouldShowLoadingUi) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onLoadStateChanged(isLoading, shouldShowLoadingUi); - } - } - - @Override - public void loadProgressChanged(double progress) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onLoadProgressChanged(progress); - } - } - - @Override - public void onFirstContentfulPaint() { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onFirstContentfulPaint(); - } - } - - @Override - public void onFirstContentfulPaint2( - long navigationStartMs, long firstContentfulPaintDurationMs) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onFirstContentfulPaint(navigationStartMs, firstContentfulPaintDurationMs); - } - } - - @Override - public void onLargestContentfulPaint( - long navigationStartMs, long largestContentfulPaintDurationMs) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onLargestContentfulPaint( - navigationStartMs, largestContentfulPaintDurationMs); - } - } - - @Override - public void onOldPageNoLongerRendered(String uri) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onOldPageNoLongerRendered(Uri.parse(uri)); - } - } - - @Override - public IClientPage createClientPage() { - StrictModeWorkaround.apply(); - return new Page(); - } - - @Override - public void onPageDestroyed(IClientPage page) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onPageDestroyed((Page) page); - } - } - - @Override - public void onPageLanguageDetermined(IClientPage page, String language) { - StrictModeWorkaround.apply(); - for (NavigationCallback callback : mCallbacks) { - callback.onPageLanguageDetermined((Page) page, language); - } - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/NavigationState.java b/weblayer/public/java/org/chromium/weblayer/NavigationState.java deleted file mode 100644 index 689a20c..0000000 --- a/weblayer/public/java/org/chromium/weblayer/NavigationState.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({NavigationState.WAITING_RESPONSE, NavigationState.RECEIVING_BYTES, - NavigationState.COMPLETE, NavigationState.FAILED}) -@Retention(RetentionPolicy.SOURCE) -@interface NavigationState { - int WAITING_RESPONSE = - org.chromium.weblayer_private.interfaces.NavigationState.WAITING_RESPONSE; - int RECEIVING_BYTES = org.chromium.weblayer_private.interfaces.NavigationState.RECEIVING_BYTES; - int COMPLETE = org.chromium.weblayer_private.interfaces.NavigationState.COMPLETE; - int FAILED = org.chromium.weblayer_private.interfaces.NavigationState.FAILED; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/NewTabCallback.java b/weblayer/public/java/org/chromium/weblayer/NewTabCallback.java deleted file mode 100644 index f8b2cde..0000000 --- a/weblayer/public/java/org/chromium/weblayer/NewTabCallback.java +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -/** - * Used for handling new tabs (such as occurs when window.open() is called). If this is not - * set, popups are disabled. - */ -abstract class NewTabCallback { - /** - * Called when a new tab has been created. - * - * @param tab The new tab. - * @param type How the tab should be shown. - */ - public abstract void onNewTab(@NonNull Tab tab, @NewTabType int type); - - /** - * Called when a tab previously opened via onNewTab() was asked to close. Generally this should - * destroy the Tab and/or Browser. - * NOTE: This callback was deprecated in 84; WebLayer now internally closes tabs in this case - * and the embedder will be notified via TabListCallback#onTabRemoved(). - * - * @see Browser#destroyTab - */ - @Deprecated - public void onCloseTab() {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/NewTabType.java b/weblayer/public/java/org/chromium/weblayer/NewTabType.java deleted file mode 100644 index 709ef1c..0000000 --- a/weblayer/public/java/org/chromium/weblayer/NewTabType.java +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({NewTabType.FOREGROUND_TAB, NewTabType.BACKGROUND_TAB, NewTabType.NEW_POPUP, - NewTabType.NEW_WINDOW}) -@Retention(RetentionPolicy.SOURCE) -@interface NewTabType { - /** - * The page requested a new tab to be shown active. - */ - int FOREGROUND_TAB = org.chromium.weblayer_private.interfaces.NewTabType.FOREGROUND_TAB; - - /** - * The page requested a new tab in the background. Generally, this is only encountered when - * keyboard modifiers are used. - */ - int BACKGROUND_TAB = org.chromium.weblayer_private.interfaces.NewTabType.BACKGROUND_TAB; - /** - * The page requested the tab to open a new popup. A popup generally shows minimal ui - * affordances, such as no tabstrip. On a phone, this is generally the same as - * NEW_TAB_MODE_FOREGROUND_TAB. - */ - int NEW_POPUP = org.chromium.weblayer_private.interfaces.NewTabType.NEW_POPUP; - - /** - * The page requested the tab to open in a new window. On a phone, this is generally the - * same as NEW_TAB_MODE_FOREGROUND_TAB. - */ - int NEW_WINDOW = org.chromium.weblayer_private.interfaces.NewTabType.NEW_WINDOW; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ObserverList.java b/weblayer/public/java/org/chromium/weblayer/ObserverList.java deleted file mode 100644 index 09bc8aa..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ObserverList.java +++ /dev/null
@@ -1,246 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -/** - * A container for a list of observers. - * <p/> - * This container can be modified during iteration without invalidating the iterator. - * So, it safely handles the case of an observer removing itself or other observers from the list - * while observers are being notified. - * <p/> - * The implementation (and the interface) is heavily influenced by the C++ ObserverList. - * Notable differences: - * - The iterator implements NOTIFY_EXISTING_ONLY. - * - The range-based for loop is left to the clients to implement in terms of iterator(). - * <p/> - * This class is not threadsafe. Observers MUST be added, removed and will be notified on the same - * thread this is created. - * - * @param <E> The type of observers that this list should hold. - */ -class ObserverList<E> implements Iterable<E> { - /** - * Extended iterator interface that provides rewind functionality. - */ - public interface RewindableIterator<E> extends Iterator<E> { - /** - * Rewind the iterator back to the beginning. - * - * If we need to iterate multiple times, we can avoid iterator object reallocation by using - * this method. - */ - public void rewind(); - } - - public final List<E> mObservers = new ArrayList<E>(); - private int mIterationDepth; - private int mCount; - private boolean mNeedsCompact; - - public ObserverList() {} - - /** - * Add an observer to the list. - * <p/> - * An observer should not be added to the same list more than once. If an iteration is already - * in progress, this observer will be not be visible during that iteration. - * - * @return true if the observer list changed as a result of the call. - */ - public boolean addObserver(E obs) { - // Avoid adding null elements to the list as they may be removed on a compaction. - if (obs == null || mObservers.contains(obs)) { - return false; - } - - // Structurally modifying the underlying list here. This means we - // cannot use the underlying list's iterator to iterate over the list. - boolean result = mObservers.add(obs); - assert result; - - ++mCount; - return true; - } - - /** - * Remove an observer from the list if it is in the list. - * - * @return true if an element was removed as a result of this call. - */ - public boolean removeObserver(E obs) { - if (obs == null) { - return false; - } - - int index = mObservers.indexOf(obs); - if (index == -1) { - return false; - } - - if (mIterationDepth == 0) { - // No one is iterating over the list. - mObservers.remove(index); - } else { - mNeedsCompact = true; - mObservers.set(index, null); - } - --mCount; - assert mCount >= 0; - - return true; - } - - public boolean hasObserver(E obs) { - return mObservers.contains(obs); - } - - public void clear() { - mCount = 0; - - if (mIterationDepth == 0) { - mObservers.clear(); - return; - } - - int size = mObservers.size(); - mNeedsCompact |= size != 0; - for (int i = 0; i < size; i++) { - mObservers.set(i, null); - } - } - - @Override - public Iterator<E> iterator() { - return new ObserverListIterator(); - } - - /** - * It's the same as {@link ObserverList#iterator()} but the return type is - * {@link RewindableIterator}. Use this iterator type if you need to use - * {@link RewindableIterator#rewind()}. - */ - public RewindableIterator<E> rewindableIterator() { - return new ObserverListIterator(); - } - - /** - * Returns the number of observers currently registered in the ObserverList. - * This is equivalent to the number of non-empty spaces in |mObservers|. - */ - public int size() { - return mCount; - } - - /** - * Returns true if the ObserverList contains no observers. - */ - public boolean isEmpty() { - return mCount == 0; - } - - /** - * Compact the underlying list be removing null elements. - * <p/> - * Should only be called when mIterationDepth is zero. - */ - private void compact() { - assert mIterationDepth == 0; - for (int i = mObservers.size() - 1; i >= 0; i--) { - if (mObservers.get(i) == null) { - mObservers.remove(i); - } - } - } - - private void incrementIterationDepth() { - mIterationDepth++; - } - - private void decrementIterationDepthAndCompactIfNeeded() { - mIterationDepth--; - assert mIterationDepth >= 0; - if (mIterationDepth > 0) return; - if (!mNeedsCompact) return; - mNeedsCompact = false; - compact(); - } - - /** - * Returns the size of the underlying storage of the ObserverList. - * It will take into account the empty spaces inside |mObservers|. - */ - private int capacity() { - return mObservers.size(); - } - - private E getObserverAt(int index) { - return mObservers.get(index); - } - - private class ObserverListIterator implements RewindableIterator<E> { - private int mListEndMarker; - private int mIndex; - private boolean mIsExhausted; - - private ObserverListIterator() { - ObserverList.this.incrementIterationDepth(); - mListEndMarker = ObserverList.this.capacity(); - } - - @Override - public void rewind() { - compactListIfNeeded(); - ObserverList.this.incrementIterationDepth(); - mListEndMarker = ObserverList.this.capacity(); - mIsExhausted = false; - mIndex = 0; - } - - @Override - public boolean hasNext() { - int lookupIndex = mIndex; - while (lookupIndex < mListEndMarker - && ObserverList.this.getObserverAt(lookupIndex) == null) { - lookupIndex++; - } - if (lookupIndex < mListEndMarker) return true; - - // We have reached the end of the list, allow for compaction. - compactListIfNeeded(); - return false; - } - - @Override - public E next() { - // Advance if the current element is null. - while (mIndex < mListEndMarker && ObserverList.this.getObserverAt(mIndex) == null) { - mIndex++; - } - if (mIndex < mListEndMarker) return ObserverList.this.getObserverAt(mIndex++); - - // We have reached the end of the list, allow for compaction. - compactListIfNeeded(); - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - private void compactListIfNeeded() { - if (!mIsExhausted) { - mIsExhausted = true; - ObserverList.this.decrementIterationDepthAndCompactIfNeeded(); - } - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/OpenUrlCallback.java b/weblayer/public/java/org/chromium/weblayer/OpenUrlCallback.java deleted file mode 100644 index 5bd23c0..0000000 --- a/weblayer/public/java/org/chromium/weblayer/OpenUrlCallback.java +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Used for handling requests to open new tabs that are not associated with any existing tab. - * - * This will be used in cases where a service worker tries to open a document, e.g. via the Web API - * clients.openWindow. - * - * @since 91 - */ -abstract class OpenUrlCallback { - /** - * Called to get the {@link Browser} in which to create a new tab for a requested navigation. - * - * @return The {@link Browser} to host the new tab in, or null if the request should be - * rejected. - */ - public abstract @Nullable Browser getBrowserForNewTab(); - - /** - * Called when a new tab has been created and added to the browser given by {@link - * getBrowserForNewTab()}. - * - * It's expected this tab will be set to active. - * - * @param tab The new tab. - */ - public abstract void onTabAdded(@NonNull Tab tab); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/Page.java b/weblayer/public/java/org/chromium/weblayer/Page.java deleted file mode 100644 index 912cfff..0000000 --- a/weblayer/public/java/org/chromium/weblayer/Page.java +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import org.chromium.weblayer_private.interfaces.IClientPage; - -/** - * This objects tracks the lifetime of a loaded web page. Most of the time there is only one Page - * object per tab at a time. However features like back-forward cache, prerendering etc... sometime - * involve the creation of additional Page object. {@link Navigation.getPage} will return the Page - * for a given navigation. Similarly it'll the same Page object that's passed in - * {@link NavigationCallback.onPageDestroyed}. - * - * @since 90 - */ -class Page extends IClientPage.Stub {}
diff --git a/weblayer/public/java/org/chromium/weblayer/PaymentDetailsUpdateServiceWrapper.java b/weblayer/public/java/org/chromium/weblayer/PaymentDetailsUpdateServiceWrapper.java deleted file mode 100644 index 5361284..0000000 --- a/weblayer/public/java/org/chromium/weblayer/PaymentDetailsUpdateServiceWrapper.java +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; -import android.os.RemoteException; - -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IWebLayer; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * A client-side service that wraps the impl-side PaymentDetailsUpdateService. WebLayer embedders - * export this service via //weblayer/public/java/AndroidManifest.xml so external payment apps can - * notify WebLayer of any updates to the selected payment details. - * - * @since 92 - */ -public class PaymentDetailsUpdateServiceWrapper extends Service { - /** The impl-side of PaymentDetailsUpdateService. Can be null if WebLayer wasn't loaded yet. */ - @Nullable - private Service mService; - - @Override - public void onCreate() { - ThreadCheck.ensureOnUiThread(); - Service service = createService(); - if (service == null) { - stopSelf(); - return; - } - mService = service; - mService.onCreate(); - } - - @Nullable - private Service createService() { - if (WebLayer.getSupportedMajorVersionInternal() < 92) { - throw new UnsupportedOperationException(); - } - - // WebLayer started the calling app so we assume WebLayer is still running. This service is - // not supposed to be started when WebLayer isn't running so we can safely ignore requests - // in that case. - if (!WebLayer.hasWebLayerInitializationStarted()) return null; - WebLayer webLayer = WebLayer.getLoadedWebLayer(this); - if (webLayer == null) return null; - IWebLayer iWebLayer = webLayer.getImpl(); - if (iWebLayer == null) return null; - - IObjectWrapper objectWrapper; - try { - objectWrapper = iWebLayer.createPaymentDetailsUpdateService(); - } catch (RemoteException e) { - throw new APICallException(e); - } - if (objectWrapper == null) return null; - return ObjectWrapper.unwrap(objectWrapper, Service.class); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - if (mService == null) return null; - try { - return mService.onBind(intent); - } catch (Exception e) { - throw new APICallException(e); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/PrerenderController.java b/weblayer/public/java/org/chromium/weblayer/PrerenderController.java deleted file mode 100644 index 82d1c4d..0000000 --- a/weblayer/public/java/org/chromium/weblayer/PrerenderController.java +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IPrerenderController; -import org.chromium.weblayer_private.interfaces.IProfile; - -/** - * PrerenderController enables prerendering of urls. - * - * Prerendering has the same effect as adding a link rel="prerender" resource hint to a web page. It - * is implemented using NoStatePrefetch and fetches resources needed for a url in advance, but does - * not execute Javascript or render any part of the page in advance. For more information on - * NoStatePrefetch, see https://developers.google.com/web/updates/2018/07/nostate-prefetch. - */ -class PrerenderController { - private final IPrerenderController mImpl; - - static PrerenderController create(IProfile profile) { - try { - return new PrerenderController(profile.getPrerenderController()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - // Constructor for test mocking. - protected PrerenderController() { - mImpl = null; - } - - PrerenderController(IPrerenderController prerenderController) { - mImpl = prerenderController; - } - - /* - * Creates a prerender for the url provided. - * Prerendering here is implemented using NoStatePrefetch. We fetch resources and save them - * to the HTTP cache. All resources are cached according to their cache headers. For details, - * see https://developers.google.com/web/updates/2018/07/nostate-prefetch#implementation. - * - * On low end devices or when the device has too many renderers running and prerender is - * considered expensive, we do preconnect instead. Preconnect involves creating connections with - * the server without actually fetching any resources. For more information on preconnect, see - * https://www.chromium.org/developers/design-documents/network-stack/preconnect. - * @param uri The uri to prerender. - */ - public void schedulePrerender(@NonNull Uri uri) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.prerender(uri.toString()); - } catch (RemoteException exception) { - throw new APICallException(exception); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/Profile.java b/weblayer/public/java/org/chromium/weblayer/Profile.java deleted file mode 100644 index 0f777dc..0000000 --- a/weblayer/public/java/org/chromium/weblayer/Profile.java +++ /dev/null
@@ -1,636 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.RemoteException; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IClientDownload; -import org.chromium.weblayer_private.interfaces.IDownload; -import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient; -import org.chromium.weblayer_private.interfaces.IGoogleAccountAccessTokenFetcherClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IOpenUrlCallbackClient; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.IProfileClient; -import org.chromium.weblayer_private.interfaces.IUserIdentityCallbackClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.io.File; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Profile holds state (typically on disk) needed for browsing. Create a - * Profile via WebLayer. - */ -class Profile { - private static final Map<String, Profile> sProfiles = new HashMap<>(); - private static final Map<String, Profile> sIncognitoProfiles = new HashMap<>(); - - /* package */ static Profile of(IProfile impl) { - ThreadCheck.ensureOnUiThread(); - String name; - try { - name = impl.getName(); - } catch (RemoteException e) { - throw new APICallException(e); - } - boolean isIncognito; - try { - isIncognito = impl.isIncognito(); - } catch (RemoteException e) { - throw new APICallException(e); - } - Profile profile; - if (isIncognito) { - profile = sIncognitoProfiles.get(name); - } else { - profile = sProfiles.get(name); - } - if (profile != null) { - return profile; - } - - return new Profile(name, impl, isIncognito); - } - - /** - * Return all profiles that have been created and not yet called destroyed. - */ - @NonNull - public static Collection<Profile> getAllProfiles() { - ThreadCheck.ensureOnUiThread(); - Set<Profile> profiles = new HashSet<Profile>(); - profiles.addAll(sProfiles.values()); - profiles.addAll(sIncognitoProfiles.values()); - return profiles; - } - - static String sanitizeProfileName(String profileName) { - if ("".equals(profileName)) { - throw new IllegalArgumentException("Profile path cannot be empty"); - } - return profileName == null ? "" : profileName; - } - - private final String mName; - private final boolean mIsIncognito; - private IProfile mImpl; - private DownloadCallbackClientImpl mDownloadCallbackClient; - private final CookieManager mCookieManager; - private final PrerenderController mPrerenderController; - - // Constructor for test mocking. - protected Profile() { - mName = null; - mIsIncognito = false; - mImpl = null; - mCookieManager = null; - mPrerenderController = null; - } - - private Profile(String name, IProfile impl, boolean isIncognito) { - mName = name; - mImpl = impl; - mIsIncognito = isIncognito; - mCookieManager = CookieManager.create(impl); - mPrerenderController = PrerenderController.create(impl); - - if (isIncognito) { - sIncognitoProfiles.put(name, this); - } else { - sProfiles.put(name, this); - } - - try { - mImpl.setClient(new ProfileClientImpl()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - IProfile getIProfile() { - return mImpl; - } - - /** - * Returns the name of the profile. While added in 87, this can be used with any version. - * - * @return The name of the profile. - */ - @NonNull - public String getName() { - return mName; - } - - /** - * Returns true if the profile is incognito. While added in 87, this can be used with any - * version. - * - * @return True if the profile is incognito. - */ - public boolean isIncognito() { - return mIsIncognito; - } - - /** - * Clears the data associated with the Profile. - * The clearing is asynchronous, and new data may be generated during clearing. It is safe to - * call this method repeatedly without waiting for callback. - * - * @param dataTypes See {@link BrowsingDataType}. - * @param fromMillis Defines the start (in milliseconds since epoch) of the time range to clear. - * @param toMillis Defines the end (in milliseconds since epoch) of the time range to clear. - * For clearing all data prefer using {@link Long#MAX_VALUE} to - * {@link System.currentTimeMillis()} to take into account possible system clock changes. - * @param callback {@link Runnable} which is run when clearing is finished. - */ - public void clearBrowsingData(@NonNull @BrowsingDataType int[] dataTypes, long fromMillis, - long toMillis, @NonNull Runnable callback) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.clearBrowsingData(dataTypes, fromMillis, toMillis, ObjectWrapper.wrap(callback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Clears the data associated with the Profile. - * Same as {@link #clearBrowsingData(int[], long, long, Runnable)} with unbounded time range. - */ - public void clearBrowsingData( - @NonNull @BrowsingDataType int[] dataTypes, @NonNull Runnable callback) { - ThreadCheck.ensureOnUiThread(); - clearBrowsingData(dataTypes, 0, Long.MAX_VALUE, callback); - } - - /** - * Delete all profile data stored on disk. There are a number of edge cases with deleting - * profile data: - * * This method will throw an exception if there are any existing usage of this Profile. For - * example, all BrowserFragment belonging to this profile must be destroyed. - * * This object is considered destroyed after this method returns. Calling any other method - * after will throw exceptions. - * * Creating a new profile of the same name before doneCallback runs will throw an exception. - * - * After calling this function, {@link #getAllProfiles()} will not return the Profile, and - * {@link #enumerateAllProfileNames} will not return the profile name. - * - * @param completionCallback Callback that is notified when destruction and deletion of data is - * complete. - */ - public void destroyAndDeleteDataFromDisk(@Nullable Runnable completionCallback) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.destroyAndDeleteDataFromDisk(ObjectWrapper.wrap(completionCallback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - onDestroyed(); - } - - /** - * This method provides the same functionality as {@link destroyAndDeleteDataFromDisk}, but - * delays until there is no usage of the Profile. If there is no usage of the profile, - * destruction and deletion of data on disk is immediate. If there is usage, then destruction - * and deletion of data happens when there is no usage of the Profile. If the process is killed - * before deletion of data on disk occurs, then deletion of data happens when WebLayer is - * restarted. - * - * While destruction may be delayed, once this function is called, the profile name will not be - * returned from {@link WebLayer#enumerateAllProfileNames}. OTOH, {@link #getAllProfiles()} - * returns this profile until there are no more usages. - * - * If this function is called multiple times before the Profile is destroyed, then every - * callback supplied is run once destruction and deletion of data is complete. - * - * @param completionCallback Callback that is notified when destruction and deletion of data is - * complete. If the process is killed before all references are removed, the callback is never - * called. - * - * @throws IllegalStateException If the Profile has already been destroyed. You can check for - * that by looking for the profile in {@link #getAllProfiles()}. - */ - public void destroyAndDeleteDataFromDiskSoon(@Nullable Runnable completionCallback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.destroyAndDeleteDataFromDiskSoon(ObjectWrapper.wrap(completionCallback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - private void throwIfDestroyed() { - if (mImpl == null) { - throw new IllegalStateException("Profile can not be used once destroyed"); - } - } - - @Deprecated - public void destroy() { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.destroy(); - } catch (RemoteException e) { - throw new APICallException(e); - } - onDestroyed(); - } - - private void onDestroyed() { - if (mIsIncognito) { - sIncognitoProfiles.remove(mName); - } else { - sProfiles.remove(mName); - } - mImpl = null; - } - - /** - * Allows embedders to override the default download directory. By default this is the system - * download directory. - * - * @param directory the directory to place downloads in. - */ - public void setDownloadDirectory(@NonNull File directory) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.setDownloadDirectory(directory.toString()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Allows embedders to control how downloads function. - * - * @param callback the callback interface implemented by the embedder. - */ - public void setDownloadCallback(@Nullable DownloadCallback callback) { - ThreadCheck.ensureOnUiThread(); - try { - if (callback != null) { - mDownloadCallbackClient = new DownloadCallbackClientImpl(callback); - mImpl.setDownloadCallbackClient(mDownloadCallbackClient); - } else { - mDownloadCallbackClient = null; - mImpl.setDownloadCallbackClient(null); - } - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Gets the cookie manager for this profile. - */ - @NonNull - public CookieManager getCookieManager() { - ThreadCheck.ensureOnUiThread(); - - return mCookieManager; - } - - /** - * Gets the prerender controller for this profile. - */ - @NonNull - public PrerenderController getPrerenderController() { - ThreadCheck.ensureOnUiThread(); - return mPrerenderController; - } - - /** - * Allows the embedder to set a boolean value for a specific setting, see {@link SettingType} - * for more details and the possible options. - * - * @param type See {@link SettingType}. - * @param value The value to set for the setting. - */ - public void setBooleanSetting(@SettingType int type, boolean value) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.setBooleanSetting(type, value); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the current value for the given setting type, see {@link SettingType} for more - * details and the possible options. - */ - public boolean getBooleanSetting(@SettingType int type) { - ThreadCheck.ensureOnUiThread(); - try { - return mImpl.getBooleanSetting(type); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Asynchronously fetches the set of known Browser persistence-ids. See - * {@link WebLayer#createBrowserFragment} for details on the persistence-id. - * - * @param callback The callback that is supplied the set of ids. - * - * @throws IllegalStateException If called on an in memory profile. - */ - public void getBrowserPersistenceIds(@NonNull Callback<Set<String>> callback) { - ThreadCheck.ensureOnUiThread(); - if (mName.isEmpty()) { - throw new IllegalStateException( - "getBrowserPersistenceIds() is not applicable to in-memory profiles"); - } - try { - mImpl.getBrowserPersistenceIds( - ObjectWrapper.wrap((ValueCallback<Set<String>>) callback::onResult)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Asynchronously removes the storage associated with the set of Browser persistence-ids. This - * ignores ids actively in use. {@link doneCallback} is supplied the result of the operation. A - * value of true means all files were removed. A value of false indicates at least one of the - * files could not be removed. - * - * @param callback The callback that is supplied the result of the operation. - * - * @throws IllegalStateException If called on an in memory profile. - * @throws IllegalArgumentException if {@link ids} contains an empty/null string. - */ - public void removeBrowserPersistenceStorage( - @NonNull Set<String> ids, @NonNull Callback<Boolean> callback) { - ThreadCheck.ensureOnUiThread(); - if (mName.isEmpty()) { - throw new IllegalStateException( - "removetBrowserPersistenceStorage() is not applicable to in-memory profiles"); - } - try { - mImpl.removeBrowserPersistenceStorage(ids.toArray(new String[ids.size()]), - ObjectWrapper.wrap((ValueCallback<Boolean>) callback::onResult)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * For cross-origin navigations, the implementation may leverage a separate OS process for - * stronger isolation. If an embedder knows that a cross-origin navigation is likely starting - * soon, they can call this method as a hint to the implementation to start a fresh OS process. - * A subsequent navigation may use this preinitialized process, improving performance. It is - * safe to call this multiple times or when it is not certain that the spare renderer will be - * used, although calling this too eagerly may reduce performance as unnecessary processes are - * created. - */ - public void prepareForPossibleCrossOriginNavigation() { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.prepareForPossibleCrossOriginNavigation(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the previously downloaded favicon for {@link uri}. - * - * @param uri The uri to get the favicon for. - * @param callback The callback that is notified of the bitmap. The bitmap passed to the - * callback will be null if one is not available. - */ - public void getCachedFaviconForPageUri(@NonNull Uri uri, @NonNull Callback<Bitmap> callback) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.getCachedFaviconForPageUri( - uri.toString(), ObjectWrapper.wrap((ValueCallback<Bitmap>) callback::onResult)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * See {@link UserIdentityCallback}. - */ - public void setUserIdentityCallback(@Nullable UserIdentityCallback callback) { - ThreadCheck.ensureOnUiThread(); - try { - mImpl.setUserIdentityCallbackClient( - callback == null ? null : new UserIdentityCallbackClientImpl(callback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * See {@link GoogleAccountAccessTokenFetcher}. - * @since 89 - */ - public void setGoogleAccountAccessTokenFetcher( - @Nullable GoogleAccountAccessTokenFetcher fetcher) { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 89) { - throw new UnsupportedOperationException(); - } - try { - mImpl.setGoogleAccountAccessTokenFetcherClient(fetcher == null - ? null - : new GoogleAccountAccessTokenFetcherClientImpl(fetcher)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Sets a callback which is invoked to open a new tab that is not associated with any open tab. - * - * This will be called in cases where a service worker tries to open a tab, e.g. via the Web API - * clients.openWindow. If set to null, all such navigation requests will be rejected. - * - * @since 91 - */ - public void setTablessOpenUrlCallback(@Nullable OpenUrlCallback callback) { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 91) { - throw new UnsupportedOperationException(); - } - - try { - mImpl.setTablessOpenUrlCallbackClient( - callback == null ? null : new OpenUrlCallbackClientImpl(callback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - static final class DownloadCallbackClientImpl extends IDownloadCallbackClient.Stub { - private final DownloadCallback mCallback; - - DownloadCallbackClientImpl(DownloadCallback callback) { - mCallback = callback; - } - - @Override - public boolean interceptDownload(String uriString, String userAgent, - String contentDisposition, String mimetype, long contentLength) { - StrictModeWorkaround.apply(); - return mCallback.onInterceptDownload( - Uri.parse(uriString), userAgent, contentDisposition, mimetype, contentLength); - } - - @Override - public void allowDownload(String uriString, String requestMethod, - String requestInitiatorString, IObjectWrapper valueCallback) { - StrictModeWorkaround.apply(); - Uri requestInitiator; - if (requestInitiatorString != null) { - requestInitiator = Uri.parse(requestInitiatorString); - } else { - requestInitiator = Uri.EMPTY; - } - mCallback.allowDownload(Uri.parse(uriString), requestMethod, requestInitiator, - (ValueCallback<Boolean>) ObjectWrapper.unwrap( - valueCallback, ValueCallback.class)); - } - - @Override - public IClientDownload createClientDownload(IDownload downloadImpl) { - StrictModeWorkaround.apply(); - return new Download(downloadImpl); - } - - @Override - public void downloadStarted(IClientDownload download) { - StrictModeWorkaround.apply(); - mCallback.onDownloadStarted((Download) download); - } - - @Override - public void downloadProgressChanged(IClientDownload download) { - StrictModeWorkaround.apply(); - mCallback.onDownloadProgressChanged((Download) download); - } - - @Override - public void downloadCompleted(IClientDownload download) { - StrictModeWorkaround.apply(); - mCallback.onDownloadCompleted((Download) download); - } - - @Override - public void downloadFailed(IClientDownload download) { - StrictModeWorkaround.apply(); - mCallback.onDownloadFailed((Download) download); - } - } - - private static final class UserIdentityCallbackClientImpl - extends IUserIdentityCallbackClient.Stub { - private UserIdentityCallback mCallback; - - UserIdentityCallbackClientImpl(UserIdentityCallback callback) { - mCallback = callback; - } - - @Override - public String getEmail() { - StrictModeWorkaround.apply(); - return mCallback.getEmail(); - } - - @Override - public String getFullName() { - StrictModeWorkaround.apply(); - return mCallback.getFullName(); - } - - @Override - public void getAvatar(int desiredSize, IObjectWrapper avatarLoadedWrapper) { - StrictModeWorkaround.apply(); - ValueCallback<Bitmap> avatarLoadedCallback = - (ValueCallback<Bitmap>) ObjectWrapper.unwrap( - avatarLoadedWrapper, ValueCallback.class); - mCallback.getAvatar(desiredSize, avatarLoadedCallback); - } - } - - private static final class GoogleAccountAccessTokenFetcherClientImpl - extends IGoogleAccountAccessTokenFetcherClient.Stub { - private GoogleAccountAccessTokenFetcher mFetcher; - - GoogleAccountAccessTokenFetcherClientImpl(GoogleAccountAccessTokenFetcher fetcher) { - mFetcher = fetcher; - } - - @Override - public void fetchAccessToken( - IObjectWrapper scopesWrapper, IObjectWrapper onTokenFetchedWrapper) { - StrictModeWorkaround.apply(); - Set<String> scopes = ObjectWrapper.unwrap(scopesWrapper, Set.class); - ValueCallback<String> valueCallback = - ObjectWrapper.unwrap(onTokenFetchedWrapper, ValueCallback.class); - - mFetcher.fetchAccessToken(scopes, (token) -> valueCallback.onReceiveValue(token)); - } - - @Override - public void onAccessTokenIdentifiedAsInvalid( - IObjectWrapper scopesWrapper, IObjectWrapper tokenWrapper) { - StrictModeWorkaround.apply(); - Set<String> scopes = ObjectWrapper.unwrap(scopesWrapper, Set.class); - String token = ObjectWrapper.unwrap(tokenWrapper, String.class); - - mFetcher.onAccessTokenIdentifiedAsInvalid(scopes, token); - } - } - - private static final class OpenUrlCallbackClientImpl extends IOpenUrlCallbackClient.Stub { - private final OpenUrlCallback mCallback; - - OpenUrlCallbackClientImpl(OpenUrlCallback callback) { - mCallback = callback; - } - - @Override - public IBrowser getBrowserForNewTab() { - StrictModeWorkaround.apply(); - Browser browser = mCallback.getBrowserForNewTab(); - return browser == null ? null : browser.getIBrowser(); - } - - @Override - public void onTabAdded(int tabId) { - StrictModeWorkaround.apply(); - Tab tab = Tab.getTabById(tabId); - // Tab should have already been created by way of BrowserClient. - assert tab != null; - mCallback.onTabAdded(tab); - } - } - - private final class ProfileClientImpl extends IProfileClient.Stub { - @Override - public void onProfileDestroyed() { - onDestroyed(); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ProfileManagerDelegate.java b/weblayer/public/java/org/chromium/weblayer/ProfileManagerDelegate.java deleted file mode 100644 index 838930f..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ProfileManagerDelegate.java +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.IProfileManagerDelegate; -import org.chromium.webengine.interfaces.IStringListCallback; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class acts as a proxy between the WebSandbox and Profiles. - */ -public class ProfileManagerDelegate extends IProfileManagerDelegate.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - private WebLayer mWeblayer; - - ProfileManagerDelegate(WebLayer webLayer) { - mWeblayer = webLayer; - } - - @Override - public void getAllProfileNames(IStringListCallback callback) { - mHandler.post(() -> { - try { - List<String> names = new ArrayList<>(); - for (Profile profile : Profile.getAllProfiles()) { - names.add(profile.getName()); - } - callback.onResult(names); - } catch (RemoteException e) { - } - }); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/README.md b/weblayer/public/java/org/chromium/weblayer/README.md deleted file mode 100644 index fb985cd8c..0000000 --- a/weblayer/public/java/org/chromium/weblayer/README.md +++ /dev/null
@@ -1,93 +0,0 @@ -# WebEngine's Service Java API - -See comments in [weblayer/public/README.md](../../../../README.md) for -general comments on WebEngine's public API and architecture. This document -provides guidance on writing WebEngine's public Java API. - -## Typical method - -A method typically looks something like: - -``` -public void aMethod() { - // Nearly all methods must be called on the ui thread. - ThreadCheck.ensureOnUiThread(); - // Newly added functions have version checks. - if (WebLayer.getSupportedMajorVersionInternal() < 86) { - throw new UnsupportedOperationException(); - } - // For cases where the implementation may be destroyed, throw an exception - // to help debugging. - if (mImpl == null) { - throw new IllegalStateException("Attempt to use class after destroyed"); - } - // All AIDL calls have checked exceptions. use try/catch and rethrow an - // APICallException. - try { - mImpl.doSomething(); - } catch (RemoteException e) { - throw new APICallException(e); - } -} -``` - -## Versioning - -A more complete write up is here -https://docs.google.com/document/d/1RsknOu7YOl2AWVXri5kfl7QblgGf41A3ZtJWJoBZ-4I. - -In general, only add new methods, and do not modify signatures of existing -methods. This is especially important of AIDL files, but also applies to the -signature of methods in the public API. - -Adding a new method to the client library generally looks like: - -``` - /** - * @since 86 - */ - public void aNewMethod() { - ThreadCheck.ensureOnUiThread(); - if (WebLayer.getSupportedMajorVersionInternal() < 86) { - throw new UnsupportedOperationException(); - } - } -} -``` - -The implementation may also need to check the version of the client. This can -be done using `WebLayerFactoryImpl.getClientMajorVersion()`. - -## Avoid Parcelable - -Parcelable does not support versioning. Additionally, as all function arguments -are written to the same Parcel, it would be very challenging to layer versioning -on top of Parcelable. For these reasons, WebEngine's public API avoids using -Parcelable. - -For methods that would have a significant number of arguments, use an Object. -At the AIDL boundary, pass all members of the Object as arguments. This makes -it trivial to add new parameters later on. - -For example, - -``` -public class CustomParameter { - private String mArg1; - private String mArg2; - public String getArgument1() { return mArg1; } - public String getArgument2() { return mArg2; } -} -``` - -And calling the AIDL method would look like: - -``` - aidlMethod(customParameter.getArgument1(), customParameter.getArgument2()); -``` - -## Abstract classes - -When adding a new method to an abstract class it must be concrete. To do -otherwise would mean embedders can not compile their code against a new version -of the client library without changing their code.
diff --git a/weblayer/public/java/org/chromium/weblayer/RemoteFragmentEventHandler.java b/weblayer/public/java/org/chromium/weblayer/RemoteFragmentEventHandler.java deleted file mode 100644 index b7e448e..0000000 --- a/weblayer/public/java/org/chromium/weblayer/RemoteFragmentEventHandler.java +++ /dev/null
@@ -1,198 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.RemoteException; -import android.view.SurfaceControlViewHost; -import android.view.View; - -import androidx.annotation.CallSuper; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.IRemoteFragmentClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * A base class for different types of Fragments being rendered remotely. - * - * This class acts as a bridge for all the of the Fragment events received from the client side and - * the weblayer private implementation. - */ -abstract class RemoteFragmentEventHandler { - @Nullable - private IRemoteFragment mRemoteFragment; - - private RemoteFragmentClientImpl mRemoteFragmentClient; - - RemoteFragmentEventHandler(IRemoteFragment remoteFragment) { - ThreadCheck.ensureOnUiThread(); - mRemoteFragment = remoteFragment; - - mRemoteFragmentClient = new RemoteFragmentClientImpl(); - try { - mRemoteFragment.setClient(mRemoteFragmentClient); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onAttach(Context context, @Nullable Fragment fragment) { - ThreadCheck.ensureOnUiThread(); - mRemoteFragmentClient.setFragment(fragment); - try { - mRemoteFragment.handleOnAttach(ObjectWrapper.wrap(context)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onCreate() { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleOnCreate(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onStart() { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleOnStart(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onResume() { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleOnResume(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onPause() { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleOnPause(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onStop() { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleOnStop(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onDestroy() { - ThreadCheck.ensureOnUiThread(); - - try { - mRemoteFragment.handleOnDestroy(); - // The other side does the clean up automatically in handleOnDestroy() - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onDetach() { - ThreadCheck.ensureOnUiThread(); - mRemoteFragmentClient.setFragment(null); - try { - mRemoteFragment.handleOnDetach(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void onActivityResult(int requestCode, int resultCode, Intent intent) { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleOnActivityResult( - requestCode, resultCode, ObjectWrapper.wrap(intent)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected View getContentViewRenderView() { - ThreadCheck.ensureOnUiThread(); - try { - return ObjectWrapper.unwrap( - mRemoteFragment.handleGetContentViewRenderView(), View.class); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void setSurfaceControlViewHost(SurfaceControlViewHost host) { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleSetSurfaceControlViewHost(ObjectWrapper.wrap(host)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @CallSuper - protected void setMinimumSurfaceSize(int width, int height) { - ThreadCheck.ensureOnUiThread(); - try { - mRemoteFragment.handleSetMinimumSurfaceSize(width, height); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - protected IRemoteFragment getRemoteFragment() { - return mRemoteFragment; - } - - final class RemoteFragmentClientImpl extends IRemoteFragmentClient.Stub { - // The WebFragment. Only available for in-process mode. - @Nullable - private Fragment mFragment; - - void setFragment(@Nullable Fragment fragment) { - mFragment = fragment; - } - - @Override - public boolean startActivityForResult( - IObjectWrapper intent, int requestCode, IObjectWrapper options) { - if (mFragment != null) { - mFragment.startActivityForResult(ObjectWrapper.unwrap(intent, Intent.class), - requestCode, ObjectWrapper.unwrap(options, Bundle.class)); - return true; - } - return false; - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java b/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java deleted file mode 100644 index 64cf8286..0000000 --- a/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Intent; -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.RemoteMediaServiceConstants; - -/** - * A foreground {@link Service} for Presentation API and Remote Playback API. - * - * Like {@link MediaSessionService}, this class is associated with a notification for an ongoing - * media session. The difference is that the media for this service is played back on a remote - * device, i.e. casting. This class can be considered an implementation detail of WebLayer. - * - * In order to set the Cast application (optional but recommended), the client should add the - * following to its manifest: - * - * <meta-data - * android:name="org.chromium.content.browser.REMOTE_PLAYBACK_APP_ID" - * android:value="$APP_ID"/> - * - * Where $APP_ID is the value assigned to your app by the Google Cast SDK Developer Console. If - * the cast application ID is not set, the app will appear as "Default Media Receiver" in the - * notification, device selection dialog, etc. - * - * @since 88 - */ -class RemoteMediaService extends MediaPlaybackBaseService { - private int mId; - - @Override - void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent) - throws RemoteException { - mId = intent.getIntExtra(RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, 0); - if (mId == 0) throw new RuntimeException("Invalid RemoteMediaService notification id"); - - webLayer.getImpl().onRemoteMediaServiceStarted(ObjectWrapper.wrap(this), intent); - } - - @Override - void forwardDestroyToImpl() throws RemoteException { - getWebLayer().getImpl().onRemoteMediaServiceDestroyed(mId); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ScrollNotificationType.java b/weblayer/public/java/org/chromium/weblayer/ScrollNotificationType.java deleted file mode 100644 index ba1e328..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ScrollNotificationType.java +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({ScrollNotificationType.DIRECTION_CHANGED_UP, - ScrollNotificationType.DIRECTION_CHANGED_DOWN}) -@Retention(RetentionPolicy.SOURCE) -@interface ScrollNotificationType { - /** - * This is the direction toward vertical scroll offset 0. Note direction change notification - * is sent on direction change. If there are two consecutive scrolls in the same direction, - * the second scroll will not generate a direction change notification. Also the notification - * is sent as a result of scroll change; this means for touch scrolls, this is sent (if there - * is a direction change) on the first touch move, not touch down. - */ - int DIRECTION_CHANGED_UP = - org.chromium.weblayer_private.interfaces.ScrollNotificationType.DIRECTION_CHANGED_UP; - - /** - * This is the direction away from vertical scroll offset 0. See notes on DIRECTION_CHANGED_UP. - */ - int DIRECTION_CHANGED_DOWN = - org.chromium.weblayer_private.interfaces.ScrollNotificationType.DIRECTION_CHANGED_DOWN; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java b/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java deleted file mode 100644 index 08726e4..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * Callback notified when the vertical location of the content of a Tab changes. The value reported - * by the callback corresponds to the 'scrollTop' html property. - * - * WARNING: use of this API necessitates additional cross process ipc that impacts overall - * performance. Only use when absolutely necessary. - * - * Because of WebLayer's multi-process architecture, this function can not be used to reliably - * synchronize the painting of other Views with WebLayer's Views. It's entirely possible one will - * render before or after the other. - */ -abstract class ScrollOffsetCallback { - /** - * Called when the vertical scroll location of the content of a Tab changes. - * - * @param scrollLocation The new vertical location. More specifically, the 'scrollTop' html - * property. - */ - public abstract void onVerticalScrollOffsetChanged(int scrollLocation); -}
diff --git a/weblayer/public/java/org/chromium/weblayer/SettingType.java b/weblayer/public/java/org/chromium/weblayer/SettingType.java deleted file mode 100644 index 97813f8..0000000 --- a/weblayer/public/java/org/chromium/weblayer/SettingType.java +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - */ -@IntDef({SettingType.BASIC_SAFE_BROWSING_ENABLED, SettingType.UKM_ENABLED, - SettingType.EXTENDED_REPORTING_SAFE_BROWSING_ENABLED, - SettingType.REAL_TIME_SAFE_BROWSING_ENABLED}) -@Retention(RetentionPolicy.SOURCE) -@interface SettingType { - /** - * Allows the embedder to set whether it wants to disable/enable the Safe Browsing functionality - * (which checks that the loaded URLs are safe). Safe Browsing is enabled by default. - */ - int BASIC_SAFE_BROWSING_ENABLED = - org.chromium.weblayer_private.interfaces.SettingType.BASIC_SAFE_BROWSING_ENABLED; - /** - * Allows the embedder to enable URL-Keyed Metrics. Disabled by default. - */ - int UKM_ENABLED = org.chromium.weblayer_private.interfaces.SettingType.UKM_ENABLED; - - /** - * Allows the embedder to set whether it wants to enable/disable the Extended Reporting - * functionality for Safe Browsing (SBER). This functionality helps improve security on the web - * for everyone. It sends URLs of some pages you visit, limited system information, and some - * page content to Google, to help discover new threats and protect everyone on the web. - * - * This setting is disabled by default, but can also be enabled by the user by checking a - * checkbox in the Safe Browsing interstitial which is displayed when the user encounters a - * dangerous web page. The setting persists on disk. - * - * Note: this setting applies when Safe Browsing is enabled (i.e. BASIC_SAFE_BROWSING_ENABLED - * is true). - */ - int EXTENDED_REPORTING_SAFE_BROWSING_ENABLED = - org.chromium.weblayer_private.interfaces.SettingType - .EXTENDED_REPORTING_SAFE_BROWSING_ENABLED; - - /** - * Allows the embedder to set whether it wants to enable/disable the Safe Browsing Real-time URL - * checks. This functionality is disabled by default. - * - * Note: this setting applies when Safe Browsing is enabled (i.e. BASIC_SAFE_BROWSING_ENABLED - * is true). - */ - int REAL_TIME_SAFE_BROWSING_ENABLED = - org.chromium.weblayer_private.interfaces.SettingType.REAL_TIME_SAFE_BROWSING_ENABLED; - - /** - * Allows the embedder to enable/disable NoStatePrefetch. Enabled by default. - */ - int NETWORK_PREDICTION_ENABLED = - org.chromium.weblayer_private.interfaces.SettingType.NETWORK_PREDICTION_ENABLED; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/Tab.java b/weblayer/public/java/org/chromium/weblayer/Tab.java deleted file mode 100644 index b298f59..0000000 --- a/weblayer/public/java/org/chromium/weblayer/Tab.java +++ /dev/null
@@ -1,893 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.RemoteException; -import android.util.Pair; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IClientNavigation; -import org.chromium.weblayer_private.interfaces.IContextMenuParams; -import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient; -import org.chromium.weblayer_private.interfaces.IExternalIntentInIncognitoCallbackClient; -import org.chromium.weblayer_private.interfaces.IFullscreenCallbackClient; -import org.chromium.weblayer_private.interfaces.IGoogleAccountsCallbackClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IStringCallback; -import org.chromium.weblayer_private.interfaces.ITab; -import org.chromium.weblayer_private.interfaces.ITabClient; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Represents a single tab in a browser. More specifically, owns a NavigationController, and allows - * configuring state of the tab, such as delegates and callbacks. - */ -class Tab { - // Maps from id (as returned from ITab.getId()) to Tab. - private static final Map<Integer, Tab> sTabMap = new HashMap<Integer, Tab>(); - - private ITab mImpl; - // Remember the stack of Tab destruction. - private Throwable mDestroyStack; - private final NavigationController mNavigationController; - private final FindInPageController mFindInPageController; - private final MediaCaptureController mMediaCaptureController; - private final ObserverList<TabCallback> mCallbacks; - private Browser mBrowser; - private FullscreenCallbackClientImpl mFullscreenCallbackClient; - private NewTabCallback mNewTabCallback; - private final ObserverList<ScrollOffsetCallback> mScrollOffsetCallbacks; - private @Nullable ActionModeCallback mActionModeCallback; - - private TabProxy mTabProxy; - private TabNavigationControllerProxy mTabNavigationControllerProxy; - - // Id from the remote side. - private final int mId; - // Guid from the remote side. - private final String mGuid; - - // Constructor for test mocking. - protected Tab() { - mImpl = null; - mNavigationController = null; - mFindInPageController = null; - mMediaCaptureController = null; - mCallbacks = null; - mScrollOffsetCallbacks = null; - mId = 0; - mGuid = ""; - mTabProxy = null; - mTabNavigationControllerProxy = null; - } - - Tab(ITab impl, Browser browser) { - mImpl = impl; - mBrowser = browser; - try { - mId = impl.getId(); - mGuid = impl.getGuid(); - mImpl.setClient(new TabClientImpl()); - } catch (RemoteException e) { - throw new APICallException(e); - } - - mCallbacks = new ObserverList<TabCallback>(); - mScrollOffsetCallbacks = new ObserverList<ScrollOffsetCallback>(); - mNavigationController = NavigationController.create(mImpl); - mFindInPageController = new FindInPageController(mImpl); - mMediaCaptureController = new MediaCaptureController(mImpl); - - mTabProxy = new TabProxy(this); - mTabNavigationControllerProxy = new TabNavigationControllerProxy(mNavigationController); - - registerTab(this); - } - - static void registerTab(Tab tab) { - assert getTabById(tab.getId()) == null; - sTabMap.put(tab.getId(), tab); - } - - static void unregisterTab(Tab tab) { - assert getTabById(tab.getId()) != null; - sTabMap.remove(tab.getId()); - } - - static Tab getTabById(int id) { - return sTabMap.get(id); - } - - static Set<Tab> getTabsInBrowser(Browser browser) { - Set<Tab> tabs = new HashSet<Tab>(); - for (Tab tab : sTabMap.values()) { - if (tab.getBrowser() == browser) tabs.add(tab); - } - return tabs; - } - - private void throwIfDestroyed() { - if (mImpl == null) { - throw new IllegalStateException("Tab can not be used once destroyed", mDestroyStack); - } - } - - int getId() { - return mId; - } - - String getUri() { - try { - return mImpl.getUri(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - void setBrowser(Browser browser) { - mBrowser = browser; - } - - /** - * Returns true if this Tab has been destroyed. - */ - public boolean isDestroyed() { - ThreadCheck.ensureOnUiThread(); - return mImpl == null; - } - - /** - * Returns whether the tab will automatically reload after its renderer process is lost. - * - * This returns true if the tab is known not to be visible, specifically if the tab is not - * active in its browser or its Fragment is not started. When a tab in this state loses its - * renderer process to a crash (or due to system memory reclamation), it will automatically - * reload next the time it becomes possibly visible. - */ - public boolean willAutomaticallyReloadAfterCrash() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - return mImpl.willAutomaticallyReloadAfterCrash(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @NonNull - public Browser getBrowser() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - return mBrowser; - } - - public void setErrorPageCallback(@Nullable ErrorPageCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.setErrorPageCallbackClient( - callback == null ? null : new ErrorPageCallbackClientImpl(callback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public void setFullscreenCallback(@Nullable FullscreenCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - if (callback != null) { - mFullscreenCallbackClient = new FullscreenCallbackClientImpl(callback); - mImpl.setFullscreenCallbackClient(mFullscreenCallbackClient); - } else { - mImpl.setFullscreenCallbackClient(null); - mFullscreenCallbackClient = null; - } - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Creates a {@link FaviconFetcher} that notifies a {@link FaviconCallback} when the favicon - * changes. - * - * When the fetcher is no longer necessary, call {@link destroy}. Destroying the Tab implicitly - * destroys any fetchers that were created. - * - * A page may provide any number of favicons. This favors a largish favicon. If a previously - * cached icon is available, it is used, otherwise the icon is downloaded. - * - * {@link callback} may be called multiple times for the same navigation. This happens if the - * page dynamically updates the favicon. - * - * @param callback The callback to notify of changes. - */ - public @NonNull FaviconFetcher createFaviconFetcher(@NonNull FaviconCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - return new FaviconFetcher(mImpl, callback); - } - - /** - * Sets the target language for translation such that whenever the translate UI shows in this - * Tab, the target language will be |targetLanguage|. Notes: - * - |targetLanguage| should be specified as the language code (e.g., "de" for German). - * - Passing an empty string causes behavior to revert to default. - * - Specifying a non-empty target language will also result in the following behaviors (all of - * which are intentional as part of the semantics of having a target language): - * - Translation is initiated automatically (note that the infobar UI is present) - * - Translation occurs even for languages/sites that the user has blocklisted - * - Translation occurs even for pages in the user's default locale - * - Translation does *not* occur nor is the infobar UI shown for pages in the specified - * target language - */ - public void setTranslateTargetLanguage(@NonNull String targetLanguage) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.setTranslateTargetLanguage(targetLanguage); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Executes the script, and returns the result to the callback if provided. - * @param useSeparateIsolate If true, runs the script in a separate v8 Isolate. This uses more - * memory, but separates the injected scrips from scripts in the page. This prevents any - * potentially malicious interaction between first-party scripts in the page, and injected - * scripts. Use with caution, only pass false for this argument if you know this isn't an issue - * or you need to interact with first-party scripts. - */ - public void executeScript( - @NonNull String script, boolean useSeparateIsolate, IStringCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.executeScript(script, useSeparateIsolate, callback); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Runs the beforeunload handler for the main frame or any sub frame, if necessary; otherwise, - * asynchronously closes the tab. - * - * If there is a beforeunload handler a dialog is shown to the user which will allow them to - * choose whether to proceed with closing the tab. WebLayer closes the tab internally and the - * embedder will be notified via TabListCallback#onTabRemoved(). The tab will not close if the - * user chooses to cancel the action. If there is no beforeunload handler, the tab closure will - * be asynchronous (but immediate) and will be notified in the same way. - * - * To close the tab synchronously without running beforeunload, use {@link Browser#destroyTab}. - */ - public void dispatchBeforeUnloadAndClose() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.dispatchBeforeUnloadAndClose(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Dismisses one active transient UI, if any. - * - * This is useful, for example, to handle presses on the system back button. UI such as tab - * modal dialogs, text selection popups and fullscreen will be dismissed. At most one piece of - * UI will be dismissed, but this distinction isn't very meaningful in practice since only one - * such kind of UI would tend to be active at a time. - * - * @return true if some piece of UI was dismissed, or false if nothing happened. - */ - public boolean dismissTransientUi() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - return mImpl.dismissTransientUi(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - public void setNewTabCallback(@Nullable NewTabCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - mNewTabCallback = callback; - try { - mImpl.setNewTabsEnabled(mNewTabCallback != null); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - @Nullable - public FullscreenCallback getFullscreenCallback() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - return mFullscreenCallbackClient != null ? mFullscreenCallbackClient.getCallback() : null; - } - - @NonNull - public NavigationController getNavigationController() { - throwIfDestroyed(); - return mNavigationController; - } - - @NonNull - public FindInPageController getFindInPageController() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - return mFindInPageController; - } - - @NonNull - public MediaCaptureController getMediaCaptureController() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - return mMediaCaptureController; - } - - public void registerTabCallback(@NonNull TabCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - mCallbacks.addObserver(callback); - } - - public void unregisterTabCallback(@NonNull TabCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - mCallbacks.removeObserver(callback); - } - - /** - * Registers {@link callback} to be notified when the scroll offset changes. <b>WARNING:</b> - * adding a {@link ScrollOffsetCallback} impacts performance, ensure - * {@link ScrollOffsetCallback} are only installed when needed. See {@link ScrollOffsetCallback} - * for more details. - * - * @param callback The ScrollOffsetCallback to notify - */ - public void registerScrollOffsetCallback(@NonNull ScrollOffsetCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - if (mScrollOffsetCallbacks.isEmpty()) { - try { - mImpl.setScrollOffsetsEnabled(true); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - mScrollOffsetCallbacks.addObserver(callback); - } - - public void unregisterScrollOffsetCallback(@NonNull ScrollOffsetCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - mScrollOffsetCallbacks.removeObserver(callback); - if (mScrollOffsetCallbacks.isEmpty()) { - try { - mImpl.setScrollOffsetsEnabled(false); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - } - - /** - * Take a screenshot of this tab and return it as a Bitmap. - * This API captures only the web content, not any Java Views, including the - * view in Browser.setTopView. The browser top view shrinks the height of - * the screenshot if it is not completely hidden. - * This method will fail if - * * the Fragment of this Tab is not started during the operation - * * this tab is not the active tab in its Browser - * * if scale is not in the range (0, 1] - * * Bitmap allocation fails - * The API is asynchronous when successful, but can be synchronous on - * failure. So embedder must take care when implementing resultCallback to - * allow reentrancy. - * @param scale Scale applied to the Bitmap. - * @param resultCallback Called when operation is complete. - */ - public void captureScreenShot(float scale, @NonNull CaptureScreenShotCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.captureScreenShot(scale, - ObjectWrapper.wrap( - (ValueCallback<Pair<Bitmap, Integer>>) (Pair<Bitmap, Integer> pair) -> { - callback.onScreenShotCaptured(pair.first, pair.second); - })); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - ITab getITab() { - return mImpl; - } - - /** - * Returns a unique id that persists across restarts. - * - * @return the unique id. - */ - @NonNull - public String getGuid() { - return mGuid; - } - - @NonNull - TabNavigationControllerProxy getTabNavigationControllerProxy() { - return mTabNavigationControllerProxy; - } - - @NonNull - TabProxy getTabProxy() { - return mTabProxy; - } - - /** - * Set arbitrary data on the tab. This will be saved and restored with the browser, so it is - * important to keep this data as small as possible. - * - * @param data The data to set, must be smaller than 4K when serialized. A snapshot of this data - * is taken, so any changes to the passed in object after this call will not be reflected. - * - * @throws IllegalArgumentException if the serialzed size of the data exceeds 4K. - */ - public void setData(@NonNull Map<String, String> data) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - if (!mImpl.setData(data)) { - throw new IllegalArgumentException("Data given to Tab.setData() was too large."); - } - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Get arbitrary data set on the tab with setData(). - * - * @return the data or an empty map if no data was set. - */ - @NonNull - public Map<String, String> getData() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - return (Map<String, String>) mImpl.getData(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Sets a callback to intercept interaction with GAIA accounts. If this callback is set, any - * link that would result in a change to a user's GAIA account state will trigger a call to - * {@link GoogleAccountsCallback#onGoogleAccountsRequest}. - */ - public void setGoogleAccountsCallback(@Nullable GoogleAccountsCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.setGoogleAccountsCallbackClient( - callback == null ? null : new GoogleAccountsCallbackClientImpl(callback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Sets a callback to present warning dialogs gating external intent launches in incognito mode. - * If this callback is set, any such pending intent launch will trigger a call to {@link - * ExternalIntentInIncognitoCallback#onExternalIntentInIncognito}. - * @since 93 - */ - public void setExternalIntentInIncognitoCallback( - @Nullable ExternalIntentInIncognitoCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - if (WebLayer.getSupportedMajorVersionInternal() < 93) { - throw new UnsupportedOperationException(); - } - try { - mImpl.setExternalIntentInIncognitoCallbackClient(callback == null - ? null - : new ExternalIntentInIncognitoCallbackClientImpl(callback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - void postMessage(String message, String targetOrigin) { - try { - mImpl.postMessage(message, targetOrigin); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns true if the content displayed in this tab can be translated. - */ - public boolean canTranslate() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - return mImpl.canTranslate(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Shows the UI which allows the user to translate the content displayed in this tab. - */ - public void showTranslateUi() { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - try { - mImpl.showTranslateUi(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Allow controlling and overriding custom items in the floating seleciton menu. - * Note floating action mode is available on M and up. - * @param actionModeItemTypes a bit field of values in ActionModeItemType. - * @param callback can be null if actionModeItemTypes is 0. - * - * @since 88 - */ - public void setFloatingActionModeOverride( - int actionModeItemTypes, @Nullable ActionModeCallback callback) { - ThreadCheck.ensureOnUiThread(); - throwIfDestroyed(); - if (WebLayer.getSupportedMajorVersionInternal() < 88) { - throw new UnsupportedOperationException(); - } - mActionModeCallback = callback; - try { - mImpl.setFloatingActionModeOverride(actionModeItemTypes); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Turns on desktop user agent if enable is true, otherwise reverts back to mobile user agent. - * The selected user agent will be used for future navigations until this method is called - * again. Each navigation saves the user agent mode it was navigated with and will reuse that on - * back/forward navigations. The tab will be reloaded with the new user agent. - * @param enable if true requests desktop site, otherwise mobile site. - * - * @since 88 - */ - public void setDesktopUserAgentEnabled(boolean enable) { - if (WebLayer.getSupportedMajorVersionInternal() < 88) { - throw new UnsupportedOperationException(); - } - try { - mImpl.setDesktopUserAgentEnabled(enable); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns true if the currently loaded page used a desktop user agent. - * - * @since 88 - */ - public boolean isDesktopUserAgentEnabled() { - if (WebLayer.getSupportedMajorVersionInternal() < 88) { - throw new UnsupportedOperationException(); - } - try { - return mImpl.isDesktopUserAgentEnabled(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Downloads the item linked to from the context menu. This could be an image/video or link. - * This will request the WRITE_EXTERNAL_STORAGE permission if it's not granted to the app. - * - * @throws IllegalArgumentException if {@link ContextMenuParams.canDownload} is false or if - * the ContextMenuParams object parameter wasn't constructed by WebLayer. - * - * @since 88 - */ - public void download(ContextMenuParams contextMenuParams) { - if (WebLayer.getSupportedMajorVersionInternal() < 88) { - throw new UnsupportedOperationException(); - } - if (!contextMenuParams.canDownload) { - throw new IllegalArgumentException("ContextMenuParams not downloadable."); - } - if (contextMenuParams.mContextMenuParams == null) { - throw new IllegalArgumentException("ContextMenuParams not constructed by WebLayer."); - } - - try { - mImpl.download(contextMenuParams.mContextMenuParams); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Experimental (for now) API to trigger the AddToHomescreen dialog for the page in the tab. - * This adds a homescreen shortcut for it, or installs as a PWA or WebAPK. - * - * @since 90 - */ - private void addToHomescreen() { - if (WebLayer.getSupportedMajorVersionInternal() < 90) { - throw new UnsupportedOperationException(); - } - try { - mImpl.addToHomescreen(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - private final class TabClientImpl extends ITabClient.Stub { - @Override - public void visibleUriChanged(String uriString) { - StrictModeWorkaround.apply(); - Uri uri = Uri.parse(uriString); - for (TabCallback callback : mCallbacks) { - callback.onVisibleUriChanged(uri); - } - } - - @Override - public void onNewTab(int tabId, int mode) { - StrictModeWorkaround.apply(); - // This should only be hit if setNewTabCallback() has been called with a non-null - // value. - assert mNewTabCallback != null; - Tab tab = getTabById(tabId); - // Tab should have already been created by way of BrowserClient. - assert tab != null; - assert tab.getBrowser() == getBrowser(); - mNewTabCallback.onNewTab(tab, mode); - } - - @Override - public void onTabDestroyed() { - unregisterTab(Tab.this); - // Ensure that the app will fail fast if the embedder mistakenly tries to call back - // into the implementation via this Tab. - mImpl = null; - mDestroyStack = new RuntimeException("onTabDestroyed"); - } - - @Override - public void onRenderProcessGone() { - StrictModeWorkaround.apply(); - for (TabCallback callback : mCallbacks) { - callback.onRenderProcessGone(); - } - } - - @Override - public void showContextMenu(IObjectWrapper pageUrl, IObjectWrapper linkUrl, - IObjectWrapper linkText, IObjectWrapper titleOrAltText, IObjectWrapper srcUrl) { - showContextMenu2( - pageUrl, linkUrl, linkText, titleOrAltText, srcUrl, false, false, false, null); - } - - @Override - public void showContextMenu2(IObjectWrapper pageUrl, IObjectWrapper linkUrl, - IObjectWrapper linkText, IObjectWrapper titleOrAltText, IObjectWrapper srcUrl, - boolean isImage, boolean isVideo, boolean canDownload, - IContextMenuParams contextMenuParams) { - StrictModeWorkaround.apply(); - String pageUrlString = ObjectWrapper.unwrap(pageUrl, String.class); - String linkUrlString = ObjectWrapper.unwrap(linkUrl, String.class); - String srcUrlString = ObjectWrapper.unwrap(srcUrl, String.class); - ContextMenuParams params = new ContextMenuParams(Uri.parse(pageUrlString), - linkUrlString != null ? Uri.parse(linkUrlString) : null, - ObjectWrapper.unwrap(linkText, String.class), - ObjectWrapper.unwrap(titleOrAltText, String.class), - srcUrlString != null ? Uri.parse(srcUrlString) : null, isImage, isVideo, - canDownload, contextMenuParams); - for (TabCallback callback : mCallbacks) { - callback.showContextMenu(params); - } - } - - @Override - public void onTabModalStateChanged(boolean isTabModalShowing) { - StrictModeWorkaround.apply(); - for (TabCallback callback : mCallbacks) { - callback.onTabModalStateChanged(isTabModalShowing); - } - } - - @Override - public void onTitleUpdated(IObjectWrapper title) { - StrictModeWorkaround.apply(); - String titleString = ObjectWrapper.unwrap(title, String.class); - for (TabCallback callback : mCallbacks) { - callback.onTitleUpdated(titleString); - } - } - - @Override - public void bringTabToFront() { - StrictModeWorkaround.apply(); - for (TabCallback callback : mCallbacks) { - callback.bringTabToFront(); - } - } - - @Override - public void onBackgroundColorChanged(int color) { - StrictModeWorkaround.apply(); - for (TabCallback callback : mCallbacks) { - callback.onBackgroundColorChanged(color); - } - } - - @Override - public void onScrollNotification( - @ScrollNotificationType int notificationType, float currentScrollRatio) { - StrictModeWorkaround.apply(); - for (TabCallback callback : mCallbacks) { - callback.onScrollNotification(notificationType, currentScrollRatio); - } - } - - @Override - public void onVerticalScrollOffsetChanged(int value) { - StrictModeWorkaround.apply(); - for (ScrollOffsetCallback callback : mScrollOffsetCallbacks) { - callback.onVerticalScrollOffsetChanged(value); - } - } - - @Override - public void onActionItemClicked( - int actionModeItemType, IObjectWrapper selectedStringWrapper) { - StrictModeWorkaround.apply(); - String selectedString = ObjectWrapper.unwrap(selectedStringWrapper, String.class); - if (mActionModeCallback != null) { - mActionModeCallback.onActionItemClicked(actionModeItemType, selectedString); - } - } - - @Override - public void onVerticalOverscroll(float accumulatedOverscrollY) { - StrictModeWorkaround.apply(); - for (TabCallback callback : mCallbacks) { - callback.onVerticalOverscroll(accumulatedOverscrollY); - } - } - - @Override - public void onPostMessage(String message, String origin) { - StrictModeWorkaround.apply(); - mTabProxy.onPostMessage(message, origin); - } - } - - private static final class ErrorPageCallbackClientImpl extends IErrorPageCallbackClient.Stub { - private final ErrorPageCallback mCallback; - - ErrorPageCallbackClientImpl(ErrorPageCallback callback) { - mCallback = callback; - } - - public ErrorPageCallback getCallback() { - return mCallback; - } - - @Override - public boolean onBackToSafety() { - StrictModeWorkaround.apply(); - return mCallback.onBackToSafety(); - } - @Override - public String getErrorPageContent(IClientNavigation navigation) { - StrictModeWorkaround.apply(); - ErrorPage errorPage = mCallback.getErrorPage((Navigation) navigation); - return errorPage == null ? null : errorPage.htmlContent; - } - } - - private static final class FullscreenCallbackClientImpl extends IFullscreenCallbackClient.Stub { - private FullscreenCallback mCallback; - - /* package */ FullscreenCallbackClientImpl(FullscreenCallback callback) { - mCallback = callback; - } - - public FullscreenCallback getCallback() { - return mCallback; - } - - @Override - public void enterFullscreen(IObjectWrapper exitFullscreenWrapper) { - StrictModeWorkaround.apply(); - ValueCallback<Void> exitFullscreenCallback = (ValueCallback<Void>) ObjectWrapper.unwrap( - exitFullscreenWrapper, ValueCallback.class); - mCallback.onEnterFullscreen(() -> exitFullscreenCallback.onReceiveValue(null)); - } - - @Override - public void exitFullscreen() { - StrictModeWorkaround.apply(); - mCallback.onExitFullscreen(); - } - } - - private static final class GoogleAccountsCallbackClientImpl - extends IGoogleAccountsCallbackClient.Stub { - private GoogleAccountsCallback mCallback; - - GoogleAccountsCallbackClientImpl(GoogleAccountsCallback callback) { - mCallback = callback; - } - - @Override - public void onGoogleAccountsRequest( - int serviceType, String email, String continueUrl, boolean isSameTab) { - StrictModeWorkaround.apply(); - mCallback.onGoogleAccountsRequest(new GoogleAccountsParams( - serviceType, email, Uri.parse(continueUrl), isSameTab)); - } - - @Override - public String getGaiaId() { - StrictModeWorkaround.apply(); - return mCallback.getGaiaId(); - } - } - - private static final class ExternalIntentInIncognitoCallbackClientImpl - extends IExternalIntentInIncognitoCallbackClient.Stub { - private ExternalIntentInIncognitoCallback mCallback; - - ExternalIntentInIncognitoCallbackClientImpl(ExternalIntentInIncognitoCallback callback) { - mCallback = callback; - } - - @Override - public void onExternalIntentInIncognito(IObjectWrapper onUserDecisionWrapper) { - StrictModeWorkaround.apply(); - ValueCallback<Integer> valueCallback = - ObjectWrapper.unwrap(onUserDecisionWrapper, ValueCallback.class); - - mCallback.onExternalIntentInIncognito( - (userDecision) -> valueCallback.onReceiveValue(userDecision)); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/TabCallback.java b/weblayer/public/java/org/chromium/weblayer/TabCallback.java deleted file mode 100644 index 469add6..0000000 --- a/weblayer/public/java/org/chromium/weblayer/TabCallback.java +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; - -import androidx.annotation.NonNull; - -/** - * Informed of interesting events that happen during the lifetime of a Tab. - */ -abstract class TabCallback { - /** - * The Uri that should be displayed in the location-bar has updated. - * - * @param uri The new user-visible uri. - */ - public void onVisibleUriChanged(@NonNull Uri uri) {} - - /** - * Triggered when the render process dies, either due to crash or killed by the system to - * reclaim memory. - */ - public void onRenderProcessGone() {} - - /** - * Triggered when a context menu should be displayed. - */ - public void showContextMenu(@NonNull ContextMenuParams params) {} - - /** - * Triggered when a tab's contents have been rendered inactive due to a modal overlay, or active - * due to the dismissal of a modal overlay (dialog/bubble/popup). - * - * @param isTabModalShowing true when a dialog is blocking interaction with the web contents. - */ - public void onTabModalStateChanged(boolean isTabModalShowing) {} - - /** - * Called when the title of this tab changes. Note before the page sets a title, the title may - * be a portion of the Uri. - * @param title New title of this tab. - */ - public void onTitleUpdated(@NonNull String title) {} - - /** - * Called when user attention should be brought to this tab. This should cause the tab, its - * containing Activity, and the task to be foregrounded. - */ - public void bringTabToFront() {} - - /** - * Called when then background color of the page changes. The background color typically comes - * from css background-color, but heuristics and blending may be used depending upon the page. - * This is mostly useful for filling in gaps around the web page during resize, but it will - * not necessarily match the full background of the page. - * @param color The new ARGB color of the page background. - */ - public void onBackgroundColorChanged(int color) {} - - /** - * Notification for scroll of the root of the web page. This is generally sent as a result of - * displaying web page. See ScrollNotificationType for more details. ScrollNotificationType is - * meant to be extensible and new types may be added in the future. Embedder should take care - * to allow unknown values. - * @param notificationType type of notification. See ScrollNotificationType for more details. - * @param currentScrollRatio value in [0, 1] indicating the current scroll ratio. For example - * a web page that is 200 pixels, has a viewport of height 50 pixels - * and a scroll offset of 50 pixels will have a ratio of 0.5. - */ - public void onScrollNotification( - @ScrollNotificationType int notificationType, float currentScrollRatio) {} - - /** - * Notification for vertical overscroll. This happens when user tries to touch scroll beyond - * the scroll bounds, or when a fling animation hits scroll bounds. - * A few caveats when using this callback: - * * This should be considered independent and unordered with respect to other scroll callbacks - * such as `onScrollNotification` or `ScrollOffsetCallback.onVerticalScrollOffsetChanged`. - * Client should not assume a certain order between this and other scroll notifications. - * * The value is accumulated scroll, so the magnitude of the value only goes up for a single - * overscroll gesture. However this is not enough to distinguish between two overscroll - * gestures and client must listen to touch events to make such distinction. Similarly there - * is no "end overscroll" event, and client is expected to listen to touch events as well. - * Added in M101. - * @param accumulatedOverscrollY negative for when trying to scroll beyond offset 0, positive - * for when trying to scroll beyond bottom scroll bounds. - */ - public void onVerticalOverscroll(float accumulatedOverscrollY) {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/TabInitializationCallback.java b/weblayer/public/java/org/chromium/weblayer/TabInitializationCallback.java deleted file mode 100644 index a0020c6b3..0000000 --- a/weblayer/public/java/org/chromium/weblayer/TabInitializationCallback.java +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * An interface for observing events related to tab initialization on startup, either a new tab or - * restoring previous tabs basedon on a persistence ID. - */ -abstract class TabInitializationCallback { - /** - * Called when WebLayer has finished the tab initialization. - */ - public void onTabInitializationCompleted() {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/TabListCallback.java b/weblayer/public/java/org/chromium/weblayer/TabListCallback.java deleted file mode 100644 index c05b18a..0000000 --- a/weblayer/public/java/org/chromium/weblayer/TabListCallback.java +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * An interface for observing changes to the set of tabs in a browser. - */ -abstract class TabListCallback { - /** - * The active tab has changed. - * - * @param activeTab The newly active tab, null if no tab is active. - */ - public void onActiveTabChanged(@Nullable Tab activeTab) {} - - /** - * A tab was added to the Browser. - * - * @param tab The tab that was added. - */ - public void onTabAdded(@NonNull Tab tab) {} - - /** - * A tab was removed from the Browser. - * - * WARNING: this is *not* called when the Browser is destroyed. See {@link - * #onWillDestroyBrowserAndAllTabs} for more. - * - * @param tab The tab that was removed. - */ - public void onTabRemoved(@NonNull Tab tab) {} - - /** - * Called when the Fragment the Browser is associated with is about to be destroyed. After this - * call the Browser and all Tabs are destroyed and can not be used. - */ - public void onWillDestroyBrowserAndAllTabs() {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/TabManagerDelegate.java b/weblayer/public/java/org/chromium/weblayer/TabManagerDelegate.java deleted file mode 100644 index ede13f33..0000000 --- a/weblayer/public/java/org/chromium/weblayer/TabManagerDelegate.java +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.ITabCallback; -import org.chromium.webengine.interfaces.ITabListObserverDelegate; -import org.chromium.webengine.interfaces.ITabManagerDelegate; -import org.chromium.webengine.interfaces.ITabParams; - -class TabManagerDelegate extends ITabManagerDelegate.Stub { - private Handler mHandler = new Handler(Looper.getMainLooper()); - - private Browser mBrowser; - - private WebFragmentTabListDelegate mTabListDelegate = new WebFragmentTabListDelegate(); - - TabManagerDelegate(Browser browser) { - mBrowser = browser; - - browser.registerTabListCallback(mTabListDelegate); - } - - @Override - public void setTabListObserverDelegate(ITabListObserverDelegate tabListObserverDelegate) { - mTabListDelegate.setObserver(tabListObserverDelegate); - } - - @Override - public void notifyInitialTabs() { - mHandler.post(() -> { - mTabListDelegate.notifyInitialTabs(mBrowser.getTabs(), mBrowser.getActiveTab()); - }); - } - - @Override - public void getActiveTab(ITabCallback tabCallback) { - mHandler.post(() -> { - Tab activeTab = mBrowser.getActiveTab(); - try { - if (activeTab != null) { - ITabParams tabParams = TabParams.buildParcelable(activeTab); - tabCallback.onResult(tabParams); - } else { - tabCallback.onResult(null); - } - } catch (RemoteException e) { - } - }); - } - - @Override - public void createTab(ITabCallback callback) { - mHandler.post(() -> { - Tab newTab = mBrowser.createTab(); - try { - callback.onResult(TabParams.buildParcelable(newTab)); - } catch (RemoteException e) { - } - }); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/TabNavigationControllerProxy.java b/weblayer/public/java/org/chromium/weblayer/TabNavigationControllerProxy.java deleted file mode 100644 index b839db88..0000000 --- a/weblayer/public/java/org/chromium/weblayer/TabNavigationControllerProxy.java +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.INavigationObserverDelegate; -import org.chromium.webengine.interfaces.ITabNavigationControllerProxy; - -class TabNavigationControllerProxy extends ITabNavigationControllerProxy.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private WebFragmentNavigationDelegate mNavigationObserverDelegate = - new WebFragmentNavigationDelegate(); - private final NavigationController mNavigationController; - - TabNavigationControllerProxy(NavigationController navigationController) { - mNavigationController = navigationController; - - mNavigationController.registerNavigationCallback(mNavigationObserverDelegate); - } - - @Override - public void navigate(String uri) { - mHandler.post(() -> { - NavigateParams.Builder navigateParamsBuilder = - new NavigateParams.Builder().disableIntentProcessing(); - mNavigationController.navigate(Uri.parse(uri), navigateParamsBuilder.build()); - }); - } - - @Override - public void goBack() { - mHandler.post(() -> { mNavigationController.goBack(); }); - } - - @Override - public void goForward() { - mHandler.post(() -> { mNavigationController.goForward(); }); - } - - @Override - public void canGoBack(IBooleanCallback callback) { - mHandler.post(() -> { - try { - callback.onResult(mNavigationController.canGoBack()); - } catch (RemoteException e) { - } - }); - } - - @Override - public void canGoForward(IBooleanCallback callback) { - mHandler.post(() -> { - try { - callback.onResult(mNavigationController.canGoForward()); - } catch (RemoteException e) { - } - }); - } - - @Override - public void reload() { - mHandler.post(() -> { mNavigationController.reload(); }); - } - - @Override - public void stop() { - mHandler.post(() -> { mNavigationController.stop(); }); - } - - @Override - public void setNavigationObserverDelegate(INavigationObserverDelegate navigationDelegate) { - mNavigationObserverDelegate.setObserver(navigationDelegate); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/TabParams.java b/weblayer/public/java/org/chromium/weblayer/TabParams.java deleted file mode 100644 index bdea25c..0000000 --- a/weblayer/public/java/org/chromium/weblayer/TabParams.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -import org.chromium.webengine.interfaces.ITabParams; - -/** - * Parameters for {@link Tab}. - */ -class TabParams { - static ITabParams buildParcelable(@NonNull Tab tab) { - ITabParams parcel = new ITabParams(); - parcel.tabProxy = tab.getTabProxy(); - parcel.tabGuid = tab.getGuid(); - parcel.uri = tab.getUri(); - parcel.navigationControllerProxy = tab.getTabNavigationControllerProxy(); - - return parcel; - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/TabProxy.java b/weblayer/public/java/org/chromium/weblayer/TabProxy.java deleted file mode 100644 index 4a337d2c4..0000000 --- a/weblayer/public/java/org/chromium/weblayer/TabProxy.java +++ /dev/null
@@ -1,184 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.ExceptionType; -import org.chromium.webengine.interfaces.IFullscreenCallbackDelegate; -import org.chromium.webengine.interfaces.IPostMessageCallback; -import org.chromium.webengine.interfaces.IStringCallback; -import org.chromium.webengine.interfaces.ITabObserverDelegate; -import org.chromium.webengine.interfaces.ITabProxy; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class acts as a proxy between a Tab object in the embedding app - * and the Tab implementation in WebLayer. - * A (@link TabProxy} is owned by the {@link Tab}. - */ -class TabProxy extends ITabProxy.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private int mTabId; - private String mGuid; - - private WebFragmentTabDelegate mTabObserverDelegate = new WebFragmentTabDelegate(); - private WebFragmentNavigationDelegate mNavigationObserverDelegate = - new WebFragmentNavigationDelegate(); - private FullscreenCallbackDelegate mFullscreenCallbackDelegate = - new FullscreenCallbackDelegate(); - private FaviconFetcher mFaviconFetcher; - - // Only use one callback for all the message event listeners. This is to avoid sending the same - // message over multiple times. The message can then be proxied to all valid listeners. - private IPostMessageCallback mMessageEventListenerCallback; - - // The union of origins allowed by all the listeners. It may contain duplicates. - private ArrayList<String> mAllowedOriginsForPostMessage = new ArrayList<>(); - - TabProxy(Tab tab) { - mTabId = tab.getId(); - mGuid = tab.getGuid(); - - tab.registerTabCallback(mTabObserverDelegate); - tab.setFullscreenCallback(mFullscreenCallbackDelegate); - mFaviconFetcher = tab.createFaviconFetcher(new FaviconCallback() { - @Override - public void onFaviconChanged(Bitmap favicon) { - mTabObserverDelegate.notifyFaviconChanged(favicon); - } - }); - } - - void invalidate() { - mTabId = -1; - mGuid = null; - - mTabObserverDelegate = null; - mNavigationObserverDelegate = null; - mFaviconFetcher.destroy(); - mFaviconFetcher = null; - } - - boolean isValid() { - return mGuid != null; - } - - private Tab getTab() { - Tab tab = Tab.getTabById(mTabId); - if (tab == null) { - // TODO(swestphal): Raise exception. - } - return tab; - } - - @Override - public void setActive() { - mHandler.post(() -> { - Tab tab = getTab(); - tab.getBrowser().setActiveTab(tab); - }); - } - - @Override - public void close() { - mHandler.post(() -> { - getTab().dispatchBeforeUnloadAndClose(); - invalidate(); - }); - } - - @Override - public void executeScript(String script, boolean useSeparateIsolate, IStringCallback callback) { - mHandler.post(() -> { - try { - getTab().executeScript(script, useSeparateIsolate, - new org.chromium.weblayer_private.interfaces.IStringCallback.Stub() { - @Override - public void onResult(String result) { - try { - callback.onResult(result); - } catch (RemoteException e) { - } - } - @Override - public void onException(@ExceptionType int type, String msg) { - try { - callback.onException(ExceptionHelper.convertType(type), msg); - } catch (RemoteException e) { - } - } - }); - } catch (RuntimeException e) { - try { - callback.onException(ExceptionType.UNKNOWN, e.getMessage()); - } catch (RemoteException re) { - } - } - }); - } - - @Override - public void setTabObserverDelegate(ITabObserverDelegate tabObserverDelegate) { - mTabObserverDelegate.setObserver(tabObserverDelegate); - } - - @Override - public void postMessage(String message, String targetOrigin) { - mHandler.post(() -> { getTab().postMessage(message, targetOrigin); }); - } - - @Override - public void createMessageEventListener( - IPostMessageCallback callback, List<String> allowedOrigins) { - assert mMessageEventListenerCallback == null; - mMessageEventListenerCallback = callback; - mAllowedOriginsForPostMessage.addAll(allowedOrigins); - } - - @Override - public void addMessageEventListener(List<String> allowedOrigins) { - mAllowedOriginsForPostMessage.addAll(allowedOrigins); - } - - @Override - public void removeMessageEventListener(List<String> allowedOrigins) { - for (String origin : allowedOrigins) { - // Remove one instance of |origin|. Other listeners may have registered with the same - // |origin| and needs to be left in |mAllowedOriginsForPostMessage|. - boolean didRemove = mAllowedOriginsForPostMessage.remove(origin); - assert didRemove; - } - } - - void onPostMessage(String message, String origin) { - if (mMessageEventListenerCallback == null) { - return; - } - - if (!mAllowedOriginsForPostMessage.contains("*") - && !mAllowedOriginsForPostMessage.contains(origin)) { - // No listener was attached to receive this message. Drop it. - return; - } - - try { - mMessageEventListenerCallback.onPostMessage(message, origin); - } catch (RemoteException e) { - } - } - - @Override - public void setFullscreenCallbackDelegate( - IFullscreenCallbackDelegate fullscreenCallbackDelegate) { - mFullscreenCallbackDelegate.setDelegate(fullscreenCallbackDelegate); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/ThreadCheck.java b/weblayer/public/java/org/chromium/weblayer/ThreadCheck.java deleted file mode 100644 index df4800e..0000000 --- a/weblayer/public/java/org/chromium/weblayer/ThreadCheck.java +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.Looper; -import android.util.AndroidRuntimeException; - -/* package */ class ThreadCheck { - /* package */ static void ensureOnUiThread() { - if (Looper.getMainLooper() != Looper.myLooper()) { - throw new AndroidRuntimeException("This method needs to be called on the main thread"); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/UnsupportedVersionException.java b/weblayer/public/java/org/chromium/weblayer/UnsupportedVersionException.java deleted file mode 100644 index 58bb536..0000000 --- a/weblayer/public/java/org/chromium/weblayer/UnsupportedVersionException.java +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * Error thrown if client and implementation versions are not compatible. - */ -class UnsupportedVersionException extends RuntimeException { - /** - * Constructs a new exception with the specified version. - */ - public UnsupportedVersionException(String implementationVersion) { - super("Unsupported WebLayer version, client version " - + WebLayerClientVersionConstants.PRODUCT_VERSION - + " is not supported by implementation version " + implementationVersion); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/UserIdentityCallback.java b/weblayer/public/java/org/chromium/weblayer/UserIdentityCallback.java deleted file mode 100644 index 894cf8d..0000000 --- a/weblayer/public/java/org/chromium/weblayer/UserIdentityCallback.java +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; - -/** - * Used to provide details about the current user's identity. - * - * If this callback is implemented and set on {@link Profile}, the information is used to better - * organize contact details in the navigator.contacts UI as well as by Autofill Assistant. - */ -abstract class UserIdentityCallback { - /** - * The current user's email address. If no user is signed in or the email is currently - * unavailable, this should return an empty string. - */ - public @NonNull String getEmail() { - return new String(); - } - - /** - * Returns the full name of the current user, or empty if the user is signed out. This can - * be provided on a best effort basis if the name is not available immediately. - */ - public @NonNull String getFullName() { - return new String(); - } - - /** - * Called to retrieve the signed-in user's avatar. - * @param desiredSize the size the avatar will be displayed at, in raw pixels. If a different - * size avatar is returned, WebLayer will scale the returned image. - * @param avatarLoadedCallback to be called with the avatar when it is available (synchronously - * or asynchronously). Until such time that it's called, WebLayer will fall back to a - * monogram based on {@link getFullName()}, e.g. encircled "JD" for "Jill Doe". This - * will no-op if the associated {@link Profile} object is destroyed before this is - * called. - */ - public void getAvatar(int desiredSize, @NonNull ValueCallback<Bitmap> avatarLoadedCallback) {} -}
diff --git a/weblayer/public/java/org/chromium/weblayer/VerifiesOnO.java b/weblayer/public/java/org/chromium/weblayer/VerifiesOnO.java deleted file mode 100644 index 2738299..0000000 --- a/weblayer/public/java/org/chromium/weblayer/VerifiesOnO.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The annotated method or class verifies on O, but not below. - * - * The annotated method (or methods on the annotated class) are guaranteed to not be inlined by R8 - * on builds targeted below O. This prevents class verification errors (which results in a very slow - * retry-verification-at-runtime) from spreading into other classes on these lower versions. - * - * Note: this is the WebLayer client library version of the annotation from - * org.chromium.base.annotations. - */ -@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.CLASS) -/* package */ @interface VerifiesOnO {}
diff --git a/weblayer/public/java/org/chromium/weblayer/VerifiesOnR.java b/weblayer/public/java/org/chromium/weblayer/VerifiesOnR.java deleted file mode 100644 index 417b24e..0000000 --- a/weblayer/public/java/org/chromium/weblayer/VerifiesOnR.java +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The annotated method or class verifies on R, but not below. - * - * The annotated method (or methods on the annotated class) are guaranteed to not be inlined by R8 - * on builds targeted below R. This prevents class verification errors (which results in a very slow - * retry-verification-at-runtime) from spreading into other classes on these lower versions. - * - * Note: this is the WebLayer client library version of the annotation from - * org.chromium.base.annotations. - */ -@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.CLASS) -/* package */ @interface VerifiesOnR {}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebEngineDelegate.java b/weblayer/public/java/org/chromium/weblayer/WebEngineDelegate.java deleted file mode 100644 index f9875ea..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebEngineDelegate.java +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; - -import org.chromium.webengine.interfaces.IBooleanCallback; -import org.chromium.webengine.interfaces.IWebEngineDelegate; -import org.chromium.webengine.interfaces.IWebEngineDelegateClient; -import org.chromium.webengine.interfaces.IWebEngineParams; -import org.chromium.weblayer_private.interfaces.BrowserFragmentArgs; - -import java.util.ArrayList; - -/** - * Class to delegate between a webengine.WebEngine and its weblayer.Browser counter part. - */ -class WebEngineDelegate extends IWebEngineDelegate.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private Browser mBrowser; - - WebEngineDelegate(Browser browser) { - mBrowser = browser; - } - - static void create(Context context, WebLayer webLayer, IWebEngineParams params, - IWebEngineDelegateClient client) { - new Handler(Looper.getMainLooper()).post(() -> { - Browser browser = new Browser(webLayer.createBrowser(context, bundleParams(params))); - - WebFragmentEventsDelegate fragmentEventsDelegate = - new WebFragmentEventsDelegate(context, browser.connectFragment()); - - CookieManagerDelegate cookieManagerDelegate = - new CookieManagerDelegate(browser.getProfile().getCookieManager()); - TabManagerDelegate tabManagerDelegate = new TabManagerDelegate(browser); - - WebEngineDelegate webEngineDelegate = new WebEngineDelegate(browser); - - browser.registerTabInitializationCallback(new TabInitializationCallback() { - @Override - public void onTabInitializationCompleted() { - new Handler(Looper.getMainLooper()).post(() -> { - try { - client.onDelegatesReady(webEngineDelegate, fragmentEventsDelegate, - tabManagerDelegate, cookieManagerDelegate); - } catch (RemoteException e) { - throw new RuntimeException("Failed to initialize WebEngineDelegate", e); - } - }); - } - }); - - browser.initializeState(); - }); - } - - private static Bundle bundleParams(IWebEngineParams params) { - String profileName = Profile.sanitizeProfileName(params.profileName); - boolean isIncognito = params.isIncognito || "".equals(profileName); - boolean isExternalIntentsEnabled = params.isExternalIntentsEnabled; - // Support for named incognito profiles was added in 87. Checking is done in - // WebFragment, as this code should not trigger loading WebLayer. - Bundle args = new Bundle(); - args.putString(BrowserFragmentArgs.PROFILE_NAME, profileName); - if (params.persistenceId != null) { - args.putString(BrowserFragmentArgs.PERSISTENCE_ID, params.persistenceId); - } - if (params.allowedOrigins != null) { - args.putStringArrayList( - BrowserFragmentArgs.ALLOWED_ORIGINS, (ArrayList<String>) params.allowedOrigins); - } - args.putBoolean(BrowserFragmentArgs.IS_INCOGNITO, isIncognito); - args.putBoolean(BrowserFragmentArgs.IS_EXTERNAL_INTENTS_ENABLED, isExternalIntentsEnabled); - args.putBoolean(BrowserFragmentArgs.USE_VIEW_MODEL, false); - - return args; - } - - @Override - public void tryNavigateBack(IBooleanCallback callback) { - mHandler.post(() -> { - mBrowser.tryNavigateBack(didNavigate -> { - try { - callback.onResult(didNavigate); - } catch (RemoteException e) { - } - }); - }); - } - - @Override - public void shutdown() { - mHandler.post(() -> { - // This is for the weblayer.Browser / weblayer_private.BrowserImpl which has a lifetime - // that exceeds the Fragment, onDestroy only destroys the Fragment UI. - // TODO(swestphal): Check order. - mBrowser.prepareForDestroy(); - mBrowser.shutdown(); - mBrowser.onDestroyed(); - mBrowser = null; - }); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/WebFragmentCreateParams.java b/weblayer/public/java/org/chromium/weblayer/WebFragmentCreateParams.java deleted file mode 100644 index 219f0890..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebFragmentCreateParams.java +++ /dev/null
@@ -1,132 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -class WebFragmentCreateParams { - private boolean mIncognito; - @Nullable - private String mProfileName; - @Nullable - private String mPersistenceId; - private boolean mUseViewModel; - - /** - * A Builder class to help create WebFragmentCreateParams. - */ - public static final class Builder { - @NonNull - private WebFragmentCreateParams mParams; - - /** - * Constructs a new Builder. - */ - public Builder() { - mParams = new WebFragmentCreateParams(); - } - - /** - * Builds the WebFragmentCreateParams. - */ - @NonNull - public WebFragmentCreateParams build() { - return mParams; - } - - /** - * Sets whether the profile is incognito. - * - * Support for incognito fragments with a non-null and non-empty profile name was added - * in 88. Attempting to use a fragment with a non-null and non-empty profile name earlier - * than 88 will result in an exception. - * - * @param incognito Whether the profile should be incognito. - */ - @NonNull - public Builder setIsIncognito(boolean incognito) { - mParams.mIncognito = incognito; - return this; - } - - /** - * - * Sets the name of the profile. Null or empty string implicitly creates an incognito - * profile. If {@code profile} must only contain alphanumeric and underscore characters - * since it will be used as a directory name in the file system. - * - * @param The name of the profile. - */ - @NonNull - public Builder setProfileName(@Nullable String name) { - mParams.mProfileName = name; - return this; - } - - /** - * Sets the persistence id, which uniquely identifies the Browser for saving the set of tabs - * and navigations. A value of null does not save/restore any state. A non-null value - * results in asynchronously restoring the tabs and navigations. Supplying a non-null value - * means the Browser initially has no tabs (until restore is complete). - * - * @param id The id for persistence. - */ - @NonNull - public Builder setPersistenceId(@Nullable String id) { - mParams.mPersistenceId = id; - return this; - } - - /** - * Sets whether the Browser should be stored in a ViewModel owned by the Fragment. A value - * of true results in the Browser not being recreated during configuration changes. This is - * a replacement for {@code Fragment#setRetainInstance()}. - * - * @param useViewModel Whether a ViewModel should be used. - */ - @NonNull - public Builder setUseViewModel(boolean useViewModel) { - mParams.mUseViewModel = useViewModel; - return this; - } - } - - /** - * Returns whether the Browser is incognito. - * - * @return True if the profile is incognito. - */ - public boolean isIncognito() { - return mIncognito; - } - - /** - * Returns the name of a profile. Null or empty is implicitly mapped to incognito. - * - * @return The profile name. - */ - @Nullable - public String getProfileName() { - return mProfileName; - } - - /** - * Returns the persisted id for the browser. - * - * @return The persistence id. - */ - @Nullable - public String getPersistenceId() { - return mPersistenceId; - } - - /** - * Whether ViewModel should be used. - */ - public boolean getUseViewModel() { - return mUseViewModel; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebFragmentEventHandler.java b/weblayer/public/java/org/chromium/weblayer/WebFragmentEventHandler.java deleted file mode 100644 index c41de19..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebFragmentEventHandler.java +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import org.chromium.weblayer_private.interfaces.IRemoteFragment; - -/** - * Class to handle events forwarded by WebFragmentEventDelegate. - */ -final class WebFragmentEventHandler extends RemoteFragmentEventHandler { - public WebFragmentEventHandler(IRemoteFragment remoteFragment) { - super(remoteFragment); - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebFragmentEventsDelegate.java b/weblayer/public/java/org/chromium/weblayer/WebFragmentEventsDelegate.java deleted file mode 100644 index 6a731fe..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebFragmentEventsDelegate.java +++ /dev/null
@@ -1,165 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.RemoteException; -import android.view.SurfaceControlViewHost; -import android.view.WindowManager; - -import androidx.fragment.app.Fragment; - -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegate; -import org.chromium.webengine.interfaces.IWebFragmentEventsDelegateClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.IRemoteFragment; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -/** - * This class proxies Fragment Lifecycle events from the WebFragment to - * the WebLayer implementation. - */ -class WebFragmentEventsDelegate extends IWebFragmentEventsDelegate.Stub { - private final Handler mHandler = new Handler(Looper.getMainLooper()); - - private Context mContext; - private WebFragmentEventHandler mEventHandler; - - private WebFragmentTabListDelegate mTabListDelegate; - - private IWebFragmentEventsDelegateClient mClient; - private SurfaceControlViewHost mSurfaceControlViewHost; - - WebFragmentEventsDelegate(Context context, IRemoteFragment remoteFragment) { - ThreadCheck.ensureOnUiThread(); - - mContext = context; - mEventHandler = new WebFragmentEventHandler(remoteFragment); - } - - @Override - public void setClient(IWebFragmentEventsDelegateClient client) { - mClient = client; - } - - @Override - public void attachViewHierarchy(IBinder hostToken) { - mHandler.post(() -> attachViewHierarchyOnUi(hostToken)); - } - - private void attachViewHierarchyOnUi(IBinder hostToken) { - WindowManager window = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); - - assert mSurfaceControlViewHost == null; - mSurfaceControlViewHost = - new SurfaceControlViewHost(mContext, window.getDefaultDisplay(), hostToken); - - mEventHandler.setSurfaceControlViewHost(mSurfaceControlViewHost); - try { - mClient.onSurfacePackageReady(mSurfaceControlViewHost.getSurfacePackage()); - } catch (RemoteException e) { - } - } - - @Override - public void retrieveContentViewRenderView() { - mHandler.post(() -> { - try { - mClient.onContentViewRenderViewReady( - ObjectWrapper.wrap(mEventHandler.getContentViewRenderView())); - } catch (RemoteException e) { - } - }); - } - - @Override - public void resizeView(int width, int height) { - mHandler.post(() -> { - if (mSurfaceControlViewHost != null) { - mSurfaceControlViewHost.relayout(width, height); - } - }); - } - - @Override - public void onAttach() { - mHandler.post(() -> mEventHandler.onAttach(mContext, null)); - } - - @Override - public void onAttachWithContext(IObjectWrapper context, IObjectWrapper fragment) { - mHandler.post(() -> mEventHandler.onAttach(ObjectWrapper.unwrap(context, Context.class), - ObjectWrapper.unwrap(fragment, Fragment.class))); - } - - @Override - public void onCreate() { - mHandler.post(() -> { mEventHandler.onCreate(); }); - } - - @Override - public void onDestroy() { - mHandler.post(() -> mEventHandler.onDestroy()); - } - - @Override - public void onDetach() { - mHandler.post(() -> { - mEventHandler.onDetach(); - if (mSurfaceControlViewHost != null) { - mSurfaceControlViewHost.release(); - mSurfaceControlViewHost = null; - } - }); - } - - @Override - public void onStart() { - mHandler.post(() -> { mEventHandler.onStart(); }); - } - - @Override - public void onStop() { - mHandler.post(() -> mEventHandler.onStop()); - } - - @Override - public void onResume() { - mHandler.post(() -> mEventHandler.onResume()); - } - - @Override - public void onPause() { - mHandler.post(() -> mEventHandler.onPause()); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, IObjectWrapper intent) { - mHandler.post(() -> mEventHandler.onActivityResult(requestCode, resultCode, - ObjectWrapper.unwrap(intent, Intent.class))); - } - - /** - * Set the minimum surface size of this BrowserFragment instance. - * Setting this avoids expensive surface resize for a fragment view resize that is within the - * minimum size. The trade off is the additional memory and power needed for the larger - * surface. For example, for a browser use case, it's likely worthwhile to set the minimum - * surface size to the screen size to avoid surface resize when entering and exiting fullscreen. - * It is safe to call this before Views are initialized. - * Note Android does have a max size limit on Surfaces which applies here as well; this - * generally should not be larger than the device screen size. - * Note the surface size is increased to the layout size only if both the width and height are - * no larger than the minimum surface size. No adjustment is made if the surface size is larger - * than the minimum size in one dimension and smaller in the other dimension. - */ - @Override - public void setMinimumSurfaceSize(int width, int height) { - mHandler.post(() -> mEventHandler.setMinimumSurfaceSize(width, height)); - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/WebFragmentNavigationDelegate.java b/weblayer/public/java/org/chromium/weblayer/WebFragmentNavigationDelegate.java deleted file mode 100644 index d9522303..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebFragmentNavigationDelegate.java +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import org.chromium.webengine.interfaces.INavigationObserverDelegate; - -/** - * This class acts as a proxy between the Tab navigation events happening in - * weblayer and the NavigationObserverDelegate in webengine. - */ -class WebFragmentNavigationDelegate extends NavigationCallback { - private INavigationObserverDelegate mNavigationObserver; - - void setObserver(INavigationObserverDelegate observer) { - mNavigationObserver = observer; - } - - @Override - public void onNavigationStarted(@NonNull Navigation navigation) { - maybeRunOnNavigationObserver(observer -> { - observer.notifyNavigationStarted(WebFragmentNavigationParams.create(navigation)); - }); - } - - @Override - public void onNavigationRedirected(@NonNull Navigation navigation) { - maybeRunOnNavigationObserver(observer -> { - observer.notifyNavigationRedirected(WebFragmentNavigationParams.create(navigation)); - }); - } - - @Override - public void onNavigationCompleted(@NonNull Navigation navigation) { - maybeRunOnNavigationObserver(observer -> { - observer.notifyNavigationCompleted(WebFragmentNavigationParams.create(navigation)); - }); - } - - @Override - public void onNavigationFailed(@NonNull Navigation navigation) { - maybeRunOnNavigationObserver(observer -> { - observer.notifyNavigationFailed(WebFragmentNavigationParams.create(navigation)); - }); - } - - @Override - public void onLoadProgressChanged(double progress) { - maybeRunOnNavigationObserver(observer -> observer.notifyLoadProgressChanged(progress)); - } - - private interface OnNavigationObserverCallback { - void run(INavigationObserverDelegate navigationObserver) throws RemoteException; - } - - private void maybeRunOnNavigationObserver(OnNavigationObserverCallback callback) { - if (mNavigationObserver != null) { - try { - callback.run(mNavigationObserver); - } catch (RemoteException e) { - } - } - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/WebFragmentNavigationParams.java b/weblayer/public/java/org/chromium/weblayer/WebFragmentNavigationParams.java deleted file mode 100644 index fb92d99..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebFragmentNavigationParams.java +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import org.chromium.webengine.interfaces.INavigationParams; - -/** - * This class is a helper class to create {@link INavigationParams}-parcelable. - */ -class WebFragmentNavigationParams { - private WebFragmentNavigationParams() {} - - public static INavigationParams create(Navigation navigation) { - INavigationParams params = new INavigationParams(); - params.uri = navigation.getUri(); - params.statusCode = navigation.getHttpStatusCode(); - params.isSameDocument = navigation.isSameDocument(); - return params; - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/WebFragmentTabDelegate.java b/weblayer/public/java/org/chromium/weblayer/WebFragmentTabDelegate.java deleted file mode 100644 index 9e69cdd..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebFragmentTabDelegate.java +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.webengine.interfaces.ITabObserverDelegate; - -/** - * This class acts as a proxy between the Tab events happening in - * weblayer and the TabObserverDelegate in webengine. - */ -class WebFragmentTabDelegate extends TabCallback { - private ITabObserverDelegate mTabObserver; - - void setObserver(ITabObserverDelegate observer) { - mTabObserver = observer; - } - - @Override - public void onVisibleUriChanged(@NonNull Uri uri) { - maybeRunOnTabObserver(observer -> { observer.notifyVisibleUriChanged(uri.toString()); }); - } - - @Override - public void onRenderProcessGone() { - maybeRunOnTabObserver(observer -> { observer.notifyRenderProcessGone(); }); - } - - @Override - public void onTitleUpdated(@NonNull String title) { - maybeRunOnTabObserver(observer -> { observer.notifyTitleUpdated(title); }); - } - - void notifyFaviconChanged(@Nullable Bitmap favicon) { - maybeRunOnTabObserver(observer -> { observer.notifyFaviconChanged(favicon); }); - } - - private interface OnTabObserverCallback { - void run(ITabObserverDelegate tabObserver) throws RemoteException; - } - - private void maybeRunOnTabObserver(OnTabObserverCallback callback) { - if (mTabObserver != null) { - try { - callback.run(mTabObserver); - } catch (RemoteException e) { - } - } - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/WebFragmentTabListDelegate.java b/weblayer/public/java/org/chromium/weblayer/WebFragmentTabListDelegate.java deleted file mode 100644 index 1994d76..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebFragmentTabListDelegate.java +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.os.RemoteException; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.webengine.interfaces.ITabListObserverDelegate; -import org.chromium.webengine.interfaces.ITabParams; - -import java.util.Set; - -/** - * This class acts as a proxy between the TabList events happening in - * weblayer and the TabListObserverDelegate in webengine. - */ -class WebFragmentTabListDelegate extends TabListCallback { - private ITabListObserverDelegate mTabListObserver; - - private final NewTabCallback mNewTabCallback = new NewTabCallback() { - @Override - public void onNewTab(@NonNull Tab tab, @NewTabType int type) { - // Set foreground tabs and tabs in new windows by default to active. - switch (type) { - case NewTabType.FOREGROUND_TAB: - case NewTabType.NEW_WINDOW: - tab.getBrowser().setActiveTab(tab); - break; - } - } - }; - - void setObserver(ITabListObserverDelegate observer) { - mTabListObserver = observer; - } - - void notifyInitialTabs(Set<Tab> allTabs, Tab activeTab) { - for (Tab tab : allTabs) { - onTabAdded(tab); - } - onActiveTabChanged(activeTab); - onFinishedTabInitialization(); - } - - @Override - public void onActiveTabChanged(@Nullable Tab tab) { - maybeRunOnTabListObserver(observer -> { - ITabParams tabParams = null; - if (tab != null) { - tabParams = TabParams.buildParcelable(tab); - } - observer.notifyActiveTabChanged(tabParams); - }); - } - - @Override - public void onTabAdded(@NonNull Tab tab) { - // This is a requirement to open new tabs. - tab.setNewTabCallback(mNewTabCallback); - - maybeRunOnTabListObserver(observer -> { - ITabParams tabParams = TabParams.buildParcelable(tab); - observer.notifyTabAdded(tabParams); - }); - } - - @Override - public void onTabRemoved(@NonNull Tab tab) { - maybeRunOnTabListObserver(observer -> { - ITabParams tabParams = TabParams.buildParcelable(tab); - observer.notifyTabRemoved(tabParams); - }); - } - - @Override - public void onWillDestroyBrowserAndAllTabs() { - maybeRunOnTabListObserver(observer -> observer.notifyWillDestroyBrowserAndAllTabs()); - } - - public void onFinishedTabInitialization() { - maybeRunOnTabListObserver(observer -> { observer.onFinishedTabInitialization(); }); - } - - private interface OnTabListObserverCallback { - void run(ITabListObserverDelegate tabObserver) throws RemoteException; - } - - private void maybeRunOnTabListObserver(OnTabListObserverCallback callback) { - if (mTabListObserver != null) { - try { - callback.run(mTabListObserver); - } catch (RemoteException e) { - } - } - } -} \ No newline at end of file
diff --git a/weblayer/public/java/org/chromium/weblayer/WebLayer.java b/weblayer/public/java/org/chromium/weblayer/WebLayer.java deleted file mode 100644 index ad4f3a58..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebLayer.java +++ /dev/null
@@ -1,726 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.StrictMode; -import android.util.AndroidRuntimeException; -import android.util.Log; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.annotation.VisibleForTesting; - -import org.chromium.weblayer_private.interfaces.APICallException; -import org.chromium.weblayer_private.interfaces.IBrowser; -import org.chromium.weblayer_private.interfaces.IProfile; -import org.chromium.weblayer_private.interfaces.IWebLayer; -import org.chromium.weblayer_private.interfaces.IWebLayerClient; -import org.chromium.weblayer_private.interfaces.IWebLayerFactory; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.interfaces.StrictModeWorkaround; -import org.chromium.weblayer_private.interfaces.WebLayerVersionConstants; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -/** - * WebLayer is responsible for initializing state necessary to use any of the classes in web layer. - */ -@VisibleForTesting -public class WebLayer { - private static final String TAG = "WebLayer"; - // This metadata key, if defined, overrides the default behaviour of loading WebLayer from the - // current WebView implementation. This is only intended for testing, and does not enforce any - // signature requirements on the implementation, nor does it use the production code path to - // load the code. Do not set this in production APKs! - private static final String PACKAGE_MANIFEST_KEY = "org.chromium.weblayer.WebLayerPackage"; - - @SuppressWarnings("StaticFieldLeak") - @Nullable - private static Context sRemoteContext; - - @Nullable - private static ClassLoader sRemoteClassLoader; - - @Nullable - private static Context sAppContext; - - @Nullable - private static WebLayerLoader sLoader; - - private static boolean sDisableWebViewCompatibilityMode; - - @NonNull - private final IWebLayer mImpl; - - /** - * Returns true if WebLayer is available. This tries to load WebLayer, but does no - * initialization. This function may be called by code that uses WebView. - * <p> - * NOTE: it's possible for this to return true, yet loading to still fail. This happens if there - * is an error during loading. - * - * @return true Returns true if WebLayer is available. - */ - static boolean isAvailable(Context context) { - ThreadCheck.ensureOnUiThread(); - return getWebLayerLoader(context).isAvailable(); - } - - private static void checkAvailable(Context context) { - if (!isAvailable(context)) { - throw new UnsupportedVersionException(sLoader.getVersion()); - } - } - - /** - * Asynchronously creates and initializes WebLayer. Calling this more than once returns the same - * object. Both this method and {@link #loadSync} yield the same instance of {@link WebLayer}. - * <p> - * {@link callback} is supplied null if unable to load WebLayer. In general, the only time null - * is supplied is if there is an unexpected error. - * - * @param appContext The hosting application's Context. - * @param callback {@link Callback} which will receive the WebLayer instance. - * @throws UnsupportedVersionException If {@link #isAvailable} returns false. See - * {@link #isAvailable} for details. - */ - static void loadAsync(@NonNull Context appContext, @NonNull Callback<WebLayer> callback) - throws UnsupportedVersionException { - ThreadCheck.ensureOnUiThread(); - checkAvailable(appContext); - getWebLayerLoader(appContext).loadAsync(callback); - } - - /** - * Synchronously creates and initializes WebLayer. - * Both this method and {@link #loadAsync} yield the same instance of {@link WebLayer}. - * It is safe to call this method after {@link #loadAsync} to block until the ongoing load - * finishes (or immediately return its result if already finished). - * <p> - * This returns null if unable to load WebLayer. In general, the only time null - * is returns is if there is an unexpected error loading. - * - * @param appContext The hosting application's Context. - * @return a {@link WebLayer} instance, or null if unable to load WebLayer. - * - * @throws UnsupportedVersionException If {@link #isAvailable} returns false. See - * {@link #isAvailable} for details. - */ - @Nullable - static WebLayer loadSync(@NonNull Context appContext) throws UnsupportedVersionException { - ThreadCheck.ensureOnUiThread(); - checkAvailable(appContext); - return getWebLayerLoader(appContext).loadSync(); - } - - private static WebLayerLoader getWebLayerLoader(Context context) { - if (sLoader == null) sLoader = new WebLayerLoader(context); - return sLoader; - } - - /** Returns whether WebLayer loading has at least started. */ - static boolean hasWebLayerInitializationStarted() { - return sLoader != null; - } - - IWebLayer getImpl() { - return mImpl; - } - - static WebLayer getLoadedWebLayer(@NonNull Context appContext) - throws UnsupportedVersionException { - ThreadCheck.ensureOnUiThread(); - checkAvailable(appContext); - return getWebLayerLoader(appContext).getLoadedWebLayer(); - } - - /** - * Returns the supported version. Using any functions defined in a newer version than - * returned by {@link getSupportedMajorVersion} result in throwing an - * UnsupportedOperationException. - * <p> For example, consider the function {@link setBottomBar}, and further assume - * {@link setBottomBar} was added in version 11. If {@link getSupportedMajorVersion} - * returns 10, then calling {@link setBottomBar} returns in an UnsupportedOperationException. - * OTOH, if {@link getSupportedMajorVersion} returns 12, then {@link setBottomBar} works as - * expected - * - * @return the supported version, or -1 if WebLayer is not available. - */ - static int getSupportedMajorVersion(@NonNull Context context) { - ThreadCheck.ensureOnUiThread(); - return getWebLayerLoader(context).getMajorVersion(); - } - - // Returns true if version checks should be done. This is provided solely for testing, and - // specifically testing that does not run on device and load the implementation. It is only - // necessary to check this in code paths that don't require WebLayer to load the implementation - // and need to be callable in tests. - static boolean shouldPerformVersionChecks() { - return !"robolectric".equals(Build.FINGERPRINT); - } - - // Internal version of getSupportedMajorVersion(). This should only be used when you know - // WebLayer has been initialized. Generally that means calling this from any non-static method. - static int getSupportedMajorVersionInternal() { - if (sLoader == null) { - throw new IllegalStateException( - "This should only be called once WebLayer is initialized"); - } - return sLoader.getMajorVersion(); - } - - // Internal getter for the app Context. This should only be used when you know WebLayer has - // been initialized. - static Context getAppContext() { - return sAppContext; - } - - /** - * Returns the Chrome version of the WebLayer implementation. This will return a full version - * string such as "79.0.3945.0", while {@link getSupportedMajorVersion} will only return the - * major version integer (79 in the example). - */ - @NonNull - static String getSupportedFullVersion(@NonNull Context context) { - ThreadCheck.ensureOnUiThread(); - return getWebLayerLoader(context).getVersion(); - } - - /** - * Returns the Chrome version this client was built at. This will return a full version string - * such as "79.0.3945.0". - */ - @NonNull - static String getVersion() { - ThreadCheck.ensureOnUiThread(); - return WebLayerClientVersionConstants.PRODUCT_VERSION; - } - - @NonNull - static String getProviderPackageName(@NonNull Context context) { - ThreadCheck.ensureOnUiThread(); - return getWebLayerLoader(context).getProviderPackageName(); - } - - /** - * Encapsulates the state of WebLayer loading and initialization. - */ - private static final class WebLayerLoader { - @NonNull - private final List<Callback<WebLayer>> mCallbacks = new ArrayList<>(); - @Nullable - private IWebLayerFactory mFactory; - @Nullable - private IWebLayer mIWebLayer; - @Nullable - private WebLayer mWebLayer; - // True if WebLayer is available and compatible with this client. - private final boolean mAvailable; - private final int mMajorVersion; - private final String mVersion; - private boolean mIsLoadingAsync; - private Context mContext; - - /** - * Creates WebLayerLoader. This does a minimal amount of loading - */ - public WebLayerLoader(@NonNull Context context) { - boolean available = false; - int majorVersion = -1; - String version = "<unavailable>"; - // Use the application context as the supplied context may have a shorter lifetime. - mContext = context.getApplicationContext(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R - && ApiHelperForR.getAttributionTag(context) != null) { - // Getting the application context means we lose any attribution. Use the - // attribution tag from the supplied context so that embedders have a way to set an - // attribution tag. - mContext = ApiHelperForR.createAttributionContext( - mContext, ApiHelperForR.getAttributionTag(context)); - } - try { - Class factoryClass = loadRemoteClass( - mContext, "org.chromium.weblayer_private.WebLayerFactoryImpl"); - mFactory = IWebLayerFactory.Stub.asInterface( - (IBinder) factoryClass - .getMethod("create", String.class, int.class, int.class) - .invoke(null, WebLayerClientVersionConstants.PRODUCT_VERSION, - WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION, -1)); - available = mFactory.isClientSupported(); - majorVersion = mFactory.getImplementationMajorVersion(); - version = mFactory.getImplementationVersion(); - if (available) { - available = majorVersion >= WebLayerVersionConstants.MIN_VERSION; - } - // See comment in WebLayerFactoryImpl.isClientSupported() for details on this. - if (available - && WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION > majorVersion) { - available = WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION - majorVersion - <= WebLayerVersionConstants.MAX_SKEW; - } - } catch (Exception e) { - Log.e(TAG, "Unable to create WebLayerFactory", e); - } - mAvailable = available; - mMajorVersion = majorVersion; - mVersion = version; - } - - public String getProviderPackageName() { - try { - return getOrCreateRemoteContext(mContext).getPackageName(); - } catch (Exception e) { - throw new APICallException(e); - } - } - - public boolean isAvailable() { - return mAvailable; - } - - public int getMajorVersion() { - return mMajorVersion; - } - - public String getVersion() { - return mVersion; - } - - public void loadAsync(@NonNull Callback<WebLayer> callback) { - if (mWebLayer != null) { - callback.onResult(mWebLayer); - return; - } - mCallbacks.add(callback); - if (mIsLoadingAsync) { - return; // Already loading. - } - mIsLoadingAsync = true; - if (getIWebLayer() == null) { - // Unable to create WebLayer. This generally shouldn't happen. - onWebLayerReady(); - return; - } - try { - getIWebLayer().loadAsync(ObjectWrapper.wrap(mContext), - ObjectWrapper.wrap(getOrCreateRemoteContext(mContext)), - ObjectWrapper.wrap( - (ValueCallback<Boolean>) result -> { onWebLayerReady(); })); - } catch (Exception e) { - throw new APICallException(e); - } - } - - public WebLayer loadSync() { - if (mWebLayer != null) { - return mWebLayer; - } - if (getIWebLayer() == null) { - // Error in creating WebLayer. This generally shouldn't happen. - onWebLayerReady(); - return null; - } - try { - getIWebLayer().loadSync(ObjectWrapper.wrap(mContext), - ObjectWrapper.wrap(getOrCreateRemoteContext(mContext))); - onWebLayerReady(); - return mWebLayer; - } catch (Exception e) { - throw new APICallException(e); - } - } - - WebLayer getLoadedWebLayer() { - return mWebLayer; - } - - @Nullable - private IWebLayer getIWebLayer() { - if (mIWebLayer != null) return mIWebLayer; - if (!mAvailable) return null; - try { - mIWebLayer = mFactory.createWebLayer(); - } catch (RemoteException e) { - // If |mAvailable| returns true, then create() should always succeed. - throw new AndroidRuntimeException(e); - } - return mIWebLayer; - } - - private void onWebLayerReady() { - if (mWebLayer != null) { - return; - } - if (mIWebLayer != null) mWebLayer = new WebLayer(mIWebLayer); - for (Callback<WebLayer> callback : mCallbacks) { - callback.onResult(mWebLayer); - } - mCallbacks.clear(); - } - } - - // Constructor for test mocking. - protected WebLayer() { - mImpl = null; - } - - private WebLayer(IWebLayer iWebLayer) { - mImpl = iWebLayer; - - try { - mImpl.setClient(new WebLayerClientImpl()); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Get or create the profile for profileName. - * @param profileName Null to indicate in-memory profile. Otherwise, name cannot be empty - * and should contain only alphanumeric and underscore characters since it will be used as - * a directory name in the file system. - */ - @NonNull - public Profile getProfile(@Nullable String profileName) { - ThreadCheck.ensureOnUiThread(); - IProfile iprofile; - try { - iprofile = mImpl.getProfile(Profile.sanitizeProfileName(profileName)); - } catch (RemoteException e) { - throw new APICallException(e); - } - return Profile.of(iprofile); - } - - /** - * Get or create the incognito profile with the name {@link profileName}. - * - * @param profileName The name of the profile. Null is mapped to an empty string. - */ - @NonNull - public Profile getIncognitoProfile(@Nullable String profileName) { - ThreadCheck.ensureOnUiThread(); - IProfile iprofile; - try { - iprofile = mImpl.getIncognitoProfile(Profile.sanitizeProfileName(profileName)); - } catch (RemoteException e) { - throw new APICallException(e); - } - return Profile.of(iprofile); - } - - /** - * Return a list of Profile names currently on disk. This does not include incognito - * profiles. This will not include profiles that are being deleted from disk. - * WebLayer must be initialized before calling this. - */ - public void enumerateAllProfileNames(@NonNull Callback<String[]> callback) { - ThreadCheck.ensureOnUiThread(); - try { - ValueCallback<String[]> valueCallback = (String[] value) -> callback.onResult(value); - mImpl.enumerateAllProfileNames(ObjectWrapper.wrap(valueCallback)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the user agent string used by WebLayer. - * - * @return The user-agent string. - */ - public String getUserAgentString() { - ThreadCheck.ensureOnUiThread(); - try { - return mImpl.getUserAgentString(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * To enable or disable DevTools remote debugging. - */ - public void setRemoteDebuggingEnabled(boolean enabled) { - try { - mImpl.setRemoteDebuggingEnabled(enabled); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * @return Whether or not DevTools remote debugging is enabled. - */ - public boolean isRemoteDebuggingEnabled() { - try { - return mImpl.isRemoteDebuggingEnabled(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Provide WebLayer with a set of active external experiment IDs. - * - * These experiment IDs are to be incorporated into metrics collection performed by WebLayer - * to aid in interpretation of data and elimination of confounding factors. - * - * This method may be called multiple times to update experient IDs if they change. - * - * @param experimentIds An array of integer active experiment IDs relevant to WebLayer. - */ - public void registerExternalExperimentIDs(@NonNull int[] experimentIds) { - ThreadCheck.ensureOnUiThread(); - try { - // First param no longer used. First param was not used in the backend as of 85, and - // always supplied as empty as of 89 client. - mImpl.registerExternalExperimentIDs("", experimentIds); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Returns the value of X-Client-Data header. - * @since 101 - */ - public String getXClientDataHeader() { - ThreadCheck.ensureOnUiThread(); - if (getSupportedMajorVersionInternal() < 101) { - throw new UnsupportedOperationException(); - } - try { - return mImpl.getXClientDataHeader(); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - IBrowser createBrowser(Context serviceContext, Bundle fragmentArgs) { - try { - return mImpl.createBrowser( - ObjectWrapper.wrap(serviceContext), ObjectWrapper.wrap(fragmentArgs)); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /* package */ static IWebLayer getIWebLayer(Context context) { - return getWebLayerLoader(context).getIWebLayer(); - } - - /* package */ static Context getApplicationContextForTesting(Context appContext) { - try { - return (Context) ObjectWrapper.unwrap( - getIWebLayer(appContext).getApplicationContext(), Context.class); - } catch (RemoteException e) { - throw new APICallException(e); - } - } - - /** - * Creates a ClassLoader for the remote (weblayer implementation) side. - */ - static Class<?> loadRemoteClass(Context appContext, String className) - throws PackageManager.NameNotFoundException, ReflectiveOperationException { - if (sRemoteClassLoader != null) { - return sRemoteClassLoader.loadClass(className); - } - - // Child processes do not need WebView compatibility since there is no chance - // WebView will run in the same process. - if (sDisableWebViewCompatibilityMode) { - Context context = getOrCreateRemoteContext(appContext); - // Android versions before O do not support isolated splits, so WebLayer will be loaded - // as a normal split which is already available from the base class loader. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // Attempt to find the class in the base ClassLoader, if it doesn't exist then load - // the weblayer ClassLoader. - try { - Class.forName(className, false, context.getClassLoader()); - } catch (ClassNotFoundException e) { - try { - // If the implementation APK does not support isolated splits, this will - // just return the original context. - context = ApiHelperForO.createContextForSplit(context, "weblayer"); - } catch (PackageManager.NameNotFoundException e2) { - // WebLayer not in split, proceed with the base context. - } - } - } - sRemoteClassLoader = context.getClassLoader(); - } else { - sRemoteClassLoader = WebViewCompatibilityHelper.initialize(appContext); - } - return sRemoteClassLoader.loadClass(className); - } - - /** - * Creates a Context for the remote (weblayer implementation) side. - */ - static Context getOrCreateRemoteContext(Context appContext) - throws PackageManager.NameNotFoundException, ReflectiveOperationException { - if (sRemoteContext != null) { - return sRemoteContext; - } - Class<?> webViewFactoryClass = Class.forName("android.webkit.WebViewFactory"); - String implPackageName = getImplPackageName(appContext); - sAppContext = appContext; - if (implPackageName != null) { - sRemoteContext = createRemoteContextFromPackageName(appContext, implPackageName); - } else { - Method getContext = - webViewFactoryClass.getDeclaredMethod("getWebViewContextAndSetProvider"); - getContext.setAccessible(true); - sRemoteContext = (Context) getContext.invoke(null); - } - return sRemoteContext; - } - - /* package */ static void disableWebViewCompatibilityMode() { - sDisableWebViewCompatibilityMode = true; - } - - /** - * Creates a Context for the remote (weblayer implementation) side - * using a specified package name as the implementation. This is only - * intended for testing, not production use. - */ - private static Context createRemoteContextFromPackageName( - Context appContext, String implPackageName) - throws PackageManager.NameNotFoundException, ReflectiveOperationException { - // Load the code for the target package. - Context remoteContext = appContext.createPackageContext( - implPackageName, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE); - - // Get the package info for the target package. - PackageInfo implPackageInfo = appContext.getPackageManager().getPackageInfo(implPackageName, - PackageManager.GET_SHARED_LIBRARY_FILES | PackageManager.GET_META_DATA); - - // Store this package info in WebViewFactory as if it had been loaded as WebView, - // because other parts of the implementation need to be able to fetch it from there. - Class<?> webViewFactory = Class.forName("android.webkit.WebViewFactory"); - Field sPackageInfo = webViewFactory.getDeclaredField("sPackageInfo"); - sPackageInfo.setAccessible(true); - sPackageInfo.set(null, implPackageInfo); - - return remoteContext; - } - - private static String getImplPackageName(Context appContext) - throws PackageManager.NameNotFoundException { - Bundle metaData = appContext.getPackageManager() - .getApplicationInfo( - appContext.getPackageName(), PackageManager.GET_META_DATA) - .metaData; - if (metaData != null) return metaData.getString(PACKAGE_MANIFEST_KEY); - return null; - } - - private final class WebLayerClientImpl extends IWebLayerClient.Stub { - @Override - public Intent createIntent() { - StrictModeWorkaround.apply(); - // Intent objects need to be created in the client library so they can refer to the - // broadcast receiver that will handle them. The broadcast receiver needs to be in the - // client library because it's referenced in the manifest. - return new Intent(WebLayer.getAppContext(), BroadcastReceiver.class); - } - - @Override - public Intent createMediaSessionServiceIntent() { - StrictModeWorkaround.apply(); - return new Intent(WebLayer.getAppContext(), MediaSessionService.class); - } - - @Override - public Intent createImageDecoderServiceIntent() { - StrictModeWorkaround.apply(); - return new Intent(WebLayer.getAppContext(), ImageDecoderService.class); - } - - @Override - public int getMediaSessionNotificationId() { - StrictModeWorkaround.apply(); - // The id is part of the public library to avoid conflicts. - return R.id.weblayer_media_session_notification; - } - - @Override - public Intent createRemoteMediaServiceIntent() { - StrictModeWorkaround.apply(); - return new Intent(WebLayer.getAppContext(), RemoteMediaService.class); - } - - @Override - public int getPresentationApiNotificationId() { - StrictModeWorkaround.apply(); - // The id is part of the public library to avoid conflicts. - return R.id.weblayer_presentation_api_notification; - } - - @Override - public int getRemotePlaybackApiNotificationId() { - StrictModeWorkaround.apply(); - // The id is part of the public library to avoid conflicts. - return R.id.weblayer_remote_playback_api_notification; - } - - @Override - public int getMaxNavigationsPerTabForInstanceState() { - return Browser.getMaxNavigationsPerTabForInstanceState(); - } - } - - /** Utility class to use new APIs that were added in O (API level 26). */ - @VerifiesOnO - @RequiresApi(Build.VERSION_CODES.O) - /* package */ static final class ApiHelperForO { - /** See {@link Context.createContextForSplit(String) }. */ - public static Context createContextForSplit(Context context, String name) - throws PackageManager.NameNotFoundException { - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - return context.createContextForSplit(name); - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } - } - - /** See {@link ApplicationInfo#splitNames}. */ - public static String[] getSplitNames(ApplicationInfo info) { - return info.splitNames; - } - } - - @VerifiesOnR - @RequiresApi(Build.VERSION_CODES.R) - private static final class ApiHelperForR { - /** See {@link Context.getAttributionTag() }. */ - public static String getAttributionTag(Context context) { - return context.getAttributionTag(); - } - - /** See {@link Context.createAttributionContext(String) }. */ - public static Context createAttributionContext(Context context, String tag) { - return context.createAttributionContext(tag); - } - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebLayerClientVersionConstants.java.version b/weblayer/public/java/org/chromium/weblayer/WebLayerClientVersionConstants.java.version deleted file mode 100644 index e34bdfc..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebLayerClientVersionConstants.java.version +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -final class WebLayerClientVersionConstants { - public static final String PRODUCT_VERSION = "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"; - - public static final int PRODUCT_MAJOR_VERSION = @MAJOR@; -}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebLayerFileProvider.java b/weblayer/public/java/org/chromium/weblayer/WebLayerFileProvider.java deleted file mode 100644 index 0917a1f7..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebLayerFileProvider.java +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.core.content.FileProvider; - -/** - * Subclass of FileProvider which prevents conflicts with the embedding application manifest. - */ -public class WebLayerFileProvider extends FileProvider {}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebMessage.java b/weblayer/public/java/org/chromium/weblayer/WebMessage.java deleted file mode 100644 index 19855de..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebMessage.java +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.annotation.NonNull; - -/** - * Used when sending and receiving messages to a page. - */ -class WebMessage { - private final String mContents; - - /** - * Creates a message with the specified contents. - * - * @param message Contents of the message. - */ - public WebMessage(@NonNull String message) { - mContents = message; - } - - /** - * Returns the contents of the message. - * - * @return The contents of the message. - */ - public @NonNull String getContents() { - return mContents; - } -}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java b/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java deleted file mode 100644 index 0dde473..0000000 --- a/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.StrictMode; -import android.text.TextUtils; - -import dalvik.system.BaseDexClassLoader; -import dalvik.system.PathClassLoader; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** Helper class which performs initialization needed for WebView compatibility. */ -final class WebViewCompatibilityHelper { - /** Creates a the ClassLoader to use for WebView compatibility. */ - static ClassLoader initialize(Context appContext) - throws PackageManager.NameNotFoundException, ReflectiveOperationException { - Context remoteContext = WebLayer.getOrCreateRemoteContext(appContext); - PackageInfo info = - appContext.getPackageManager().getPackageInfo(remoteContext.getPackageName(), - PackageManager.GET_SHARED_LIBRARY_FILES - | PackageManager.MATCH_UNINSTALLED_PACKAGES); - String[] libraryPaths = getLibraryPaths(remoteContext.getClassLoader()); - // Prepend "/." to all library paths. This changes the library path while still pointing to - // the same directory, allowing us to get around a check in the JVM. This is only necessary - // for N+, where we rely on linker namespaces. - for (int i = 0; i < libraryPaths.length; i++) { - assert libraryPaths[i].startsWith("/"); - libraryPaths[i] = "/." + libraryPaths[i]; - } - - String dexPath = getAllApkPaths(info.applicationInfo); - String librarySearchPath = TextUtils.join(File.pathSeparator, libraryPaths); - // TODO(cduvall): PathClassLoader may call stat on the library paths, consider moving - // this to a background thread. - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - // Use the system class loader's parent here, since it is much more efficient. This - // matches what Android does when constructing class loaders, see - // android.app.ApplicationLoaders. - return new PathClassLoader( - dexPath, librarySearchPath, ClassLoader.getSystemClassLoader().getParent()); - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } - } - - /** Returns the library paths the given class loader will search. */ - static String[] getLibraryPaths(ClassLoader classLoader) throws ReflectiveOperationException { - // This seems to be the best way to reliably get both the native lib directory and the path - // within the APK where libs might be stored. - return ((String) BaseDexClassLoader.class.getDeclaredMethod("getLdLibraryPath") - .invoke((BaseDexClassLoader) classLoader)) - .split(":"); - } - - /** This is mostly taken from ApplicationInfo.getAllApkPaths(). */ - private static String getAllApkPaths(ApplicationInfo info) { - // The OS version of this method also includes resourceDirs, but this is not available in - // the SDK. - final List<String> output = new ArrayList<>(10); - // First add the base APK path, since this is always needed. - if (info.sourceDir != null) { - output.add(info.sourceDir); - } - // Next add split paths that are used by WebLayer. - if (info.splitSourceDirs != null) { - String[] splitNames = null; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - splitNames = WebLayer.ApiHelperForO.getSplitNames(info); - } - for (int i = 0; i < info.splitSourceDirs.length; i++) { - // WebLayer only uses the "chrome" and "weblayer" splits. - if (splitNames != null && !splitNames[i].equals("chrome") - && !splitNames[i].equals("weblayer")) { - continue; - } - output.add(info.splitSourceDirs[i]); - } - } - // Last, add shared library paths. - if (info.sharedLibraryFiles != null) { - for (String input : info.sharedLibraryFiles) { - output.add(input); - } - } - return TextUtils.join(File.pathSeparator, output); - } - - private WebViewCompatibilityHelper() {} -}
diff --git a/weblayer/public/java/proguard.flags b/weblayer/public/java/proguard.flags deleted file mode 100644 index e9795b1..0000000 --- a/weblayer/public/java/proguard.flags +++ /dev/null
@@ -1,28 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - --keep @interface org.chromium.weblayer.VerifiesOnO --if @org.chromium.weblayer.VerifiesOnO class * { - *** *(...); -} --keep,allowobfuscation class <1> { - *** <2>(...); -} --keepclassmembers,allowobfuscation class ** { - @org.chromium.weblayer.VerifiesOnO <methods>; -} - --keep @interface org.chromium.weblayer.VerifiesOnR --if @org.chromium.weblayer.VerifiesOnR class * { - *** *(...); -} --keep,allowobfuscation class <1> { - *** <2>(...); -} --keepclassmembers,allowobfuscation class ** { - @org.chromium.weblayer.VerifiesOnR <methods>; -} - -# Android uses reflection to create an instance of this. --keep class org.chromium.weblayer.BrowserFragment$BrowserViewModel
diff --git a/weblayer/public/java/res/values-night/colors.xml b/weblayer/public/java/res/values-night/colors.xml deleted file mode 100644 index a74de904..0000000 --- a/weblayer/public/java/res/values-night/colors.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources> - <color name="weblayer_default_bg_color">@color/weblayer_default_bg_color_dark</color> - <color name="weblayer_bottom_system_nav_color">@android:color/black</color> - <color name="weblayer_bottom_system_nav_divider_color">@android:color/black</color> -</resources>
diff --git a/weblayer/public/java/res/values-night/values.xml b/weblayer/public/java/res/values-night/values.xml deleted file mode 100644 index 5b573bf..0000000 --- a/weblayer/public/java/res/values-night/values.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools"> - <!-- Status and navigation bar icon styling. --> - <bool name="weblayer_window_light_status_bar">false</bool> - <bool name="weblayer_window_light_navigation_bar">false</bool> -</resources>
diff --git a/weblayer/public/java/res/values-v27/styles.xml b/weblayer/public/java/res/values-v27/styles.xml deleted file mode 100644 index 84fb3f80..0000000 --- a/weblayer/public/java/res/values-v27/styles.xml +++ /dev/null
@@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources> - <style name="Theme.WebLayer.Settings" parent="Base.Theme.WebLayer.Settings"> - <item name="android:navigationBarColor">@color/weblayer_bottom_system_nav_color</item> - <item name="android:navigationBarDividerColor">@color/weblayer_bottom_system_nav_divider_color</item> - <item name="android:windowLightNavigationBar">@bool/weblayer_window_light_navigation_bar</item> - </style> -</resources>
diff --git a/weblayer/public/java/res/values-v28/styles.xml b/weblayer/public/java/res/values-v28/styles.xml deleted file mode 100644 index ea65fc6..0000000 --- a/weblayer/public/java/res/values-v28/styles.xml +++ /dev/null
@@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources> - <style name="Theme.WebLayer.Settings" parent="Base.Theme.WebLayer.Settings"> - <item name="android:navigationBarColor">@color/weblayer_bottom_system_nav_color</item> - <item name="android:navigationBarDividerColor">@color/weblayer_bottom_system_nav_divider_color</item> - <item name="android:windowLightNavigationBar">@bool/weblayer_window_light_navigation_bar</item> - - <!-- The windowLightStatusBar attribute was added in API 23, but we - avoid using it via XML prior to 28 due to: https://crbug.com/884144 - and https://crbug.com/1014844 --> - <item name="android:statusBarColor">@color/weblayer_default_bg_color</item> - <item name="android:windowLightStatusBar">@bool/weblayer_window_light_status_bar</item> - </style> -</resources>
diff --git a/weblayer/public/java/res/values/colors.xml b/weblayer/public/java/res/values/colors.xml deleted file mode 100644 index 72ad8c79..0000000 --- a/weblayer/public/java/res/values/colors.xml +++ /dev/null
@@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources"> - <color name="weblayer_default_bg_color">@color/weblayer_default_bg_color_light</color> - <color name="weblayer_default_bg_color_light">@android:color/white</color> - <color name="weblayer_default_bg_color_dark">@color/weblayer_modern_grey_900</color> - - <color name="weblayer_bottom_system_nav_color">@android:color/white</color> - <color name="weblayer_bottom_system_nav_divider_color">@color/weblayer_black_alpha_12</color> - - <color name="weblayer_black_alpha_12">#1F000000</color> - <color name="weblayer_modern_grey_900">#202124</color> -</resources>
diff --git a/weblayer/public/java/res/values/ids.xml b/weblayer/public/java/res/values/ids.xml deleted file mode 100644 index 8a7502b..0000000 --- a/weblayer/public/java/res/values/ids.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources> - <item type="id" name="weblayer_media_session_notification" /> - <item type="id" name="weblayer_presentation_api_notification" /> - <item type="id" name="weblayer_remote_playback_api_notification" /> -</resources>
diff --git a/weblayer/public/java/res/values/styles.xml b/weblayer/public/java/res/values/styles.xml deleted file mode 100644 index d7268b9..0000000 --- a/weblayer/public/java/res/values/styles.xml +++ /dev/null
@@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools"> - <style name="Base.Theme.WebLayer.Settings" parent="Theme.AppCompat.DayNight"> - <!-- Window Properties --> - <item name="android:windowBackground">@color/weblayer_default_bg_color</item> - - <!-- Action bar color --> - <item name="colorPrimary">@color/weblayer_default_bg_color</item> - - <!-- Status bar color --> - <item name="colorPrimaryDark">@android:color/black</item> - <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item> - <item name="android:windowLightStatusBar" tools:targetApi="23">false</item> - </style> - - <style name="Theme.WebLayer.Settings" parent="Base.Theme.WebLayer.Settings" /> -</resources>
diff --git a/weblayer/public/java/res/values/values.xml b/weblayer/public/java/res/values/values.xml deleted file mode 100644 index 06d1ecd2..0000000 --- a/weblayer/public/java/res/values/values.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2020 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools"> - <!-- Status and navigation bar icon styling. --> - <bool name="weblayer_window_light_status_bar">true</bool> - <bool name="weblayer_window_light_navigation_bar">true</bool> -</resources>
diff --git a/weblayer/public/java/res/xml/weblayer_file_paths.xml b/weblayer/public/java/res/xml/weblayer_file_paths.xml deleted file mode 100644 index d92ac1e2..0000000 --- a/weblayer/public/java/res/xml/weblayer_file_paths.xml +++ /dev/null
@@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2019 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<!-- The attributes in this XML file provide configuration information --> -<!-- for the ContentProvider. --> - -<paths xmlns:android="http://schemas.android.com/apk/res/android"> - <files-path name="images" path="images/"/> - <external-path name="external_files" path="."/> - <cache-path name="cache" path="weblayer/net-export/"/> -</paths>
diff --git a/weblayer/public/javatests/BUILD.gn b/weblayer/public/javatests/BUILD.gn deleted file mode 100644 index 184207d1..0000000 --- a/weblayer/public/javatests/BUILD.gn +++ /dev/null
@@ -1,21 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") - -android_library("weblayer_public_javatests") { - testonly = true - sources = [ - "org/chromium/weblayer/ObserverListTest.java", - "org/chromium/weblayer/WebViewCompatibilityHelperTest.java", - ] - deps = [ - "//base:base_java_test_support", - "//third_party/androidx:androidx_test_monitor_java", - "//third_party/androidx:androidx_test_runner_java", - "//third_party/junit:junit", - "//weblayer/public/java", - ] -}
diff --git a/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java b/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java deleted file mode 100644 index 1b94f19..0000000 --- a/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java +++ /dev/null
@@ -1,332 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import androidx.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.BaseJUnit4ClassRunner; - -import java.util.Collection; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Tests for (@link ObserverList}. - */ -@RunWith(BaseJUnit4ClassRunner.class) -public class ObserverListTest { - interface Observer { - void observe(int x); - } - - private static class Foo implements Observer { - private final int mScalar; - private int mTotal; - - Foo(int scalar) { - mScalar = scalar; - } - - @Override - public void observe(int x) { - mTotal += x * mScalar; - } - } - - /** - * An observer which add a given Observer object to the list when observe is called. - */ - private static class FooAdder implements Observer { - private final ObserverList<Observer> mList; - private final Observer mLucky; - - FooAdder(ObserverList<Observer> list, Observer oblivious) { - mList = list; - mLucky = oblivious; - } - - @Override - public void observe(int x) { - mList.addObserver(mLucky); - } - } - - /** - * An observer which removes a given Observer object from the list when observe is called. - */ - private static class FooRemover implements Observer { - private final ObserverList<Observer> mList; - private final Observer mDoomed; - - FooRemover(ObserverList<Observer> list, Observer innocent) { - mList = list; - mDoomed = innocent; - } - - @Override - public void observe(int x) { - mList.removeObserver(mDoomed); - } - } - - private static <T> int getSizeOfIterable(Iterable<T> iterable) { - if (iterable instanceof Collection<?>) return ((Collection<?>) iterable).size(); - int num = 0; - for (T el : iterable) num++; - return num; - } - - @Test - @SmallTest - public void testRemoveWhileIteration() { - ObserverList<Observer> observerList = new ObserverList<Observer>(); - Foo a = new Foo(1); - Foo b = new Foo(-1); - Foo c = new Foo(1); - Foo d = new Foo(-1); - Foo e = new Foo(-1); - FooRemover evil = new FooRemover(observerList, c); - - observerList.addObserver(a); - observerList.addObserver(b); - - for (Observer obs : observerList) obs.observe(10); - - // Removing an observer not in the list should do nothing. - observerList.removeObserver(e); - - observerList.addObserver(evil); - observerList.addObserver(c); - observerList.addObserver(d); - - for (Observer obs : observerList) obs.observe(10); - - // observe should be called twice on a. - Assert.assertEquals(20, a.mTotal); - // observe should be called twice on b. - Assert.assertEquals(-20, b.mTotal); - // evil removed c from the observerList before it got any callbacks. - Assert.assertEquals(0, c.mTotal); - // observe should be called once on d. - Assert.assertEquals(-10, d.mTotal); - // e was never added to the list, observe should not be called. - Assert.assertEquals(0, e.mTotal); - } - - @Test - @SmallTest - public void testAddWhileIteration() { - ObserverList<Observer> observerList = new ObserverList<Observer>(); - Foo a = new Foo(1); - Foo b = new Foo(-1); - Foo c = new Foo(1); - FooAdder evil = new FooAdder(observerList, c); - - observerList.addObserver(evil); - observerList.addObserver(a); - observerList.addObserver(b); - - for (Observer obs : observerList) obs.observe(10); - - Assert.assertTrue(observerList.hasObserver(c)); - Assert.assertEquals(10, a.mTotal); - Assert.assertEquals(-10, b.mTotal); - Assert.assertEquals(0, c.mTotal); - } - - @Test - @SmallTest - public void testIterator() { - ObserverList<Integer> observerList = new ObserverList<Integer>(); - observerList.addObserver(5); - observerList.addObserver(10); - observerList.addObserver(15); - Assert.assertEquals(3, getSizeOfIterable(observerList)); - - observerList.removeObserver(10); - Assert.assertEquals(2, getSizeOfIterable(observerList)); - - Iterator<Integer> it = observerList.iterator(); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(5 == it.next()); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(15 == it.next()); - Assert.assertFalse(it.hasNext()); - - boolean removeExceptionThrown = false; - try { - it.remove(); - Assert.fail("Expecting UnsupportedOperationException to be thrown here."); - } catch (UnsupportedOperationException e) { - removeExceptionThrown = true; - } - Assert.assertTrue(removeExceptionThrown); - Assert.assertEquals(2, getSizeOfIterable(observerList)); - - boolean noElementExceptionThrown = false; - try { - it.next(); - Assert.fail("Expecting NoSuchElementException to be thrown here."); - } catch (NoSuchElementException e) { - noElementExceptionThrown = true; - } - Assert.assertTrue(noElementExceptionThrown); - } - - @Test - @SmallTest - public void testRewindableIterator() { - ObserverList<Integer> observerList = new ObserverList<Integer>(); - observerList.addObserver(5); - observerList.addObserver(10); - observerList.addObserver(15); - Assert.assertEquals(3, getSizeOfIterable(observerList)); - - ObserverList.RewindableIterator<Integer> it = observerList.rewindableIterator(); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(5 == it.next()); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(10 == it.next()); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(15 == it.next()); - Assert.assertFalse(it.hasNext()); - - it.rewind(); - - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(5 == it.next()); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(10 == it.next()); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(15 == it.next()); - Assert.assertEquals(5, (int) observerList.mObservers.get(0)); - observerList.removeObserver(5); - Assert.assertEquals(null, observerList.mObservers.get(0)); - - it.rewind(); - - Assert.assertEquals(10, (int) observerList.mObservers.get(0)); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(10 == it.next()); - Assert.assertTrue(it.hasNext()); - Assert.assertTrue(15 == it.next()); - } - - @Test - @SmallTest - public void testAddObserverReturnValue() { - ObserverList<Object> observerList = new ObserverList<Object>(); - - Object a = new Object(); - Assert.assertTrue(observerList.addObserver(a)); - Assert.assertFalse(observerList.addObserver(a)); - - Object b = new Object(); - Assert.assertTrue(observerList.addObserver(b)); - Assert.assertFalse(observerList.addObserver(null)); - } - - @Test - @SmallTest - public void testRemoveObserverReturnValue() { - ObserverList<Object> observerList = new ObserverList<Object>(); - - Object a = new Object(); - Object b = new Object(); - observerList.addObserver(a); - observerList.addObserver(b); - - Assert.assertTrue(observerList.removeObserver(a)); - Assert.assertFalse(observerList.removeObserver(a)); - Assert.assertFalse(observerList.removeObserver(new Object())); - Assert.assertTrue(observerList.removeObserver(b)); - Assert.assertFalse(observerList.removeObserver(null)); - - // If we remove an object while iterating, it will be replaced by 'null'. - observerList.addObserver(a); - Assert.assertTrue(observerList.removeObserver(a)); - Assert.assertFalse(observerList.removeObserver(null)); - } - - @Test - @SmallTest - public void testSize() { - ObserverList<Object> observerList = new ObserverList<Object>(); - - Assert.assertEquals(0, observerList.size()); - Assert.assertTrue(observerList.isEmpty()); - - observerList.addObserver(null); - Assert.assertEquals(0, observerList.size()); - Assert.assertTrue(observerList.isEmpty()); - - Object a = new Object(); - observerList.addObserver(a); - Assert.assertEquals(1, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.addObserver(a); - Assert.assertEquals(1, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.addObserver(null); - Assert.assertEquals(1, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - Object b = new Object(); - observerList.addObserver(b); - Assert.assertEquals(2, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.removeObserver(null); - Assert.assertEquals(2, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.removeObserver(new Object()); - Assert.assertEquals(2, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.removeObserver(b); - Assert.assertEquals(1, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.removeObserver(b); - Assert.assertEquals(1, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.removeObserver(a); - Assert.assertEquals(0, observerList.size()); - Assert.assertTrue(observerList.isEmpty()); - - observerList.removeObserver(a); - observerList.removeObserver(b); - observerList.removeObserver(null); - observerList.removeObserver(new Object()); - Assert.assertEquals(0, observerList.size()); - Assert.assertTrue(observerList.isEmpty()); - - observerList.addObserver(new Object()); - observerList.addObserver(new Object()); - observerList.addObserver(new Object()); - observerList.addObserver(a); - Assert.assertEquals(4, observerList.size()); - Assert.assertFalse(observerList.isEmpty()); - - observerList.clear(); - Assert.assertEquals(0, observerList.size()); - Assert.assertTrue(observerList.isEmpty()); - - observerList.removeObserver(a); - observerList.removeObserver(b); - observerList.removeObserver(null); - observerList.removeObserver(new Object()); - Assert.assertEquals(0, observerList.size()); - Assert.assertTrue(observerList.isEmpty()); - } -}
diff --git a/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java b/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java deleted file mode 100644 index f7186ec09..0000000 --- a/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.BaseJUnit4ClassRunner; - -/** - * Tests for (@link WebViewCompatibilityHelper}. - */ -@RunWith(BaseJUnit4ClassRunner.class) -public class WebViewCompatibilityHelperTest { - @Test - @SmallTest - public void testLibraryPaths() throws Exception { - Context appContext = InstrumentationRegistry.getTargetContext(); - ClassLoader classLoader = WebViewCompatibilityHelper.initialize(appContext); - String[] libraryPaths = WebViewCompatibilityHelper.getLibraryPaths(classLoader); - for (String path : libraryPaths) { - Assert.assertTrue(path.startsWith("/./")); - } - } -}
diff --git a/weblayer/public/javatestutil/BUILD.gn b/weblayer/public/javatestutil/BUILD.gn deleted file mode 100644 index 37245804..0000000 --- a/weblayer/public/javatestutil/BUILD.gn +++ /dev/null
@@ -1,26 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") - -android_library("test_java") { - testonly = true - sources = [ - "org/chromium/weblayer/TestProfile.java", - "org/chromium/weblayer/TestWebLayer.java", - ] - - deps = [ - "//base:base_java", - "//base:base_java_test_support", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/junit:junit", - "//weblayer/browser/java:base_module_interfaces_java", - "//weblayer/browser/java:interfaces_java", - "//weblayer/browser/java:test_java", - "//weblayer/public/java", - ] -}
diff --git a/weblayer/public/javatestutil/org/chromium/weblayer/SettingsTestUtils.java b/weblayer/public/javatestutil/org/chromium/weblayer/SettingsTestUtils.java deleted file mode 100644 index ea12bbdc..0000000 --- a/weblayer/public/javatestutil/org/chromium/weblayer/SettingsTestUtils.java +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.content.Intent; - -import org.chromium.weblayer_private.interfaces.SettingsIntentHelper; - -/** - * Helpers for writing tests for the Settings UI. - */ -public final class SettingsTestUtils { - // This can be removed if/when we move this into SettingsActivity. Currently no embedders - // need to launch the single site settings UI directly. - public static Intent createIntentForSiteSettingsSingleWebsite( - Context context, String profileName, boolean isIncognito, String url) { - return SettingsIntentHelper.createIntentForSiteSettingsSingleWebsite( - context, profileName, isIncognito, url); - } - - // This can be removed if/when we move this into SettingsActivity. Currently no embedders - // need to launch the single category settings UI directly. - public static Intent createIntentForSiteSettingsSingleCategory(Context context, - String profileName, boolean isIncognito, String categoryType, String categoryTitle) { - return SettingsIntentHelper.createIntentForSiteSettingsSingleCategory( - context, profileName, isIncognito, categoryType, categoryTitle); - } -}
diff --git a/weblayer/public/javatestutil/org/chromium/weblayer/TestProfile.java b/weblayer/public/javatestutil/org/chromium/weblayer/TestProfile.java deleted file mode 100644 index 5c68366..0000000 --- a/weblayer/public/javatestutil/org/chromium/weblayer/TestProfile.java +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -/** - * TestProfile is responsible for forwarding function calls to Profile. - */ -public final class TestProfile { - public static void destroy(Profile profile) { - profile.destroy(); - } -} \ No newline at end of file
diff --git a/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java b/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java deleted file mode 100644 index ece082db..0000000 --- a/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java +++ /dev/null
@@ -1,233 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.util.AndroidRuntimeException; -import android.view.View; -import android.webkit.ValueCallback; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.base.Callback; -import org.chromium.weblayer_private.interfaces.BrowserFragmentArgs; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; -import org.chromium.weblayer_private.test_interfaces.ITestWebLayer; - -import java.util.ArrayList; -import java.util.Set; - -/** - * TestWebLayer is responsible for passing messages over a test only AIDL to the - * WebLayer implementation. - */ -public final class TestWebLayer { - @Nullable - private ITestWebLayer mITestWebLayer; - - @Nullable - private static TestWebLayer sInstance; - - public static TestWebLayer getTestWebLayer(@NonNull Context appContext) { - if (sInstance == null) sInstance = new TestWebLayer(appContext); - return sInstance; - } - - private TestWebLayer(@NonNull Context appContext) { - try { - Class TestWebLayerClass = WebLayer.loadRemoteClass( - appContext, "org.chromium.weblayer_private.test.TestWebLayerImpl"); - mITestWebLayer = ITestWebLayer.Stub.asInterface( - (IBinder) TestWebLayerClass.getMethod("create").invoke(null)); - } catch (PackageManager.NameNotFoundException | ReflectiveOperationException e) { - throw new AndroidRuntimeException(e); - } - } - - public static WebLayer loadSync(Context context) { - return WebLayer.loadSync(context); - } - - public boolean isNetworkChangeAutoDetectOn() throws RemoteException { - return mITestWebLayer.isNetworkChangeAutoDetectOn(); - } - - /** - * Gets the processed context which is returned by ContextUtils.getApplicationContext() on the - * remote side. - */ - public static Context getRemoteContext(@NonNull Context appContext) { - return WebLayer.getApplicationContextForTesting(appContext); - } - - /** Gets the context for the WebLayer implementation package. */ - public static Context getWebLayerContext(@NonNull Context appContext) { - try { - return WebLayer.getOrCreateRemoteContext(appContext); - } catch (PackageManager.NameNotFoundException | ReflectiveOperationException e) { - throw new AndroidRuntimeException(e); - } - } - - public void setMockLocationProvider(boolean enabled) throws RemoteException { - mITestWebLayer.setMockLocationProvider(enabled); - } - - public boolean isMockLocationProviderRunning() throws RemoteException { - return mITestWebLayer.isMockLocationProviderRunning(); - } - - public boolean isPermissionDialogShown() throws RemoteException { - return mITestWebLayer.isPermissionDialogShown(); - } - - public void clickPermissionDialogButton(boolean allow) throws RemoteException { - mITestWebLayer.clickPermissionDialogButton(allow); - } - - public void setSystemLocationSettingEnabled(boolean enabled) throws RemoteException { - mITestWebLayer.setSystemLocationSettingEnabled(enabled); - } - - // Runs |runnable| when cc::RenderFrameMetadata's |top_controls_height| and - // |bottom_controls_height| matches the supplied values. |runnable| may be run synchronously. - public void waitForBrowserControlsMetadataState(Tab tab, int top, int bottom, Runnable runnable) - throws RemoteException { - mITestWebLayer.waitForBrowserControlsMetadataState( - tab.getITab(), top, bottom, ObjectWrapper.wrap(runnable)); - } - - public void setAccessibilityEnabled(boolean enabled) throws RemoteException { - mITestWebLayer.setAccessibilityEnabled(enabled); - } - - public void addInfoBar(Tab tab, Runnable runnable) throws RemoteException { - mITestWebLayer.addInfoBar(tab.getITab(), ObjectWrapper.wrap(runnable)); - } - - public View getInfoBarContainerView(Tab tab) throws RemoteException { - return (View) ObjectWrapper.unwrap( - mITestWebLayer.getInfoBarContainerView(tab.getITab()), View.class); - } - - public void setIgnoreMissingKeyForTranslateManager(boolean ignore) throws RemoteException { - mITestWebLayer.setIgnoreMissingKeyForTranslateManager(ignore); - } - - public void forceNetworkConnectivityState(boolean networkAvailable) throws RemoteException { - mITestWebLayer.forceNetworkConnectivityState(networkAvailable); - } - - public boolean canInfoBarContainerScroll(Tab tab) throws RemoteException { - return mITestWebLayer.canInfoBarContainerScroll(tab.getITab()); - } - - public String getTranslateInfoBarTargetLanguage(Tab tab) throws RemoteException { - return mITestWebLayer.getTranslateInfoBarTargetLanguage(tab.getITab()); - } - - public static void disableWebViewCompatibilityMode() { - WebLayer.disableWebViewCompatibilityMode(); - } - - public static void setupWeblayerForBrowserTest(Context application, Callback<View> callback) { - WebLayer.loadAsync(application, webLayer -> { - Bundle args = new Bundle(); - args.putString(BrowserFragmentArgs.PROFILE_NAME, "browsertest"); - args.putBoolean(BrowserFragmentArgs.IS_INCOGNITO, false); - - Browser browser = new Browser(webLayer.createBrowser(application, args)); - - WebFragmentEventHandler eventHandler = - new WebFragmentEventHandler(browser.connectFragment()); - browser.initializeState(); - eventHandler.onAttach(application, null); - eventHandler.onCreate(); - eventHandler.onStart(); - eventHandler.onResume(); - - callback.onResult(eventHandler.getContentViewRenderView()); - }); - } - - public boolean didShowFullscreenToast(Tab tab) throws RemoteException { - return mITestWebLayer.didShowFullscreenToast(tab.getITab()); - } - - public void initializeMockMediaRouteProvider(boolean closeRouteWithErrorOnSend, - boolean disableIsSupportsSource, @Nullable String createRouteErrorMessage, - @Nullable String joinRouteErrorMessage) throws RemoteException { - mITestWebLayer.initializeMockMediaRouteProvider(closeRouteWithErrorOnSend, - disableIsSupportsSource, createRouteErrorMessage, joinRouteErrorMessage); - } - - public View getMediaRouteButton(String name) throws RemoteException { - return (View) ObjectWrapper.unwrap(mITestWebLayer.getMediaRouteButton(name), View.class); - } - - public void crashTab(Tab tab) throws RemoteException { - mITestWebLayer.crashTab(tab.getITab()); - } - - public boolean isWindowOnSmallDevice(Browser browser) throws RemoteException { - return mITestWebLayer.isWindowOnSmallDevice(browser.getIBrowser()); - } - - public void fetchAccessToken(Profile profile, Set<String> scopes, - Callback<String> onTokenFetched) throws RemoteException { - ValueCallback<String> valueCallback = (String token) -> { - onTokenFetched.onResult(token); - }; - mITestWebLayer.fetchAccessToken(profile.getIProfile(), ObjectWrapper.wrap(scopes), - ObjectWrapper.wrap(valueCallback)); - } - - public void addContentCaptureConsumer(Browser browser, Runnable runnable, - ArrayList<Integer> callbacks) throws RemoteException { - mITestWebLayer.addContentCaptureConsumer( - browser.getIBrowser(), ObjectWrapper.wrap(runnable), ObjectWrapper.wrap(callbacks)); - } - - public void notifyOfAutofillEvents(Browser browser, Runnable onNewEvent, - ArrayList<Integer> eventsObserved) throws RemoteException { - mITestWebLayer.notifyOfAutofillEvents(browser.getIBrowser(), ObjectWrapper.wrap(onNewEvent), - ObjectWrapper.wrap(eventsObserved)); - } - - public void activateBackgroundFetchNotification(int id) throws RemoteException { - mITestWebLayer.activateBackgroundFetchNotification(id); - } - - public void expediteDownloadService() throws RemoteException { - mITestWebLayer.expediteDownloadService(); - } - - public void setMockWebAuthnEnabled(boolean enabled) throws RemoteException { - mITestWebLayer.setMockWebAuthnEnabled(enabled); - } - - public void fireOnAccessTokenIdentifiedAsInvalid( - Profile profile, Set<String> scopes, String token) throws RemoteException { - mITestWebLayer.fireOnAccessTokenIdentifiedAsInvalid( - profile.getIProfile(), ObjectWrapper.wrap(scopes), ObjectWrapper.wrap(token)); - } - - public void grantLocationPermission(String url) throws RemoteException { - mITestWebLayer.grantLocationPermission(url); - } - - public void setTextScaling(Profile profile, float value) throws RemoteException { - mITestWebLayer.setTextScaling(profile.getIProfile(), value); - } - - public boolean getForceEnableZoom(Profile profile) throws RemoteException { - return mITestWebLayer.getForceEnableZoom(profile.getIProfile()); - } -}
diff --git a/weblayer/public/main.h b/weblayer/public/main.h deleted file mode 100644 index 0a521d6..0000000 --- a/weblayer/public/main.h +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_MAIN_H_ -#define WEBLAYER_PUBLIC_MAIN_H_ - -#include <string> - -#include "base/files/file.h" -#include "base/functional/callback_forward.h" -#include "base/memory/raw_ptr.h" -#include "build/build_config.h" - -#if BUILDFLAG(IS_WIN) -#include <windows.h> -#endif - -namespace weblayer { - -class MainDelegate { - public: - virtual void PreMainMessageLoopRun() = 0; - virtual void PostMainMessageLoopRun() = 0; - virtual void SetMainMessageLoopQuitClosure( - base::OnceClosure quit_closure) = 0; -}; - -struct MainParams { - MainParams(); - MainParams(const MainParams& other); - ~MainParams(); - - raw_ptr<MainDelegate> delegate; - - // If set, logging will redirect to this file. - base::FilePath log_filename; - - // The name of the file that has the PAK data. - std::string pak_name; -}; - -int Main(MainParams params -#if BUILDFLAG(IS_WIN) -#if !defined(WIN_CONSOLE_APP) - , - HINSTANCE instance -#endif -#else - , - int argc, - const char** argv -#endif -); - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_MAIN_H_
diff --git a/weblayer/public/navigation.h b/weblayer/public/navigation.h deleted file mode 100644 index 250707f..0000000 --- a/weblayer/public/navigation.h +++ /dev/null
@@ -1,188 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_NAVIGATION_H_ -#define WEBLAYER_PUBLIC_NAVIGATION_H_ - -#include <string> -#include <vector> - -class GURL; - -namespace net { -class HttpResponseHeaders; -} - -namespace weblayer { -class Page; - -// These types are sent over IPC and across different versions. Never remove -// or change the order. -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private -// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplNavigationState -enum class NavigationState { - // Waiting to receive initial response data. - kWaitingResponse = 0, - // Processing the response. - kReceivingBytes = 1, - // The navigation succeeded. Any NavigationObservers would have had - // NavigationCompleted() called. - kComplete = 2, - // The navigation failed. This could be because of an error (in which case - // IsErrorPage() will return true) or the navigation got turned into a - // download (in which case IsDownload() will return true). - // NavigationObservers would have had NavigationFailed() called. - kFailed = 3, -}; - -class Navigation { - public: - virtual ~Navigation() {} - - // The URL the frame is navigating to. This may change during the navigation - // when encountering a server redirect. - virtual GURL GetURL() = 0; - - // Returns the redirects that occurred on the way to the current page. The - // current page is the last one in the list (so even when there's no redirect, - // there will be one entry in the list). - virtual const std::vector<GURL>& GetRedirectChain() = 0; - - virtual NavigationState GetState() = 0; - - // Returns the status code of the navigation. Returns 0 if the navigation - // hasn't completed yet or if a response wasn't received. - virtual int GetHttpStatusCode() = 0; - - // Returns the HTTP response headers. Returns nullptr if the navigation - // hasn't completed yet or if a response wasn't received. - virtual const net::HttpResponseHeaders* GetResponseHeaders() = 0; - - // Whether the navigation happened without changing document. Examples of - // same document navigations are: - // * reference fragment navigations - // * pushState/replaceState - // * same page history navigation - virtual bool IsSameDocument() = 0; - - // Whether the navigation resulted in an error page (e.g. interstitial). Note - // that if an error page reloads, this will return true even though - // GetNetErrorCode will be kNoError. - virtual bool IsErrorPage() = 0; - - // Returns true if this navigation resulted in a download. Returns false if - // this navigation did not result in a download, or if download status is not - // yet known for this navigation. Download status is determined for a - // navigation when processing final (post redirect) HTTP response headers. - // This means the only time the embedder can know if it's a download is in - // NavigationObserver::NavigationFailed. - virtual bool IsDownload() = 0; - - // Whether the target URL can be handled by the browser's internal protocol - // handlers, i.e., has a scheme that the browser knows how to process - // internally. Examples of such URLs are http(s) URLs, data URLs, and file - // URLs. A typical example of a URL for which there is no internal protocol - // handler (and for which this method would return false) is an intent:// URL. - // Added in 89. - virtual bool IsKnownProtocol() = 0; - - // Returns true if the navigation was stopped before it could complete because - // NavigationController::Stop() was called. - virtual bool WasStopCalled() = 0; - - // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private - // GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplLoadError - enum LoadError { - kNoError = 0, // Navigation completed successfully. - kHttpClientError = 1, // Server responded with 4xx status code. - kHttpServerError = 2, // Server responded with 5xx status code. - kSSLError = 3, // Certificate error. - kConnectivityError = 4, // Problem connecting to server. - kOtherError = 5, // An error not listed above or below occurred. - kSafeBrowsingError = 6, // Safe browsing error. - }; - - // Return information about the error, if any, that was encountered while - // loading the page. - virtual LoadError GetLoadError() = 0; - - // Set a request's header. If the header is already present, its value is - // overwritten. This function can only be called at two times, during start - // and redirect. When called during start, the header applies to both the - // start and redirect. |name| must be rfc 2616 compliant and |value| must - // not contain '\0', '\n' or '\r'. - // - // This function may be used to set the referer. If the referer is set in - // navigation start, it is reset during the redirect. In other words, if you - // need to set a referer that applies to redirects, then this must be called - // from NavigationRedirected(). - virtual void SetRequestHeader(const std::string& name, - const std::string& value) = 0; - - // Sets the user-agent string used for this navigation. The user-agent is - // not sticky, it applies to this navigation only (and any redirects). This - // function may only be called from NavigationObserver::NavigationStarted(). - // Any value specified during start carries through to a redirect. |value| - // must not contain any illegal characters as documented in - // SetRequestHeader(). Setting this to a non empty string will cause the - // User-Agent Client Hint header values and the values returned by - // `navigator.userAgentData` to be empty for requests this override is applied - // to. - virtual void SetUserAgentString(const std::string& value) = 0; - - // Disables auto-reload for this navigation if the network is down and comes - // back later. Auto-reload is enabled by default. This function may only be - // called from NavigationObserver::NavigationStarted(). - virtual void DisableNetworkErrorAutoReload() = 0; - - // Whether the navigation was initiated by the page. Examples of - // page-initiated navigations include: - // * <a> link click - // * changing window.location.href - // * redirect via the <meta http-equiv="refresh"> tag - // * using window.history.pushState - // * window.history.forward() or window.history.back() - // - // This method returns false for navigations initiated by the WebLayer API. - virtual bool IsPageInitiated() = 0; - - // Whether the navigation is a reload. Examples of reloads include: - // * embedder-specified through NavigationController::Reload - // * page-initiated reloads, e.g. location.reload() - // * reloads when the network interface is reconnected - virtual bool IsReload() = 0; - - // Whether the navigation is restoring a page from back-forward cache (see - // https://web.dev/bfcache/). Since a previously loaded page is being reused, - // there are some things embedders have to keep in mind such as: - // * there will be no NavigationObserver::OnFirstContentfulPaint callbacks - // * if an embedder injects code using Tab::ExecuteScript there is no need - // to reinject scripts - virtual bool IsServedFromBackForwardCache() = 0; - - // Returns true if this navigation was initiated by a form submission. - virtual bool IsFormSubmission() = 0; - - // Returns the referrer for this request. - virtual GURL GetReferrer() = 0; - - // Returns the Page object this navigation is occurring for. This method may - // only be called in or after NavigationObserver::NavigationCompleted() or - // NavigationObserve::NavigationFailed(). It can return null if the navigation - // didn't commit (e.g. 204/205 or download). - virtual Page* GetPage() = 0; - - // Returns the offset between the indices of the previous last committed and - // the newly committed navigation entries (e.g. -1 for back navigations, 0 - // for reloads, 1 for forward navigations). This may not cover all corner - // cases, and can be incorrect in cases like main frame client redirects. - virtual int GetNavigationEntryOffset() = 0; - - // Returns true if the navigation response was fetched from the cache. - virtual bool WasFetchedFromCache() = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_NAVIGATION_H_
diff --git a/weblayer/public/navigation_controller.h b/weblayer/public/navigation_controller.h deleted file mode 100644 index d2306950..0000000 --- a/weblayer/public/navigation_controller.h +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_NAVIGATION_CONTROLLER_H_ -#define WEBLAYER_PUBLIC_NAVIGATION_CONTROLLER_H_ - -#include <algorithm> -#include <string> - -class GURL; - -namespace weblayer { -class NavigationObserver; - -class NavigationController { - public: - // The members of this struct and their defaults should be kept in sync with - // |NavigationController::LoadURLParams|. - struct NavigateParams { - bool should_replace_current_entry = false; - bool enable_auto_play = false; - }; - - virtual ~NavigationController() = default; - - virtual void AddObserver(NavigationObserver* observer) = 0; - - virtual void RemoveObserver(NavigationObserver* observer) = 0; - - virtual void Navigate(const GURL& url) = 0; - - virtual void Navigate(const GURL& url, const NavigateParams& params) = 0; - - virtual void GoBack() = 0; - - virtual void GoForward() = 0; - - virtual bool CanGoBack() = 0; - - virtual bool CanGoForward() = 0; - - // Navigates to the specified absolute index. - virtual void GoToIndex(int index) = 0; - - virtual void Reload() = 0; - - virtual void Stop() = 0; - - // Gets the number of entries in the back/forward list. - virtual int GetNavigationListSize() = 0; - - // Gets the index of the current entry in the back/forward list, or -1 if - // there are no entries. - virtual int GetNavigationListCurrentIndex() = 0; - - // Gets the URL of the given entry in the back/forward list, or an empty GURL - // if there is no navigation entry at that index. - virtual GURL GetNavigationEntryDisplayURL(int index) = 0; - - // Gets the page title of the given entry in the back/forward list, or an - // empty string if there is no navigation entry at that index. - virtual std::string GetNavigationEntryTitle(int index) = 0; - - // Returns whether this entry will be skipped on a call to GoBack() or - // GoForward(). This will be true for navigations that were done without a - // user gesture, including both client side redirects and history.pushState. - virtual bool IsNavigationEntrySkippable(int index) = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_NAVIGATION_CONTROLLER_H_
diff --git a/weblayer/public/navigation_observer.h b/weblayer/public/navigation_observer.h deleted file mode 100644 index da2c791..0000000 --- a/weblayer/public/navigation_observer.h +++ /dev/null
@@ -1,132 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_NAVIGATION_OBSERVER_H_ -#define WEBLAYER_PUBLIC_NAVIGATION_OBSERVER_H_ - -class GURL; - -namespace base { -class TimeDelta; -class TimeTicks; -} // namespace base - -namespace weblayer { -class Navigation; -class Page; - -// An interface for a WebLayer embedder to get notified about navigations. For -// now this only notifies for the main frame. -// -// The lifecycle of a navigation: -// 1) A navigation is initiated, such as by NavigationController::Navigate() -// or within the page -// 2) LoadStateChanged() first invoked -// 3) NavigationStarted -// 4) 0 or more NavigationRedirected -// 5) NavigationCompleted or NavigationFailed -// 6) Main frame completes loading, LoadStateChanged() last invoked -class NavigationObserver { - public: - virtual ~NavigationObserver() {} - - // Called when a navigation started in the Tab. |navigation| is - // unique to a specific navigation. The same |navigation| will be provided on - // subsequent calls to NavigationRedirected, NavigationCommitted, - // NavigationCompleted and NavigationFailed when related to this navigation. - // Observers should clear any references to |navigation| in - // NavigationCompleted or NavigationFailed, just before it is destroyed. - // - // Note that this is only fired by navigations in the main frame. - // - // Note that this is fired by same-document navigations, such as fragment - // navigations or pushState/replaceState, which will not result in a document - // change. To filter these out, use Navigation::IsSameDocument. - // - // Note that more than one navigation can be ongoing in the Tab - // at the same time. Each will get its own Navigation object. - // - // Note that there is no guarantee that NavigationCompleted/NavigationFailed - // will be called for any particular navigation before NavigationStarted is - // called on the next. - virtual void NavigationStarted(Navigation* navigation) {} - - // Called when a navigation encountered a server redirect. - virtual void NavigationRedirected(Navigation* navigation) {} - - // Called when a navigation completes successfully in the Tab. - // - // The document load will still be ongoing in the Tab. Use the - // document loads events such as OnFirstContentfulPaint and related methods to - // listen for continued events from this Tab. - // - // Note that this is fired by same-document navigations, such as fragment - // navigations or pushState/replaceState, which will not result in a document - // change. To filter these out, use NavigationHandle::IsSameDocument. - // - // Note that |navigation| will be destroyed at the end of this call, so do not - // keep a reference to it afterward. - virtual void NavigationCompleted(Navigation* navigation) {} - - // Called when a navigation aborts in the Tab. - // - // Note that |navigation| will be destroyed at the end of this call, so do not - // keep a reference to it afterward. - virtual void NavigationFailed(Navigation* navigation) {} - - // Indicates that loading has started (|is_loading| is true) or is done - // (|is_loading| is false). |should_show_loading_ui| will be true unless the - // load is a fragment navigation, or triggered by - // history.pushState/replaceState. - virtual void LoadStateChanged(bool is_loading, bool should_show_loading_ui) {} - - // Indicates that the load progress of the page has changed. |progress| - // ranges from 0.0 to 1.0. - virtual void LoadProgressChanged(double progress) {} - - // This is fired after each navigation has completed to indicate that the - // first paint after a non-empty layout has finished. - virtual void OnFirstContentfulPaint() {} - - // Similar to OnFirstContentfulPaint but contains timing information from the - // renderer process to better align with the Navigation Timing API. - // |navigation_start| is the navigation start time. - // |first_contentful_paint| is the duration to first contentful paint from - // navigation start. - virtual void OnFirstContentfulPaint( - const base::TimeTicks& navigation_start, - const base::TimeDelta& first_contentful_paint) {} - - // This is fired when the largest contentful paint page load metric is - // available. |navigation_start| is the navigation start time. - // |largest_contentful_paint| is the duration to largest contentful paint from - // navigation start. - virtual void OnLargestContentfulPaint( - const base::TimeTicks& navigation_start, - const base::TimeDelta& largest_contentful_paint) {} - - // Called after each navigation to indicate that the old page is no longer - // being rendered. Note this is not ordered with respect to - // OnFirstContentfulPaint. - virtual void OnOldPageNoLongerRendered(const GURL& url) {} - - // Called when a Page is destroyed. For the common case, this is called when - // the user navigates away from a page to a new one or when the Tab is - // destroyed. However there are situations when a page is alive when it's not - // visible, e.g. when it goes into the back-forward cache. In that case this - // method will either be called when the back-forward cache entry is evicted - // or if it is used then this cycle repeats. - virtual void OnPageDestroyed(Page* page) {} - - // Called when the source language for |page| has been determined to be - // |language|. - // Note: |language| is an ISO 639 language code (two letters, except for - // Chinese where a localization is necessary). - virtual void OnPageLanguageDetermined(Page* page, - const std::string& language) {} -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_NAVIGATION_OBSERVER_H_
diff --git a/weblayer/public/new_tab_delegate.h b/weblayer/public/new_tab_delegate.h deleted file mode 100644 index 02bb2e9..0000000 --- a/weblayer/public/new_tab_delegate.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_NEW_TAB_DELEGATE_H_ -#define WEBLAYER_PUBLIC_NEW_TAB_DELEGATE_H_ - -namespace weblayer { - -class Tab; - -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private -// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplNewTabType -// Corresponds to type of browser the page requested. -enum class NewTabType { - // The new browser should be opened in the foreground. - kForeground = 0, - - // The new browser should be opened in the foreground. - kBackground, - - // The page requested the browser be shown in a new window with minimal - // browser UI. For example, no tabstrip. - kNewPopup, - - // The page requested the browser be shown in a new window. - kNewWindow, -}; - -// An interface that allows clients to handle requests for new browsers, or -// in web terms, a new popup/window (and random other things). -class NewTabDelegate { - public: - // Called when a new tab is created by the browser. |new_tab| is owned by the - // browser. - virtual void OnNewTab(Tab* new_tab, NewTabType type) = 0; - - protected: - virtual ~NewTabDelegate() {} -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_NEW_TAB_DELEGATE_H_
diff --git a/weblayer/public/page.h b/weblayer/public/page.h deleted file mode 100644 index 0722e32..0000000 --- a/weblayer/public/page.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_PAGE_H_ -#define WEBLAYER_PUBLIC_PAGE_H_ - -namespace weblayer { - -// This objects tracks the lifetime of a loaded web page. Most of the time there -// is only one Page object per tab. However features like back-forward cache, -// prerendering etc... sometime involve the creation of additional Page objects. -// Navigation::getPage() will return the Page for a given navigation. Similarly -// it'll be the same Page object that's passed in -// NavigationObserver::OnPageDestroyed(). -class Page { - protected: - virtual ~Page() = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_PAGE_H_
diff --git a/weblayer/public/prerender_controller.h b/weblayer/public/prerender_controller.h deleted file mode 100644 index c71bbdb..0000000 --- a/weblayer/public/prerender_controller.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_PRERENDER_CONTROLLER_H_ -#define WEBLAYER_PUBLIC_PRERENDER_CONTROLLER_H_ - -class GURL; - -namespace weblayer { - -// PrerenderController enables prerendering of urls. -// Prerendering has the same effect as adding a link rel="prerender" resource -// hint to a web page. It is implemented using NoStatePrefetch and fetches -// resources needed for a url in advance, but does not execute Javascript or -// render any part of the page in advance. For more information on -// NoStatePrefetch, see -// https://developers.google.com/web/updates/2018/07/nostate-prefetch. -class PrerenderController { - public: - virtual void Prerender(const GURL& url) = 0; - virtual void DestroyAllContents() = 0; - - protected: - virtual ~PrerenderController() = default; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_PRERENDER_CONTROLLER_H_
diff --git a/weblayer/public/profile.h b/weblayer/public/profile.h deleted file mode 100644 index fb8fc87a..0000000 --- a/weblayer/public/profile.h +++ /dev/null
@@ -1,130 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_PROFILE_H_ -#define WEBLAYER_PUBLIC_PROFILE_H_ - -#include <memory> -#include <string> - -#include "base/containers/flat_set.h" -#include "base/functional/callback_forward.h" -#include "base/time/time.h" - -namespace base { -class FilePath; -} - -namespace gfx { -class Image; -} - -class GURL; - -namespace weblayer { -class CookieManager; -class DownloadDelegate; -class GoogleAccountAccessTokenFetchDelegate; -class PrerenderController; - -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private -// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplBrowsingDataType -enum class BrowsingDataType { - COOKIES_AND_SITE_DATA = 0, - CACHE = 1, - SITE_SETTINGS = 2, -}; - -// Used for setting/getting profile related settings. -enum class SettingType { - BASIC_SAFE_BROWSING_ENABLED = 0, - UKM_ENABLED = 1, - EXTENDED_REPORTING_SAFE_BROWSING_ENABLED = 2, - REAL_TIME_SAFE_BROWSING_ENABLED = 3, - NETWORK_PREDICTION_ENABLED = 4, -}; - -class Profile { - public: - // Creates a new profile. - static std::unique_ptr<Profile> Create(const std::string& name, - bool is_incognito); - - // Delete all profile's data from disk. If there are any existing usage - // of this profile, return |profile| immediately and |done_callback| will not - // be called. Otherwise return nullptr and |done_callback| is called when - // deletion is complete. - static std::unique_ptr<Profile> DestroyAndDeleteDataFromDisk( - std::unique_ptr<Profile> profile, - base::OnceClosure done_callback); - - virtual ~Profile() {} - - virtual void ClearBrowsingData( - const std::vector<BrowsingDataType>& data_types, - base::Time from_time, - base::Time to_time, - base::OnceClosure callback) = 0; - - // Allows embedders to override the default download directory, which is the - // system download directory on Android and on other platforms it's in the - // home directory. - virtual void SetDownloadDirectory(const base::FilePath& directory) = 0; - - // Sets the DownloadDelegate. If none is set, downloads will be dropped. - virtual void SetDownloadDelegate(DownloadDelegate* delegate) = 0; - - // Sets the delegate for access token fetches. If none is set, the browser - // will not be able to fetch access tokens. - virtual void SetGoogleAccountAccessTokenFetchDelegate( - GoogleAccountAccessTokenFetchDelegate* delegate) = 0; - - // Gets the cookie manager for this profile. - virtual CookieManager* GetCookieManager() = 0; - - // Gets the prerender controller for this profile. - virtual PrerenderController* GetPrerenderController() = 0; - - // Asynchronously fetches the set of known Browser persistence-ids. See - // Browser::PersistenceInfo for more details on persistence-ids. - virtual void GetBrowserPersistenceIds( - base::OnceCallback<void(base::flat_set<std::string>)> callback) = 0; - - // Asynchronously removes the storage associated with the set of - // Browser persistence-ids. This ignores ids actively in use. |done_callback| - // is run with the result of the operation (on the main thread). A value of - // true means all files were removed. A value of false indicates at least one - // of the files could not be removed. - virtual void RemoveBrowserPersistenceStorage( - base::OnceCallback<void(bool)> done_callback, - base::flat_set<std::string> ids) = 0; - - // Set the boolean value of the given setting type. - virtual void SetBooleanSetting(SettingType type, bool value) = 0; - - // Get the boolean value of the given setting type. - virtual bool GetBooleanSetting(SettingType type) = 0; - - // Returns the cached favicon for the specified url. Off the record profiles - // do not cache favicons. If this is called on an off-the-record profile - // the callback is run with an empty image synchronously. The returned image - // matches that returned by FaviconFetcher. - virtual void GetCachedFaviconForPageUrl( - const GURL& page_url, - base::OnceCallback<void(gfx::Image)> callback) = 0; - - // For cross-origin navigations, the implementation may leverage a separate OS - // process for stronger isolation. If an embedder knows that a cross-origin - // navigation is likely starting soon, they can call this method as a hint to - // the implementation to start a fresh OS process. A subsequent navigation may - // use this preinitialized process, improving performance. It is safe to call - // this multiple times or when it is not certain that the spare renderer will - // be used, although calling this too eagerly may reduce performance as - // unnecessary processes are created. - virtual void PrepareForPossibleCrossOriginNavigation() = 0; -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_PROFILE_H_
diff --git a/weblayer/public/tab.h b/weblayer/public/tab.h deleted file mode 100644 index c61a6e4a..0000000 --- a/weblayer/public/tab.h +++ /dev/null
@@ -1,126 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_TAB_H_ -#define WEBLAYER_PUBLIC_TAB_H_ - -#include <algorithm> -#include <map> -#include <string> -#include <vector> - -#include "base/functional/callback_forward.h" -#include "build/build_config.h" - -namespace base { -class Value; -} - -#if !BUILDFLAG(IS_ANDROID) -namespace views { -class WebView; -} -#endif - -namespace weblayer { -class Browser; -class ErrorPageDelegate; -class FaviconFetcher; -class FaviconFetcherDelegate; -class FullscreenDelegate; -class GoogleAccountsDelegate; -class NavigationController; -class NewTabDelegate; -class TabObserver; - -// Represents a tab that is navigable. -class Tab { - public: - virtual ~Tab() = default; - - // Returns the Browser that owns this. - virtual Browser* GetBrowser() = 0; - - // Sets the ErrorPageDelegate. If none is set, a default action will be taken - // for any given interaction with an error page. - virtual void SetErrorPageDelegate(ErrorPageDelegate* delegate) = 0; - - // Sets the FullscreenDelegate. Setting a non-null value implicitly enables - // fullscreen. - virtual void SetFullscreenDelegate(FullscreenDelegate* delegate) = 0; - - // Sets the NewBrowserDelegate. Setting a null value implicitly disables - // popups. - virtual void SetNewTabDelegate(NewTabDelegate* delegate) = 0; - - virtual void SetGoogleAccountsDelegate(GoogleAccountsDelegate* delegate) = 0; - - virtual void AddObserver(TabObserver* observer) = 0; - - virtual void RemoveObserver(TabObserver* observer) = 0; - - virtual NavigationController* GetNavigationController() = 0; - - using JavaScriptResultCallback = base::OnceCallback<void(base::Value)>; - - // Executes the script, and returns the result to the callback if provided. If - // |use_separate_isolate| is true, runs the script in a separate v8 Isolate. - // This uses more memory, but separates the injected scrips from scripts in - // the page. This prevents any potentially malicious interaction between - // first-party scripts in the page, and injected scripts. Use with caution, - // only pass false for this argument if you know this isn't an issue or you - // need to interact with first-party scripts. - virtual void ExecuteScript(const std::u16string& script, - bool use_separate_isolate, - JavaScriptResultCallback callback) = 0; - - // Returns the tab's guid. - virtual const std::string& GetGuid() = 0; - - // Allows the embedder to get and set arbitrary data on the tab. This will be - // saved and restored with the browser, so it is important to keep this data - // as small as possible. - virtual void SetData(const std::map<std::string, std::string>& data) = 0; - virtual const std::map<std::string, std::string>& GetData() = 0; - - // Creates a FaviconFetcher that notifies a FaviconFetcherDelegate when - // the favicon changes. - // A page may provide any number of favicons. The preferred image size - // used depends upon the platform. If a previously cached icon is available, - // it is used, otherwise the icon is downloaded. - // |delegate| may be called multiple times for the same navigation. This - // happens when the page dynamically updates the favicon, but may also happen - // if a cached icon is determined to be out of date. - virtual std::unique_ptr<FaviconFetcher> CreateFaviconFetcher( - FaviconFetcherDelegate* delegate) = 0; - - // Sets the target language for translation such that whenever the translate - // UI shows in this Tab, the target language will be |targetLanguage|. Notes: - // - |targetLanguage| should be specified as the language code (e.g., "de" for - // German). - // - Passing an empty string causes behavior to revert to default. - // - Specifying a non-empty target language will also result in the following - // behaviors (all of which are intentional as part of the semantics of - // having a target language): - // - Translation is initiated automatically (note that the infobar UI is - // present) - // - Translation occurs even for languages/sites that the user has - // blocklisted - // - Translation occurs even for pages in the user's default locale - // - Translation does *not* occur nor is the infobar UI shown for pages in - // the specified target language - virtual void SetTranslateTargetLanguage( - const std::string& translate_target_lang) = 0; - -#if !BUILDFLAG(IS_ANDROID) - // TODO: this isn't a stable API, so use it now for expediency in the C++ API, - // but if we ever want to have backward or forward compatibility in C++ this - // will have to be something else. - virtual void AttachToView(views::WebView* web_view) = 0; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_TAB_H_
diff --git a/weblayer/public/tab_observer.h b/weblayer/public/tab_observer.h deleted file mode 100644 index 4b04dcb4d..0000000 --- a/weblayer/public/tab_observer.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_PUBLIC_TAB_OBSERVER_H_ -#define WEBLAYER_PUBLIC_TAB_OBSERVER_H_ - -#include <string> - - -class GURL; - -namespace weblayer { - -class TabObserver { - public: - // The URL bar should be updated to |url|. - virtual void DisplayedUrlChanged(const GURL& url) {} - - // Triggered when the render process dies, either due to crash or killed by - // the system to reclaim memory. - virtual void OnRenderProcessGone() {} - - // Called when the title of this tab changes. Note before the page sets a - // title, the title may be a portion of the Uri. - virtual void OnTitleUpdated(const std::u16string& title) {} - - protected: - virtual ~TabObserver() {} -}; - -} // namespace weblayer - -#endif // WEBLAYER_PUBLIC_TAB_OBSERVER_H_
diff --git a/weblayer/renderer/DEPS b/weblayer/renderer/DEPS deleted file mode 100644 index 178aca55..0000000 --- a/weblayer/renderer/DEPS +++ /dev/null
@@ -1,37 +0,0 @@ -include_rules = [ - "+components/android_system_error_page", - "+components/autofill/core/common", - "+components/autofill/content/renderer", - "+components/cdm/renderer", - "+components/content_capture/common", - "+components/content_capture/renderer", - "+components/content_settings/common", - "+components/content_settings/renderer", - "+components/error_page/common", - "+components/grit", - "+components/page_load_metrics/renderer", - "+components/no_state_prefetch/common", - "+components/no_state_prefetch/renderer", - "+components/safe_browsing/buildflags.h", - "+components/safe_browsing/content/common", - "+components/safe_browsing/content/renderer", - "+components/safe_browsing/core/common", - "+components/security_interstitials/content/renderer", - "+components/security_interstitials/core/common", - "+components/spellcheck/renderer", - "+components/subresource_filter/content/renderer", - "+components/subresource_filter/core/common", - "+components/translate/content/renderer", - "+components/translate/core/common", - "+components/webapps/renderer", - "+content/public/common", - "+content/public/renderer", - # needed for safebrowsing - "+mojo/public/cpp/bindings", - "+net/base", - "+services/service_manager/public/cpp", - "+third_party/blink/public/common", - "+third_party/blink/public/platform", - "+third_party/blink/public/web", - "+ui/base", -]
diff --git a/weblayer/renderer/content_renderer_client_impl.cc b/weblayer/renderer/content_renderer_client_impl.cc deleted file mode 100644 index 2eba353..0000000 --- a/weblayer/renderer/content_renderer_client_impl.cc +++ /dev/null
@@ -1,261 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/renderer/content_renderer_client_impl.h" - -#include "base/feature_list.h" -#include "build/build_config.h" -#include "components/autofill/content/renderer/autofill_agent.h" -#include "components/autofill/content/renderer/password_autofill_agent.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/content_capture/common/content_capture_features.h" -#include "components/content_capture/renderer/content_capture_sender.h" -#include "components/content_settings/renderer/content_settings_agent_impl.h" -#include "components/error_page/common/error.h" -#include "components/grit/components_scaled_resources.h" -#include "components/no_state_prefetch/common/prerender_url_loader_throttle.h" -#include "components/no_state_prefetch/renderer/no_state_prefetch_client.h" -#include "components/no_state_prefetch/renderer/no_state_prefetch_helper.h" -#include "components/no_state_prefetch/renderer/no_state_prefetch_utils.h" -#include "components/no_state_prefetch/renderer/prerender_render_frame_observer.h" -#include "components/page_load_metrics/renderer/metrics_render_frame_observer.h" -#include "components/subresource_filter/content/renderer/ad_resource_tracker.h" -#include "components/subresource_filter/content/renderer/subresource_filter_agent.h" -#include "components/subresource_filter/content/renderer/unverified_ruleset_dealer.h" -#include "components/subresource_filter/core/common/common_features.h" -#include "components/webapps/renderer/web_page_metadata_agent.h" -#include "content/public/renderer/render_frame.h" -#include "content/public/renderer/render_thread.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_runtime_features.h" -#include "ui/base/resource/resource_bundle.h" -#include "weblayer/common/features.h" -#include "weblayer/renderer/error_page_helper.h" -#include "weblayer/renderer/url_loader_throttle_provider.h" -#include "weblayer/renderer/weblayer_render_frame_observer.h" -#include "weblayer/renderer/weblayer_render_thread_observer.h" - -#if BUILDFLAG(IS_ANDROID) -#include "components/android_system_error_page/error_page_populator.h" -#include "components/cdm/renderer/android_key_systems.h" -#include "components/spellcheck/renderer/spellcheck.h" // nogncheck -#include "components/spellcheck/renderer/spellcheck_provider.h" // nogncheck -#include "content/public/common/url_constants.h" -#include "content/public/renderer/render_thread.h" -#include "services/service_manager/public/cpp/local_interface_provider.h" -#include "third_party/blink/public/platform/web_runtime_features.h" -#include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/public/web/web_security_policy.h" -#endif - -namespace weblayer { - -namespace { - -#if BUILDFLAG(IS_ANDROID) -class SpellcheckInterfaceProvider - : public service_manager::LocalInterfaceProvider { - public: - SpellcheckInterfaceProvider() = default; - - SpellcheckInterfaceProvider(const SpellcheckInterfaceProvider&) = delete; - SpellcheckInterfaceProvider& operator=(const SpellcheckInterfaceProvider&) = - delete; - - ~SpellcheckInterfaceProvider() override = default; - - // service_manager::LocalInterfaceProvider: - void GetInterface(const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) override { - // A dirty hack to make SpellCheckHost requests work on WebLayer. - // TODO(crbug.com/806394): Use a WebView-specific service for SpellCheckHost - // and SafeBrowsing, instead of |content_browser|. - content::RenderThread::Get()->BindHostReceiver(mojo::GenericPendingReceiver( - interface_name, std::move(interface_pipe))); - } -}; -#endif // BUILDFLAG(IS_ANDROID) - -} // namespace - -ContentRendererClientImpl::ContentRendererClientImpl() = default; -ContentRendererClientImpl::~ContentRendererClientImpl() = default; - -void ContentRendererClientImpl::RenderThreadStarted() { -#if BUILDFLAG(IS_ANDROID) - if (!spellcheck_) { - local_interface_provider_ = std::make_unique<SpellcheckInterfaceProvider>(); - spellcheck_ = std::make_unique<SpellCheck>(local_interface_provider_.get()); - } - blink::WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer( - blink::WebString::FromUTF8(content::kAndroidAppScheme)); -#endif - - content::RenderThread* thread = content::RenderThread::Get(); - weblayer_observer_ = std::make_unique<WebLayerRenderThreadObserver>(); - thread->AddObserver(weblayer_observer_.get()); - - browser_interface_broker_ = - blink::Platform::Current()->GetBrowserInterfaceBroker(); - - subresource_filter_ruleset_dealer_ = - std::make_unique<subresource_filter::UnverifiedRulesetDealer>(); - thread->AddObserver(subresource_filter_ruleset_dealer_.get()); -} - -void ContentRendererClientImpl::RenderFrameCreated( - content::RenderFrame* render_frame) { - auto* render_frame_observer = new WebLayerRenderFrameObserver(render_frame); - new prerender::PrerenderRenderFrameObserver(render_frame); - - ErrorPageHelper::Create(render_frame); - - autofill::PasswordAutofillAgent* password_autofill_agent = - new autofill::PasswordAutofillAgent( - render_frame, render_frame_observer->associated_interfaces()); - new autofill::AutofillAgent(render_frame, password_autofill_agent, nullptr, - render_frame_observer->associated_interfaces()); - auto* agent = new content_settings::ContentSettingsAgentImpl( - render_frame, false /* should_whitelist */, - std::make_unique<content_settings::ContentSettingsAgentImpl::Delegate>()); - if (weblayer_observer_) { - if (weblayer_observer_->content_settings_manager()) { - mojo::Remote<content_settings::mojom::ContentSettingsManager> manager; - weblayer_observer_->content_settings_manager()->Clone( - manager.BindNewPipeAndPassReceiver()); - agent->SetContentSettingsManager(std::move(manager)); - } - } - - auto* metrics_render_frame_observer = - new page_load_metrics::MetricsRenderFrameObserver(render_frame); - - auto ad_resource_tracker = - std::make_unique<subresource_filter::AdResourceTracker>(); - metrics_render_frame_observer->SetAdResourceTracker( - ad_resource_tracker.get()); - auto* subresource_filter_agent = - new subresource_filter::SubresourceFilterAgent( - render_frame, subresource_filter_ruleset_dealer_.get(), - std::move(ad_resource_tracker)); - subresource_filter_agent->Initialize(); - -#if BUILDFLAG(IS_ANDROID) - // |SpellCheckProvider| manages its own lifetime (and destroys itself when the - // RenderFrame is destroyed). - new SpellCheckProvider(render_frame, spellcheck_.get(), - local_interface_provider_.get()); -#endif - - if (render_frame->IsMainFrame()) - new webapps::WebPageMetadataAgent(render_frame); - - if (content_capture::features::IsContentCaptureEnabledInWebLayer()) { - new content_capture::ContentCaptureSender( - render_frame, render_frame_observer->associated_interfaces()); - } - - if (!render_frame->IsMainFrame()) { - auto* main_frame_no_state_prefetch_helper = - prerender::NoStatePrefetchHelper::Get( - render_frame->GetMainRenderFrame()); - if (main_frame_no_state_prefetch_helper) { - // Avoid any race conditions from having the browser tell subframes that - // they're no-state prefetching. - new prerender::NoStatePrefetchHelper( - render_frame, - main_frame_no_state_prefetch_helper->histogram_prefix()); - } - } -} - -void ContentRendererClientImpl::WebViewCreated( - blink::WebView* web_view, - bool was_created_by_renderer, - const url::Origin* outermost_origin) { - new prerender::NoStatePrefetchClient(web_view); -} - -SkBitmap* ContentRendererClientImpl::GetSadPluginBitmap() { - return const_cast<SkBitmap*>(ui::ResourceBundle::GetSharedInstance() - .GetImageNamed(IDR_SAD_PLUGIN) - .ToSkBitmap()); -} - -SkBitmap* ContentRendererClientImpl::GetSadWebViewBitmap() { - return const_cast<SkBitmap*>(ui::ResourceBundle::GetSharedInstance() - .GetImageNamed(IDR_SAD_WEBVIEW) - .ToSkBitmap()); -} - -void ContentRendererClientImpl::PrepareErrorPage( - content::RenderFrame* render_frame, - const blink::WebURLError& error, - const std::string& http_method, - content::mojom::AlternativeErrorPageOverrideInfoPtr - alternative_error_page_info, - std::string* error_html) { - auto* error_page_helper = ErrorPageHelper::GetForFrame(render_frame); - if (error_page_helper) - error_page_helper->PrepareErrorPage(); - -#if BUILDFLAG(IS_ANDROID) - // This does nothing if |error_html| is non-null (which happens if the - // embedder injects an error page). - android_system_error_page::PopulateErrorPageHtml(error, error_html); -#endif -} - -std::unique_ptr<blink::URLLoaderThrottleProvider> -ContentRendererClientImpl::CreateURLLoaderThrottleProvider( - blink::URLLoaderThrottleProviderType provider_type) { - return std::make_unique<URLLoaderThrottleProvider>( - browser_interface_broker_.get(), provider_type); -} - -void ContentRendererClientImpl::GetSupportedKeySystems( - media::GetSupportedKeySystemsCB cb) { - media::KeySystemInfos key_systems; -#if BUILDFLAG(IS_ANDROID) -#if BUILDFLAG(ENABLE_WIDEVINE) - cdm::AddAndroidWidevine(&key_systems); -#endif // BUILDFLAG(ENABLE_WIDEVINE) - cdm::AddAndroidPlatformKeySystems(&key_systems); -#endif // BUILDFLAG(IS_ANDROID) - std::move(cb).Run(std::move(key_systems)); -} - -void ContentRendererClientImpl:: - SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() { - blink::WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(true); -#if BUILDFLAG(IS_ANDROID) - // Web Share is experimental by default, and explicitly enabled on Android - // (for both Chrome and WebLayer). - blink::WebRuntimeFeatures::EnableWebShare(true); -#endif - - if (base::FeatureList::IsEnabled(subresource_filter::kAdTagging)) { - blink::WebRuntimeFeatures::EnableAdTagging(true); - } - - if (base::FeatureList::IsEnabled( - autofill::features::kAutofillSharedAutofill)) { - blink::WebRuntimeFeatures::EnableSharedAutofill(true); - } -} - -bool ContentRendererClientImpl::IsPrefetchOnly( - content::RenderFrame* render_frame) { - return prerender::NoStatePrefetchHelper::IsPrefetching(render_frame); -} - -bool ContentRendererClientImpl::DeferMediaLoad( - content::RenderFrame* render_frame, - bool has_played_media_before, - base::OnceClosure closure) { - return prerender::DeferMediaLoad(render_frame, has_played_media_before, - std::move(closure)); -} - -} // namespace weblayer
diff --git a/weblayer/renderer/content_renderer_client_impl.h b/weblayer/renderer/content_renderer_client_impl.h deleted file mode 100644 index 336b9b0..0000000 --- a/weblayer/renderer/content_renderer_client_impl.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_RENDERER_CONTENT_RENDERER_CLIENT_IMPL_H_ -#define WEBLAYER_RENDERER_CONTENT_RENDERER_CLIENT_IMPL_H_ - -#include "build/build_config.h" -#include "content/public/common/alternative_error_page_override_info.mojom.h" -#include "content/public/renderer/content_renderer_client.h" -#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" - -class SpellCheck; - -namespace service_manager { -class LocalInterfaceProvider; -} // namespace service_manager - -namespace subresource_filter { -class UnverifiedRulesetDealer; -} - -namespace weblayer { -class WebLayerRenderThreadObserver; - -class ContentRendererClientImpl : public content::ContentRendererClient { - public: - ContentRendererClientImpl(); - - ContentRendererClientImpl(const ContentRendererClientImpl&) = delete; - ContentRendererClientImpl& operator=(const ContentRendererClientImpl&) = - delete; - - ~ContentRendererClientImpl() override; - - // content::ContentRendererClient: - void RenderThreadStarted() override; - void RenderFrameCreated(content::RenderFrame* render_frame) override; - void WebViewCreated(blink::WebView* web_view, - bool was_created_by_renderer, - const url::Origin* outermost_origin) override; - SkBitmap* GetSadPluginBitmap() override; - SkBitmap* GetSadWebViewBitmap() override; - void PrepareErrorPage(content::RenderFrame* render_frame, - const blink::WebURLError& error, - const std::string& http_method, - content::mojom::AlternativeErrorPageOverrideInfoPtr - alternative_error_page_info, - std::string* error_html) override; - std::unique_ptr<blink::URLLoaderThrottleProvider> - CreateURLLoaderThrottleProvider( - blink::URLLoaderThrottleProviderType provider_type) override; - void GetSupportedKeySystems(media::GetSupportedKeySystemsCB cb) override; - void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override; - bool IsPrefetchOnly(content::RenderFrame* render_frame) override; - bool DeferMediaLoad(content::RenderFrame* render_frame, - bool has_played_media_before, - base::OnceClosure closure) override; - - private: -#if BUILDFLAG(IS_ANDROID) - std::unique_ptr<service_manager::LocalInterfaceProvider> - local_interface_provider_; - std::unique_ptr<SpellCheck> spellcheck_; -#endif - - std::unique_ptr<subresource_filter::UnverifiedRulesetDealer> - subresource_filter_ruleset_dealer_; - - std::unique_ptr<WebLayerRenderThreadObserver> weblayer_observer_; - - scoped_refptr<blink::ThreadSafeBrowserInterfaceBrokerProxy> - browser_interface_broker_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_RENDERER_CONTENT_RENDERER_CLIENT_IMPL_H_
diff --git a/weblayer/renderer/error_page_helper.cc b/weblayer/renderer/error_page_helper.cc deleted file mode 100644 index 6ccb8805..0000000 --- a/weblayer/renderer/error_page_helper.cc +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/renderer/error_page_helper.h" - -#include "base/command_line.h" -#include "components/security_interstitials/content/renderer/security_interstitial_page_controller.h" -#include "content/public/renderer/render_frame.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" -#include "third_party/blink/public/web/web_local_frame.h" -#include "weblayer/common/features.h" - -namespace weblayer { - -// static -void ErrorPageHelper::Create(content::RenderFrame* render_frame) { - if (render_frame->IsMainFrame()) - new ErrorPageHelper(render_frame); -} - -// static -ErrorPageHelper* ErrorPageHelper::GetForFrame( - content::RenderFrame* render_frame) { - return render_frame->IsMainFrame() ? Get(render_frame) : nullptr; -} - -void ErrorPageHelper::PrepareErrorPage() { - if (is_disabled_for_next_error_) { - is_disabled_for_next_error_ = false; - return; - } - is_preparing_for_error_page_ = true; -} - -void ErrorPageHelper::DidCommitProvisionalLoad(ui::PageTransition transition) { - show_error_page_in_finish_load_ = is_preparing_for_error_page_; - is_preparing_for_error_page_ = false; -} - -void ErrorPageHelper::DidFinishLoad() { - if (!show_error_page_in_finish_load_) - return; - - security_interstitials::SecurityInterstitialPageController::Install( - render_frame()); -} - -void ErrorPageHelper::OnDestruct() { - delete this; -} - -void ErrorPageHelper::DisableErrorPageHelperForNextError() { - is_disabled_for_next_error_ = true; -} - -ErrorPageHelper::ErrorPageHelper(content::RenderFrame* render_frame) - : RenderFrameObserver(render_frame), - RenderFrameObserverTracker<ErrorPageHelper>(render_frame) { - render_frame->GetAssociatedInterfaceRegistry() - ->AddInterface<mojom::ErrorPageHelper>(base::BindRepeating( - &ErrorPageHelper::BindErrorPageHelper, weak_factory_.GetWeakPtr())); -} - -ErrorPageHelper::~ErrorPageHelper() = default; - -void ErrorPageHelper::BindErrorPageHelper( - mojo::PendingAssociatedReceiver<mojom::ErrorPageHelper> receiver) { - // There is only a need for a single receiver to be bound at a time. - error_page_helper_receiver_.reset(); - error_page_helper_receiver_.Bind(std::move(receiver)); -} - -} // namespace weblayer
diff --git a/weblayer/renderer/error_page_helper.h b/weblayer/renderer/error_page_helper.h deleted file mode 100644 index 276b5f9..0000000 --- a/weblayer/renderer/error_page_helper.h +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_RENDERER_ERROR_PAGE_HELPER_H_ -#define WEBLAYER_RENDERER_ERROR_PAGE_HELPER_H_ - -#include "content/public/renderer/render_frame_observer.h" -#include "content/public/renderer/render_frame_observer_tracker.h" -#include "mojo/public/cpp/bindings/associated_receiver.h" -#include "mojo/public/cpp/bindings/pending_associated_receiver.h" -#include "weblayer/common/error_page_helper.mojom.h" - -namespace weblayer { - -// A class that allows error pages to handle user interaction by handling their -// javascript commands. Currently only SSL and safebrowsing related -// interstitials are supported. -// This is a stripped down version of Chrome's NetErrorHelper. -// TODO(crbug.com/1073624): Share this logic with NetErrorHelper. -class ErrorPageHelper - : public content::RenderFrameObserver, - public content::RenderFrameObserverTracker<ErrorPageHelper>, - public mojom::ErrorPageHelper { - public: - ErrorPageHelper(const ErrorPageHelper&) = delete; - ErrorPageHelper& operator=(const ErrorPageHelper&) = delete; - - // Creates an ErrorPageHelper which will observe and tie its lifetime to - // |render_frame|, if it's a main frame. ErrorPageHelpers will not be created - // for sub frames. - static void Create(content::RenderFrame* render_frame); - - // Returns the ErrorPageHelper for the frame, if it exists. - static ErrorPageHelper* GetForFrame(content::RenderFrame* render_frame); - - // Called when the current navigation results in an error. - void PrepareErrorPage(); - - // content::RenderFrameObserver: - void DidCommitProvisionalLoad(ui::PageTransition transition) override; - void DidFinishLoad() override; - void OnDestruct() override; - - // mojom::ErrorPageHelper: - void DisableErrorPageHelperForNextError() override; - - private: - explicit ErrorPageHelper(content::RenderFrame* render_frame); - ~ErrorPageHelper() override; - - void BindErrorPageHelper( - mojo::PendingAssociatedReceiver<mojom::ErrorPageHelper> receiver); - - // Set to true in PrepareErrorPage(). - bool is_preparing_for_error_page_ = false; - - // Set to the value of |is_preparing_for_error_page_| in - // DidCommitProvisionalLoad(). Used to determine if the security interstitial - // should be shown when the load finishes. - bool show_error_page_in_finish_load_ = false; - - // Set to true when the embedder injects its own error page. When the - // embedder injects its own error page the support here is not needed and - // disabled. - bool is_disabled_for_next_error_ = false; - - mojo::AssociatedReceiver<mojom::ErrorPageHelper> error_page_helper_receiver_{ - this}; - - base::WeakPtrFactory<ErrorPageHelper> weak_factory_{this}; -}; - -} // namespace weblayer - -#endif // WEBLAYER_RENDERER_ERROR_PAGE_HELPER_H_
diff --git a/weblayer/renderer/url_loader_throttle_provider.cc b/weblayer/renderer/url_loader_throttle_provider.cc deleted file mode 100644 index a43fdd9..0000000 --- a/weblayer/renderer/url_loader_throttle_provider.cc +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/renderer/url_loader_throttle_provider.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "components/no_state_prefetch/renderer/no_state_prefetch_helper.h" -#include "components/safe_browsing/content/renderer/renderer_url_loader_throttle.h" -#include "content/public/renderer/render_thread.h" -#include "third_party/blink/public/common/loader/resource_type_util.h" - -namespace weblayer { - -URLLoaderThrottleProvider::URLLoaderThrottleProvider( - blink::ThreadSafeBrowserInterfaceBrokerProxy* broker, - blink::URLLoaderThrottleProviderType type) - : type_(type) { - DETACH_FROM_SEQUENCE(sequence_checker_); - broker->GetInterface(safe_browsing_remote_.InitWithNewPipeAndPassReceiver()); -} - -URLLoaderThrottleProvider::URLLoaderThrottleProvider( - const URLLoaderThrottleProvider& other) - : type_(other.type_) { - DETACH_FROM_SEQUENCE(sequence_checker_); - if (other.safe_browsing_) { - other.safe_browsing_->Clone( - safe_browsing_remote_.InitWithNewPipeAndPassReceiver()); - } -} - -std::unique_ptr<blink::URLLoaderThrottleProvider> -URLLoaderThrottleProvider::Clone() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (safe_browsing_remote_) - safe_browsing_.Bind(std::move(safe_browsing_remote_)); - return base::WrapUnique(new URLLoaderThrottleProvider(*this)); -} - -URLLoaderThrottleProvider::~URLLoaderThrottleProvider() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -blink::WebVector<std::unique_ptr<blink::URLLoaderThrottle>> -URLLoaderThrottleProvider::CreateThrottles( - int render_frame_id, - const blink::WebURLRequest& request) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - blink::WebVector<std::unique_ptr<blink::URLLoaderThrottle>> throttles; - - bool is_frame_resource = - blink::IsRequestDestinationFrame(request.GetRequestDestination()); - - DCHECK(!is_frame_resource || - type_ == blink::URLLoaderThrottleProviderType::kFrame); - - if (!is_frame_resource) { - if (safe_browsing_remote_) - safe_browsing_.Bind(std::move(safe_browsing_remote_)); - throttles.emplace_back( - std::make_unique<safe_browsing::RendererURLLoaderThrottle>( - safe_browsing_.get(), render_frame_id)); - } - - if (type_ == blink::URLLoaderThrottleProviderType::kFrame && - !is_frame_resource) { - auto throttle = - prerender::NoStatePrefetchHelper::MaybeCreateThrottle(render_frame_id); - if (throttle) - throttles.emplace_back(std::move(throttle)); - } - - return throttles; -} - -void URLLoaderThrottleProvider::SetOnline(bool is_online) {} - -} // namespace weblayer
diff --git a/weblayer/renderer/url_loader_throttle_provider.h b/weblayer/renderer/url_loader_throttle_provider.h deleted file mode 100644 index ffb0334..0000000 --- a/weblayer/renderer/url_loader_throttle_provider.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_RENDERER_URL_LOADER_THROTTLE_PROVIDER_H_ -#define WEBLAYER_RENDERER_URL_LOADER_THROTTLE_PROVIDER_H_ - -#include "base/sequence_checker.h" -#include "components/safe_browsing/content/common/safe_browsing.mojom.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" -#include "third_party/blink/public/platform/url_loader_throttle_provider.h" - -namespace weblayer { - -// Instances must be constructed on the render main thread, and then used and -// destructed on a single sequence, which can be different from the render main -// thread. -class URLLoaderThrottleProvider : public blink::URLLoaderThrottleProvider { - public: - URLLoaderThrottleProvider( - blink::ThreadSafeBrowserInterfaceBrokerProxy* broker, - blink::URLLoaderThrottleProviderType type); - - URLLoaderThrottleProvider& operator=(const URLLoaderThrottleProvider&) = - delete; - - ~URLLoaderThrottleProvider() override; - - // blink::URLLoaderThrottleProvider implementation. - std::unique_ptr<blink::URLLoaderThrottleProvider> Clone() override; - blink::WebVector<std::unique_ptr<blink::URLLoaderThrottle>> CreateThrottles( - int render_frame_id, - const blink::WebURLRequest& request) override; - void SetOnline(bool is_online) override; - - private: - // This copy constructor works in conjunction with Clone(), not intended for - // general use. - URLLoaderThrottleProvider(const URLLoaderThrottleProvider& other); - - blink::URLLoaderThrottleProviderType type_; - - mojo::PendingRemote<safe_browsing::mojom::SafeBrowsing> safe_browsing_remote_; - mojo::Remote<safe_browsing::mojom::SafeBrowsing> safe_browsing_; - - SEQUENCE_CHECKER(sequence_checker_); -}; - -} // namespace weblayer - -#endif // WEBLAYER_RENDERER_URL_LOADER_THROTTLE_PROVIDER_H_
diff --git a/weblayer/renderer/weblayer_render_frame_observer.cc b/weblayer/renderer/weblayer_render_frame_observer.cc deleted file mode 100644 index e3c5533b..0000000 --- a/weblayer/renderer/weblayer_render_frame_observer.cc +++ /dev/null
@@ -1,165 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/renderer/weblayer_render_frame_observer.h" - -#include "content/public/renderer/render_frame.h" - -#include "base/metrics/histogram_macros.h" -#include "base/time/time.h" -#include "components/no_state_prefetch/renderer/no_state_prefetch_helper.h" -#include "components/translate/content/renderer/translate_agent.h" -#include "components/translate/core/common/translate_util.h" -#include "third_party/blink/public/web/web_document_loader.h" -#include "third_party/blink/public/web/web_frame_content_dumper.h" -#include "third_party/blink/public/web/web_local_frame.h" -#include "weblayer/common/features.h" -#include "weblayer/common/isolated_world_ids.h" - -#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) -#include "components/safe_browsing/content/renderer/phishing_classifier/phishing_classifier_delegate.h" -#endif - -namespace weblayer { - -namespace { -// Maximum number of characters in the document to index. -// Any text beyond this point will be clipped. -static const size_t kMaxIndexChars = 65535; - -// Constants for UMA statistic collection. -static const char kTranslateCaptureText[] = "Translate.CaptureText"; - -// For a page that auto-refreshes, we still show the bubble, if -// the refresh delay is less than this value (in seconds). -static constexpr base::TimeDelta kLocationChangeInterval = base::Seconds(10); -} // namespace - -WebLayerRenderFrameObserver::WebLayerRenderFrameObserver( - content::RenderFrame* render_frame) - : content::RenderFrameObserver(render_frame), translate_agent_(nullptr) { - // Don't do anything for subframes. - if (!render_frame->IsMainFrame()) - return; - - if (base::FeatureList::IsEnabled( - features::kWebLayerClientSidePhishingDetection)) - SetClientSidePhishingDetection(); - - translate_agent_ = - new translate::TranslateAgent(render_frame, ISOLATED_WORLD_ID_TRANSLATE); -} - -WebLayerRenderFrameObserver::~WebLayerRenderFrameObserver() = default; - -bool WebLayerRenderFrameObserver::OnAssociatedInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedInterfaceEndpointHandle* handle) { - return associated_interfaces_.TryBindInterface(interface_name, handle); -} - -void WebLayerRenderFrameObserver::ReadyToCommitNavigation( - blink::WebDocumentLoader* document_loader) { - // Let translate_agent do any preparatory work for loading a URL. - if (!translate_agent_) - return; - - translate_agent_->PrepareForUrl( - render_frame()->GetWebFrame()->GetDocument().Url()); -} - -void WebLayerRenderFrameObserver::DidMeaningfulLayout( - blink::WebMeaningfulLayout layout_type) { - // Don't do any work for subframes. - if (!render_frame()->IsMainFrame()) - return; - - switch (layout_type) { - case blink::WebMeaningfulLayout::kFinishedParsing: - CapturePageText(PRELIMINARY_CAPTURE); - break; - case blink::WebMeaningfulLayout::kFinishedLoading: - CapturePageText(FINAL_CAPTURE); - break; - default: - break; - } -} - -// NOTE: This is a simplified version of -// ChromeRenderFrameObserver::CapturePageText(), which is more complex as it is -// used for embedder-level purposes beyond translation. This code is expected to -// be eliminated when WebLayer adopts Chrome's upcoming per-frame translate -// architecture (crbug.com/1063520). -void WebLayerRenderFrameObserver::CapturePageText( - TextCaptureType capture_type) { - blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); - if (!frame) - return; - - // Don't capture pages that have pending redirect or location change. - if (frame->IsNavigationScheduledWithin(kLocationChangeInterval)) - return; - - // Don't index/capture pages that are in view source mode. - if (frame->IsViewSourceModeEnabled()) - return; - - // Don't capture text of the error pages. - blink::WebDocumentLoader* document_loader = frame->GetDocumentLoader(); - if (document_loader && document_loader->HasUnreachableURL()) - return; - - // Don't index/capture pages that are being no-state prefetched. - if (prerender::NoStatePrefetchHelper::IsPrefetching(render_frame())) - return; - - // Don't capture contents unless there is either a translate agent or a - // phishing classifier to consume them. -#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) - if (!translate_agent_ && !phishing_classifier_) - return; -#else - if (!translate_agent_) - return; -#endif - - base::TimeTicks capture_begin_time = base::TimeTicks::Now(); - - // Retrieve the frame's full text (up to kMaxIndexChars), and pass it to the - // translate helper for language detection and possible translation. - // TODO(http://crbug.com/1163244): Update this when the corresponding usage of - // this function in //chrome is updated. - std::u16string contents = - blink::WebFrameContentDumper::DumpFrameTreeAsText(frame, kMaxIndexChars) - .Utf16(); - - UMA_HISTOGRAM_TIMES(kTranslateCaptureText, - base::TimeTicks::Now() - capture_begin_time); - - // We should run language detection only once. Parsing finishes before - // the page loads, so let's pick that timing (as in chrome). - if (translate_agent_ && capture_type == PRELIMINARY_CAPTURE) { - translate_agent_->PageCaptured(contents); - } - -#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) - if (phishing_classifier_) - phishing_classifier_->PageCaptured(&contents, - capture_type == PRELIMINARY_CAPTURE); -#endif -} - -void WebLayerRenderFrameObserver::OnDestruct() { - delete this; -} - -void WebLayerRenderFrameObserver::SetClientSidePhishingDetection() { -#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) - phishing_classifier_ = safe_browsing::PhishingClassifierDelegate::Create( - render_frame(), nullptr); -#endif -} - -} // namespace weblayer
diff --git a/weblayer/renderer/weblayer_render_frame_observer.h b/weblayer/renderer/weblayer_render_frame_observer.h deleted file mode 100644 index e026dd54..0000000 --- a/weblayer/renderer/weblayer_render_frame_observer.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_RENDERER_WEBLAYER_RENDER_FRAME_OBSERVER_H_ -#define WEBLAYER_RENDERER_WEBLAYER_RENDER_FRAME_OBSERVER_H_ - -#include "components/safe_browsing/buildflags.h" -#include "content/public/renderer/render_frame_observer.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" - -namespace safe_browsing { -class PhishingClassifierDelegate; -} - -namespace translate { -class TranslateAgent; -} - -namespace weblayer { - -// This class holds the WebLayer-specific parts of RenderFrame, and has the -// same lifetime. It is analogous to //chrome's ChromeRenderFrameObserver. -class WebLayerRenderFrameObserver : public content::RenderFrameObserver { - public: - explicit WebLayerRenderFrameObserver(content::RenderFrame* render_frame); - - WebLayerRenderFrameObserver(const WebLayerRenderFrameObserver&) = delete; - WebLayerRenderFrameObserver& operator=(const WebLayerRenderFrameObserver&) = - delete; - - blink::AssociatedInterfaceRegistry* associated_interfaces() { - return &associated_interfaces_; - } - - private: - enum TextCaptureType { PRELIMINARY_CAPTURE, FINAL_CAPTURE }; - ~WebLayerRenderFrameObserver() override; - - // RenderFrameObserver: - bool OnAssociatedInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedInterfaceEndpointHandle* handle) override; - void ReadyToCommitNavigation( - blink::WebDocumentLoader* document_loader) override; - void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override; - void OnDestruct() override; - - void CapturePageText(TextCaptureType capture_type); - - // Initializes a |phishing_classifier_delegate_|. - void SetClientSidePhishingDetection(); - - blink::AssociatedInterfaceRegistry associated_interfaces_; - - // Has the same lifetime as this object. - translate::TranslateAgent* translate_agent_; - -#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) - safe_browsing::PhishingClassifierDelegate* phishing_classifier_ = nullptr; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_RENDERER_WEBLAYER_RENDER_FRAME_OBSERVER_H_
diff --git a/weblayer/renderer/weblayer_render_thread_observer.cc b/weblayer/renderer/weblayer_render_thread_observer.cc deleted file mode 100644 index 844b409..0000000 --- a/weblayer/renderer/weblayer_render_thread_observer.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/renderer/weblayer_render_thread_observer.h" - -#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" - -namespace weblayer { - -WebLayerRenderThreadObserver::WebLayerRenderThreadObserver() = default; - -WebLayerRenderThreadObserver::~WebLayerRenderThreadObserver() = default; - -void WebLayerRenderThreadObserver::RegisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) { - associated_interfaces->AddInterface< - mojom::RendererConfiguration>(base::BindRepeating( - &WebLayerRenderThreadObserver::OnRendererConfigurationAssociatedRequest, - base::Unretained(this))); -} - -void WebLayerRenderThreadObserver::UnregisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) { - associated_interfaces->RemoveInterface(mojom::RendererConfiguration::Name_); -} - -// weblayer::mojom::RendererConfiguration: -void WebLayerRenderThreadObserver::SetInitialConfiguration( - mojo::PendingRemote<content_settings::mojom::ContentSettingsManager> - content_settings_manager) { - if (content_settings_manager) - content_settings_manager_.Bind(std::move(content_settings_manager)); -} - -void WebLayerRenderThreadObserver::OnRendererConfigurationAssociatedRequest( - mojo::PendingAssociatedReceiver<mojom::RendererConfiguration> receiver) { - renderer_configuration_receivers_.Add(this, std::move(receiver)); -} - -} // namespace weblayer
diff --git a/weblayer/renderer/weblayer_render_thread_observer.h b/weblayer/renderer/weblayer_render_thread_observer.h deleted file mode 100644 index ae2ecb4b..0000000 --- a/weblayer/renderer/weblayer_render_thread_observer.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_RENDERER_WEBLAYER_RENDER_THREAD_OBSERVER_H_ -#define WEBLAYER_RENDERER_WEBLAYER_RENDER_THREAD_OBSERVER_H_ - -#include "components/content_settings/common/content_settings_manager.mojom.h" -#include "content/public/renderer/render_thread_observer.h" -#include "mojo/public/cpp/bindings/associated_receiver_set.h" -#include "weblayer/common/renderer_configuration.mojom.h" - -namespace weblayer { - -// Listens for WebLayer-specific messages from the browser. -class WebLayerRenderThreadObserver : public content::RenderThreadObserver, - public mojom::RendererConfiguration { - public: - WebLayerRenderThreadObserver(); - ~WebLayerRenderThreadObserver() override; - - content_settings::mojom::ContentSettingsManager* content_settings_manager() { - if (content_settings_manager_) - return content_settings_manager_.get(); - return nullptr; - } - - private: - // content::RenderThreadObserver: - void RegisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) override; - void UnregisterMojoInterfaces( - blink::AssociatedInterfaceRegistry* associated_interfaces) override; - - // weblayer::mojom::RendererConfiguration: - void SetInitialConfiguration( - mojo::PendingRemote<content_settings::mojom::ContentSettingsManager> - content_settings_manager) override; - - void OnRendererConfigurationAssociatedRequest( - mojo::PendingAssociatedReceiver<mojom::RendererConfiguration> receiver); - - mojo::Remote<content_settings::mojom::ContentSettingsManager> - content_settings_manager_; - - mojo::AssociatedReceiverSet<mojom::RendererConfiguration> - renderer_configuration_receivers_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_RENDERER_WEBLAYER_RENDER_THREAD_OBSERVER_H_
diff --git a/weblayer/shell/BUILD.gn b/weblayer/shell/BUILD.gn deleted file mode 100644 index 02e9a52..0000000 --- a/weblayer/shell/BUILD.gn +++ /dev/null
@@ -1,255 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/chrome_build.gni") -import("//build/config/features.gni") -import("//build/config/sanitizers/sanitizers.gni") -import("//build/config/ui.gni") -import("//build/config/win/console_app.gni") -import("//build/config/win/manifest.gni") -import("//tools/grit/grit_rule.gni") -import("//tools/grit/repack.gni") -import("//tools/v8_context_snapshot/v8_context_snapshot.gni") -if (is_android) { - import("//build/config/android/config.gni") -} - -static_library("webengine_shell_lib") { - testonly = true - sources = [ - "app/shell_main_params.cc", - "app/shell_main_params.h", - "browser/shell.cc", - "browser/shell.h", - "common/shell_switches.cc", - "common/shell_switches.h", - ] - - if (is_android) { - sources += [ "browser/shell_android.cc" ] - } - - configs += [ "//build/config:precompiled_headers" ] - - public_deps = [ "//weblayer:weblayer_lib" ] - deps = [ - ":resources", - "//base", - "//base:base_static", - "//base/third_party/dynamic_annotations", - "//net", - "//net:net_resources", - "//sandbox", - "//skia", - "//third_party/icu", - "//ui/base", - "//ui/base/clipboard", - "//ui/base/ime/init", - "//ui/display", - "//ui/events:events_base", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gfx/ipc", - "//ui/gfx/ipc/geometry", - "//ui/gfx/ipc/skia", - "//ui/gl", - "//ui/platform_window", - "//url", - "//v8", - "//weblayer:resources", - ] - - if (is_linux || is_chromeos) { - deps += [ - "//third_party/fontconfig", - "//ui/gfx:test_support", - ] - } - - if (is_android) { - deps += [ "//ui/android" ] - } - - if (toolkit_views) { - deps += [ "//ui/views" ] - } - - if (use_aura) { - deps += [ - "//ui/aura", - "//ui/aura:test_support", - "//ui/events", - "//ui/strings", - "//ui/wm", - ] - - if (toolkit_views) { - sources += [ "browser/shell_views.cc" ] - deps += [ - "//ui/color:color_headers", - "//ui/native_theme", - "//ui/resources", - "//ui/views:test_support", - "//ui/views/controls/webview", - "//ui/wm:test_support", - ] - } - } - - if (is_linux || is_chromeos) { - deps += [ "//build/config/freetype" ] - } -} - -grit("webengine_shell_resources_grit") { - testonly = true - - # External code should depend on ":resources" instead. - visibility = [ ":*" ] - source = "shell_resources.grd" - outputs = [ - "grit/shell_resources.h", - "webengine_shell_resources.pak", - ] -} - -copy("copy_shell_resources") { - testonly = true - - sources = [ "$target_gen_dir/webengine_shell_resources.pak" ] - outputs = [ "$root_out_dir/webengine_shell_resources.pak" ] - - public_deps = [ ":webengine_shell_resources_grit" ] -} - -group("resources") { - testonly = true - - public_deps = [ ":copy_shell_resources" ] -} - -repack("shell_pak") { - testonly = true - - sources = [ "$root_gen_dir/weblayer/shell/webengine_shell_resources.pak" ] - - deps = [ ":resources" ] - output = "$root_out_dir/webengine_shell.pak" -} - -repack("support_pak") { - testonly = true - - sources = [ - "$root_gen_dir/components/components_resources.pak", - "$root_gen_dir/components/components_resources_100_percent.pak", - "$root_gen_dir/components/strings/components_${branding_path_product}_strings_en-US.pak", - "$root_gen_dir/components/strings/components_locale_settings_en-US.pak", - "$root_gen_dir/components/strings/components_strings_en-US.pak", - "$root_gen_dir/content/content_resources.pak", - "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak", - "$root_gen_dir/net/net_resources.pak", - "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak", - "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak", - "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak", - "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/resources/webui_resources.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ax_strings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", - "$root_gen_dir/weblayer/weblayer_resources.pak", - ] - - deps = [ - "//components/resources", - "//components/strings", - "//content:content_resources", - "//mojo/public/js:resources", - "//net:net_resources", - "//third_party/blink/public:resources", - "//third_party/blink/public:scaled_resources_100_percent", - "//third_party/blink/public/strings", - "//ui/resources", - "//ui/strings", - "//weblayer:resources", - ] - - if (toolkit_views) { - deps += [ "//ui/views/resources" ] - sources += - [ "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak" ] - } - if (is_android) { - deps += [ "//ui/android:ui_java_resources" ] - } else { - deps += [ "//content/browser/tracing:resources" ] - sources += [ "$root_gen_dir/content/browser/tracing/tracing_resources.pak" ] - } - output = "$root_out_dir/weblayer_support.pak" -} - -repack("pak") { - testonly = true - - sources = [ - "$root_out_dir/webengine_shell.pak", - "$root_out_dir/weblayer_support.pak", - ] - - deps = [ - ":shell_pak", - ":support_pak", - ] - output = "$root_out_dir/weblayer.pak" -} - -if (is_android) { - group("weblayer_support") { - testonly = true - deps = [ "//weblayer/shell/android:weblayer_support_apk" ] - } -} else { - executable("webengine_shell") { - testonly = true - - sources = [ "app/shell_main.cc" ] - - if (is_win) { - sources += [ "app/shell.rc" ] - } - - defines = [] - - deps = [ - ":webengine_shell_lib", - "//base", - "//build/win:default_exe_manifest", - "//net", - ] - - data_deps = [ - ":pak", - "//tools/v8_context_snapshot:v8_context_snapshot", - ] - - if (is_win) { - deps += [ "//sandbox" ] - if (win_console_app) { - defines += [ "WIN_CONSOLE_APP" ] - } else { - # Set /SUBSYSTEM:WINDOWS unless a console build has been requested. - configs -= [ "//build/config/win:console" ] - configs += [ "//build/config/win:windowed" ] - } - - data_deps += - [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ] - } - - if ((is_linux || is_chromeos) && !is_component_build) { - # Set rpath to find our own libfreetype even in a non-component build. - configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ] - } - } -}
diff --git a/weblayer/shell/DEPS b/weblayer/shell/DEPS deleted file mode 100644 index e81b184..0000000 --- a/weblayer/shell/DEPS +++ /dev/null
@@ -1,12 +0,0 @@ -include_rules = [ - "+net", - "+ui/aura", - "+ui/base", - "+ui/color", - "+ui/display", - "+ui/events", - "+ui/gfx", - "+ui/native_theme", - "+ui/views", - "+ui/wm", -]
diff --git a/weblayer/shell/OWNERS b/weblayer/shell/OWNERS deleted file mode 100644 index 262cd04d..0000000 --- a/weblayer/shell/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -rayankans@chromium.org -swestphal@chromium.org \ No newline at end of file
diff --git a/weblayer/shell/README.md b/weblayer/shell/README.md deleted file mode 100644 index acd23ec8..0000000 --- a/weblayer/shell/README.md +++ /dev/null
@@ -1,18 +0,0 @@ -# WebEngine Shell - -This directory contains a minimal shell that runs WebEngine. - - -To build and run the sample app: - -``` - $ autoninja -C out/Default run_webengine_shell_local - $ out/Default/bin/run_webengine_shell_local -``` - -To build and run the sample app with a browsing sandbox (limited capabilities): - -``` - $ autoninja -C out/Default run_webengine_shell - $ out/Default/bin/run_webengine_shell -``` \ No newline at end of file
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn deleted file mode 100644 index 03e7288..0000000 --- a/weblayer/shell/android/BUILD.gn +++ /dev/null
@@ -1,244 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//android_webview/system_webview_apk_tmpl.gni") -import("//build/config/android/abi.gni") -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") -import("//build/config/python.gni") -import("//device/vr/buildflags/buildflags.gni") -import("//third_party/icu/config.gni") -import("//tools/v8_context_snapshot/v8_context_snapshot.gni") -import("//weblayer/variables.gni") - -generate_wrapper("run_webengine_shell") { - testonly = true - wrapper_script = "$root_out_dir/bin/run_webengine_shell" - executable = "//weblayer/tools/run_webengine_shell.py" - executable_args = [ - "--shell-apk-path", - "@WrappedPath(apks/WEShellSandbox.apk)", - "--support-apk-path", - "@WrappedPath(apks/WESandbox.apk)", - "--support-apk-path", - "@WrappedPath(apks/WebLayerSupport.apk)", - ] - - deps = [ - ":browser_sandbox_apk", - ":webengine_shell_sandbox_apk", - ":weblayer_support_apk", - ] -} - -generate_wrapper("run_webengine_shell_local") { - testonly = true - wrapper_script = "$root_out_dir/bin/run_webengine_shell_local" - executable = "//weblayer/tools/run_webengine_shell.py" - executable_args = [ - "--shell-apk-path", - "@WrappedPath(apks/WEShellLocal.apk)", - "--support-apk-path", - "@WrappedPath(apks/WebLayerSupport.apk)", - ] - - deps = [ - ":browser_sandbox_apk", - ":webengine_shell_local_apk", - ":weblayer_support_apk", - ] -} - -weblayer_support_manifest = - "$target_gen_dir/weblayer_support_manifest/AndroidManifest.xml" - -jinja_template("weblayer_support_manifest") { - input = "support_apk/AndroidManifest.xml" - output = weblayer_support_manifest -} - -android_apk("weblayer_support_apk") { - testonly = true - - # Test runner does not support having "additional apks" that are incremental. - never_incremental = true - - deps = [ - ":weblayer_support_manifest", - "//android_webview:locale_pak_assets", - "//android_webview:pak_file_assets", - "//android_webview:weblayer_webview_assets", - "//weblayer:locale_pak_assets", - "//weblayer/browser/java", - "//weblayer/browser/java:test_java", - ] - - # Transitive dependencies - deps += [ - "//components/safe_browsing/android:safe_browsing_java", - "//components/viz/service:service_java", - "//media/base/android:media_java", - "//media/capture/video/android:capture_java", - "//mojo/public/java:system_java", - "//net/android:net_java", - ] - - # default upstream classes - deps += [ "//weblayer/browser/java:upstream_java" ] - - # Add the Chromium linker for WebView compatibility support on L-M. - deps += [ "//base/android/linker:chromium_android_linker" ] - loadable_modules = - [ "$root_out_dir/libchromium_android_linker$shlib_extension" ] - - if (enable_arcore) { - _libarcore_dir = get_label_info( - "//third_party/arcore-android-sdk-client:com_google_ar_core_java($default_toolchain)", - "target_out_dir") + "/com_google_ar_core_java/jni" - loadable_modules += - [ "$_libarcore_dir/$android_app_abi/libarcore_sdk_c.so" ] - deps += - [ "//third_party/arcore-android-sdk-client:com_google_ar_core_java" ] - } - - apk_name = "WebLayerSupport" - android_manifest = weblayer_support_manifest - target_sdk_version = 28 - android_manifest_dep = ":weblayer_support_manifest" - shared_resources = true - version_name = chrome_version_name - version_code = webview_stable_version_code - - product_config_java_packages = [ weblayer_product_config_java_package ] - - shared_libraries = [ "//weblayer:libweblayer_test" ] - srcjar_deps = [ "//weblayer:libweblayer_test__jni_registration" ] -} - -android_resources("webengine_shell_resources") { - sources = [ - "webengine_shell_apk/res/drawable-night/ic_refresh.xml", - "webengine_shell_apk/res/drawable-night/ic_stop.xml", - "webengine_shell_apk/res/drawable/ic_refresh.xml", - "webengine_shell_apk/res/drawable/ic_stop.xml", - "webengine_shell_apk/res/layout/main.xml", - "webengine_shell_apk/res/layout/navigation_test.xml", - "webengine_shell_apk/res/layout/spa.xml", - "webengine_shell_apk/res/layout/state_test.xml", - "webengine_shell_apk/res/values/strings.xml", - "webengine_shell_apk/res/values/styles.xml", - ] -} - -android_library("webengine_shell_java") { - testonly = true - resources_package = "org.chromium.webengine.shell" - - sources = [ - "webengine_shell_apk/src/org/chromium/webengine/shell/DefaultObservers.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineNavigationTestActivity.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineSinglePageActivity.kt", - "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineStateTestActivity.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/CustomSpinner.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java", - "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java", - ] - - deps = [ - ":webengine_service_provider_resources", - ":webengine_shell_resources", - "//base:base_java", - "//third_party/android_deps:com_google_guava_listenablefuture_java", - "//third_party/android_deps:guava_android_java", - "//third_party/android_deps:org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm_java", - "//third_party/android_deps:org_jetbrains_kotlinx_kotlinx_coroutines_guava_java", - "//third_party/androidx:androidx_activity_activity_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_appcompat_appcompat_java", - "//third_party/androidx:androidx_concurrent_concurrent_futures_java", - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_ktx_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", - "//third_party/kotlin_stdlib:kotlin_stdlib_java", - "//weblayer/public/java:service_provider_java", - "//weblayer/public/java:webengine_java", - ] -} - -template("webengine_shell_apk_helper") { - _webengine_shell_manifest = - "$target_gen_dir/manifest_$target_name/AndroidManifest.xml" - _manifest_target = target_name + "_manifest" - - jinja_template(_manifest_target) { - input = "webengine_shell_apk/AndroidManifest.xml" - output = _webengine_shell_manifest - if (defined(invoker.browser_process_mode)) { - variables = [ "browser_process_mode=" + invoker.browser_process_mode ] - } - } - android_apk(target_name + "_apk") { - testonly = true - apk_name = invoker.apk_name - - deps = [ - ":$_manifest_target", - ":webengine_shell_java", - ] - - android_manifest = _webengine_shell_manifest - android_manifest_dep = ":$_manifest_target" - target_sdk_version = 28 - } -} - -webengine_shell_apk_helper("webengine_shell_local") { - browser_process_mode = "local" - apk_name = "WEShellLocal" -} - -webengine_shell_apk_helper("webengine_shell_sandbox") { - browser_process_mode = "sandbox" - apk_name = "WEShellSandbox" -} - -webengine_services_manifest = - "$target_gen_dir/service_provider/AndroidManifest.xml" - -jinja_template("webengine_services_manifest") { - input = "service_provider/AndroidManifest.xml" - output = webengine_services_manifest -} - -android_resources("webengine_service_provider_resources") { - testonly = true - android_manifest = webengine_services_manifest - android_manifest_dep = ":webengine_services_manifest" - - deps = [ ":webengine_services_manifest" ] -} - -# TODO(swestphal): Make this an AAR when BrowserProcess service can run in isolated process. -android_apk("browser_sandbox_apk") { - testonly = true - - # Test runner does not support having "additional apks" that are incremental. - never_incremental = true - - deps = [ - ":webengine_service_provider_resources", - "//weblayer/public/java:service_provider_java", - "//weblayer/public/java:webengine_interfaces_java", - ] - - apk_name = "WESandbox" - android_manifest = webengine_services_manifest - android_manifest_dep = ":webengine_services_manifest" - target_sdk_version = 28 - shared_resources = true -}
diff --git a/weblayer/shell/android/browsertests_apk/AndroidManifest.xml b/weblayer/shell/android/browsertests_apk/AndroidManifest.xml deleted file mode 100644 index bb920d9..0000000 --- a/weblayer/shell/android/browsertests_apk/AndroidManifest.xml +++ /dev/null
@@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2019 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chromium.weblayer_browsertests_apk"> - - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> - <uses-permission android:name="android.permission.CAMERA"/> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> - <uses-permission android:name="android.permission.NFC"/> - <uses-permission android:name="android.permission.RECORD_AUDIO"/> - <uses-permission android:name="android.permission.VIBRATE"/> - <uses-permission android:name="android.permission.WAKE_LOCK"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - - <application android:name="WebLayerBrowserTestsApplication" - android:label="WebLayerBrowserTests" - android:memtagMode="sync"> - <activity android:name="WebLayerBrowserTestsActivity" - android:launchMode="singleTask" - android:theme="@android:style/Theme.Holo.Light.NoActionBar" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize" - android:windowSoftInputMode="adjustPan|stateUnspecified" - android:exported="true" - android:process=":test_process"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - - <meta-data android:name="org.chromium.weblayer.WebLayerPackage" - android:value="org.chromium.weblayer_browsertests_apk"/> - </application> - - <instrumentation android:name="org.chromium.build.gtest_apk.NativeTestInstrumentationTestRunner" - android:label="WebLayerBrowserTests" - android:targetPackage="org.chromium.weblayer_browsertests_apk"/> -</manifest>
diff --git a/weblayer/shell/android/browsertests_apk/DEPS b/weblayer/shell/android/browsertests_apk/DEPS deleted file mode 100644 index 9522755..0000000 --- a/weblayer/shell/android/browsertests_apk/DEPS +++ /dev/null
@@ -1,9 +0,0 @@ -include_rules = [ - "+components/embedder_support", - "+components/metrics", - "+components/translate/content/android", - "+content/public/android", - "+content/public/app", - "+content/public/test", - "+ui/android", -]
diff --git a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java b/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java deleted file mode 100644 index d3549daf..0000000 --- a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_browsertests_apk; - -import android.view.View; -import android.widget.LinearLayout; - -import org.chromium.base.test.util.UrlUtils; -import org.chromium.content_public.browser.BrowserStartupController; -import org.chromium.native_test.NativeBrowserTest; -import org.chromium.native_test.NativeBrowserTestActivity; -import org.chromium.weblayer.TestWebLayer; - -import java.io.File; - -/** An Activity base class for running browser tests against WebLayerShell. */ -public class WebLayerBrowserTestsActivity extends NativeBrowserTestActivity { - private static final String TAG = "native_test"; - - @Override - protected void initializeBrowserProcess() { - BrowserStartupController.getInstance().setContentMainCallbackForTests(() -> { - // This jumps into C++ to set up and run the test harness. The test harness runs - // ContentMain()-equivalent code, and then waits for javaStartupTasksComplete() - // to be called. - runTests(); - }); - - try { - // Browser tests cannot be run in WebView compatibility mode since the class loader - // WebLayer uses needs to match the class loader used for setup. - TestWebLayer.disableWebViewCompatibilityMode(); - TestWebLayer.setupWeblayerForBrowserTest(getApplication(), (contentView) -> { - LinearLayout mainView = new LinearLayout(this); - int viewId = View.generateViewId(); - mainView.setId(viewId); - setContentView(mainView); - - mainView.addView(contentView); - NativeBrowserTest.javaStartupTasksComplete(); - }); - } catch (Exception e) { - throw new RuntimeException("failed loading WebLayer", e); - } - } - - @Override - protected File getPrivateDataDirectory() { - return new File(UrlUtils.getIsolatedTestRoot(), - WebLayerBrowserTestsApplication.PRIVATE_DATA_DIRECTORY_SUFFIX); - } - - @Override - /** - * Ensure that the user data directory gets overridden to getPrivateDataDirectory() (which is - * cleared at the start of every run); the directory that ANDROID_APP_DATA_DIR is set to in the - * context of Java browsertests is not cleared as it also holds persistent state, which - * causes test failures due to state bleedthrough. See crbug.com/617734 for details. - */ - protected String getUserDataDirectoryCommandLineSwitch() { - return "webengine-user-data-dir"; - } -}
diff --git a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsApplication.java b/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsApplication.java deleted file mode 100644 index 109d287..0000000 --- a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsApplication.java +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_browsertests_apk; - -import android.content.Context; - -import org.chromium.base.ContextUtils; -import org.chromium.base.PathUtils; -import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory; -import org.chromium.native_test.NativeBrowserTestApplication; - -/** - * A basic weblayer_public.browser.tests {@link android.app.Application}. - */ -public class WebLayerBrowserTestsApplication extends NativeBrowserTestApplication { - static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "weblayer_shell"; - - @Override - protected void attachBaseContext(Context base) { - super.attachBaseContext(base); - - if (isBrowserProcess()) { - // Test-only stuff, see also NativeUnitTest.java. - PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX); - } - } - - @Override - protected void setLibraryProcessType() {} - - @Override - protected void initApplicationContext() { - // Matches the initApplicationContext call in WebLayerImpl.minimalInitForContext. - ContextUtils.initApplicationContext(ClassLoaderContextWrapperFactory.get(this)); - } -}
diff --git a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/AccessTokenFetchTestBridge.java b/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/AccessTokenFetchTestBridge.java deleted file mode 100644 index bdabfddd..0000000 --- a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/AccessTokenFetchTestBridge.java +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; - -/** - * Bridge for setup of AccessTokenFetch browsertests from native. - */ -@JNINamespace("weblayer") -public class AccessTokenFetchTestBridge { - AccessTokenFetchTestBridge() {} - - // Installs a GoogleAccountAccessTokenFetcherTestStub on |profile|. Returns the instance for - // use by the test invoking this method. - @CalledByNative - private static GoogleAccountAccessTokenFetcherTestStub - installGoogleAccountAccessTokenFetcherTestStub(ProfileImpl profile) { - GoogleAccountAccessTokenFetcherTestStub testClient = - new GoogleAccountAccessTokenFetcherTestStub(); - profile.setGoogleAccountAccessTokenFetcherClient(testClient); - - return testClient; - } -}
diff --git a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherTestStub.java b/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherTestStub.java deleted file mode 100644 index 1526db9..0000000 --- a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherTestStub.java +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.webkit.ValueCallback; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.weblayer_private.interfaces.IGoogleAccountAccessTokenFetcherClient; -import org.chromium.weblayer_private.interfaces.IObjectWrapper; -import org.chromium.weblayer_private.interfaces.ObjectWrapper; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * Implementation of IGoogleAccountAccessTokenFetcherClient that saves requests made from the - * WebLayer implementation for introspection by tests and/or responses directed by tests. - */ -@JNINamespace("weblayer") -public class GoogleAccountAccessTokenFetcherTestStub - extends IGoogleAccountAccessTokenFetcherClient.Stub { - private HashMap<Integer, ValueCallback<String>> mOutstandingRequests = - new HashMap<Integer, ValueCallback<String>>(); - private int mMostRecentRequestId; - private Set<String> mMostRecentScopes; - private Set<String> mScopesForMostRecentInvalidToken = new HashSet<String>(); - private String mMostRecentInvalidToken = ""; - - @Override - public void fetchAccessToken( - IObjectWrapper scopesWrapper, IObjectWrapper onTokenFetchedWrapper) { - Set<String> scopes = ObjectWrapper.unwrap(scopesWrapper, Set.class); - ValueCallback<String> valueCallback = - ObjectWrapper.unwrap(onTokenFetchedWrapper, ValueCallback.class); - - mMostRecentScopes = scopes; - mMostRecentRequestId++; - mOutstandingRequests.put(mMostRecentRequestId, valueCallback); - } - - @Override - public void onAccessTokenIdentifiedAsInvalid( - IObjectWrapper scopesWrapper, IObjectWrapper tokenWrapper) { - Set<String> scopes = ObjectWrapper.unwrap(scopesWrapper, Set.class); - String token = ObjectWrapper.unwrap(tokenWrapper, String.class); - - mScopesForMostRecentInvalidToken = scopes; - mMostRecentInvalidToken = token; - } - - @CalledByNative - int getMostRecentRequestId() { - return mMostRecentRequestId; - } - - @CalledByNative - String[] getMostRecentRequestScopes() { - return mMostRecentScopes.toArray(new String[0]); - } - - @CalledByNative - int getNumOutstandingRequests() { - return mOutstandingRequests.size(); - } - - @CalledByNative - String[] getScopesForMostRecentInvalidToken() { - return mScopesForMostRecentInvalidToken.toArray(new String[0]); - } - - @CalledByNative - String getMostRecentInvalidToken() { - return mMostRecentInvalidToken; - } - - @CalledByNative - public void respondWithTokenForRequest(int requestId, String token) { - ValueCallback<String> callback = mOutstandingRequests.get(requestId); - assert callback != null; - mOutstandingRequests.remove(requestId); - - callback.onReceiveValue(token); - } -}
diff --git a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java b/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java deleted file mode 100644 index 330741f4..0000000 --- a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import android.content.Context; -import android.text.TextUtils; - -import org.chromium.base.Callback; -import org.chromium.base.ContextUtils; -import org.chromium.base.ThreadUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.base.annotations.NativeMethods; -import org.chromium.weblayer.TestProfile; -import org.chromium.weblayer.TestWebLayer; -import org.chromium.weblayer.WebLayer; - -/** - * Helper for metrics_browsertest.cc - */ -@JNINamespace("weblayer") -class MetricsTestHelper { - private static class TestGmsBridge extends GmsBridge { - private final @ConsentType int mConsentType; - private Callback<Boolean> mConsentCallback; - public static TestGmsBridge sInstance; - - public TestGmsBridge(@ConsentType int consentType) { - sInstance = this; - mConsentType = consentType; - } - - @Override - public boolean canUseGms() { - return true; - } - - @Override - public void setSafeBrowsingHandler() { - // We don't have this specialized service here. - } - - @Override - public void queryMetricsSetting(Callback<Boolean> callback) { - ThreadUtils.assertOnUiThread(); - if (mConsentType == ConsentType.DELAY_CONSENT) { - mConsentCallback = callback; - } else { - callback.onResult(mConsentType == ConsentType.CONSENT); - } - } - - @Override - public void logMetrics(byte[] data) { - MetricsTestHelperJni.get().onLogMetrics(data); - } - } - - @CalledByNative - private static void installTestGmsBridge(@ConsentType int consentType) { - GmsBridge.injectInstance(new TestGmsBridge(consentType)); - } - - @CalledByNative - private static void runConsentCallback(boolean hasConsent) { - assert TestGmsBridge.sInstance != null; - assert TestGmsBridge.sInstance.mConsentCallback != null; - TestGmsBridge.sInstance.mConsentCallback.onResult(hasConsent); - } - - @CalledByNative - private static void createProfile(String name, boolean incognito) { - Context appContext = ContextUtils.getApplicationContext(); - WebLayer weblayer = TestWebLayer.loadSync(appContext); - - if (incognito) { - String nameOrNull = null; - if (!TextUtils.isEmpty(name)) nameOrNull = name; - weblayer.getIncognitoProfile(nameOrNull); - } else { - weblayer.getProfile(name); - } - } - - @CalledByNative - private static void destroyProfile(String name, boolean incognito) { - Context appContext = ContextUtils.getApplicationContext(); - WebLayer weblayer = TestWebLayer.loadSync(appContext); - - if (incognito) { - String nameOrNull = null; - if (!TextUtils.isEmpty(name)) nameOrNull = name; - TestProfile.destroy(weblayer.getIncognitoProfile(nameOrNull)); - } else { - TestProfile.destroy(weblayer.getProfile(name)); - } - } - - @CalledByNative - private static void removeTestGmsBridge() { - GmsBridge.injectInstance(null); - } - - @NativeMethods - interface Natives { - void onLogMetrics(byte[] data); - } -}
diff --git a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/TranslateTestBridge.java b/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/TranslateTestBridge.java deleted file mode 100644 index d9292e9..0000000 --- a/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/TranslateTestBridge.java +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.weblayer_private; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.components.translate.TranslateMenu; - -/** - * Bridge for TranslateCompactInfoBar test methods invoked from native. - */ -@JNINamespace("weblayer") -public class TranslateTestBridge { - TranslateTestBridge() {} - - // Selects the tab corresponding to |actionType| to simulate the user pressing on this tab. - @CalledByNative - private static void selectTab(TranslateCompactInfoBar infobar, int actionType) { - infobar.selectTabForTesting(actionType); - } - - @CalledByNative - // Simulates a click of the overflow menu item for "never translate this language." - private static void clickNeverTranslateLanguageMenuItem(TranslateCompactInfoBar infobar) { - infobar.onOverflowMenuItemClicked(TranslateMenu.ID_OVERFLOW_NEVER_LANGUAGE); - } - - @CalledByNative - // Simulates a click of the overflow menu item for "never translate this site." - private static void clickNeverTranslateSiteMenuItem(TranslateCompactInfoBar infobar) { - infobar.onOverflowMenuItemClicked(TranslateMenu.ID_OVERFLOW_NEVER_SITE); - } -}
diff --git a/weblayer/shell/android/browsertests_apk/translate_test_bridge.cc b/weblayer/shell/android/browsertests_apk/translate_test_bridge.cc deleted file mode 100644 index f48b940..0000000 --- a/weblayer/shell/android/browsertests_apk/translate_test_bridge.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/shell/android/browsertests_apk/translate_test_bridge.h" - -#include "base/android/jni_android.h" -#include "weblayer/test/weblayer_browsertests_jni/TranslateTestBridge_jni.h" - -using base::android::JavaParamRef; -using base::android::ScopedJavaLocalRef; - -namespace weblayer { - -// static -void TranslateTestBridge::SelectButton( - TranslateCompactInfoBar* infobar, - TranslateCompactInfoBar::ActionType action_type) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_TranslateTestBridge_selectTab(env, infobar->GetJavaInfoBar(), - action_type); -} - -// static -void TranslateTestBridge::ClickOverflowMenuItem( - TranslateCompactInfoBar* infobar, - OverflowMenuItemId item_id) { - JNIEnv* env = base::android::AttachCurrentThread(); - switch (item_id) { - case OverflowMenuItemId::NEVER_TRANSLATE_LANGUAGE: - Java_TranslateTestBridge_clickNeverTranslateLanguageMenuItem( - env, infobar->GetJavaInfoBar()); - return; - case OverflowMenuItemId::NEVER_TRANSLATE_SITE: - Java_TranslateTestBridge_clickNeverTranslateSiteMenuItem( - env, infobar->GetJavaInfoBar()); - return; - } -} - -} // namespace weblayer
diff --git a/weblayer/shell/android/browsertests_apk/translate_test_bridge.h b/weblayer/shell/android/browsertests_apk/translate_test_bridge.h deleted file mode 100644 index 2e605ba..0000000 --- a/weblayer/shell/android/browsertests_apk/translate_test_bridge.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_SHELL_ANDROID_BROWSERTESTS_APK_TRANSLATE_TEST_BRIDGE_H_ -#define WEBLAYER_SHELL_ANDROID_BROWSERTESTS_APK_TRANSLATE_TEST_BRIDGE_H_ - -#include "weblayer/browser/translate_compact_infobar.h" - -namespace weblayer { - -// Bridge to support translate_browsertest.cc to calling into Java. -class TranslateTestBridge { - public: - TranslateTestBridge(); - ~TranslateTestBridge(); - - TranslateTestBridge(const TranslateTestBridge&) = delete; - TranslateTestBridge& operator=(const TranslateTestBridge&) = delete; - - enum class OverflowMenuItemId { - NEVER_TRANSLATE_LANGUAGE = 0, - NEVER_TRANSLATE_SITE = 1, - }; - - // Instructs the Java infobar to select the button corresponding to - // |action_type|. - static void SelectButton(TranslateCompactInfoBar* infobar, - TranslateCompactInfoBar::ActionType action_type); - - // Instructs the Java infobar to click the specified overflow menu item. - static void ClickOverflowMenuItem(TranslateCompactInfoBar* infobar, - OverflowMenuItemId item_id); -}; - -} // namespace weblayer - -#endif // WEBLAYER_SHELL_ANDROID_BROWSERTESTS_APK_TRANSLATE_TEST_BRIDGE_H_
diff --git a/weblayer/shell/android/browsertests_apk/weblayer_browser_tests_jni_onload.cc b/weblayer/shell/android/browsertests_apk/weblayer_browser_tests_jni_onload.cc deleted file mode 100644 index 75d9b80..0000000 --- a/weblayer/shell/android/browsertests_apk/weblayer_browser_tests_jni_onload.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> - -#include "base/android/jni_android.h" -#include "base/android/library_loader/library_loader_hooks.h" -#include "base/functional/bind.h" -#include "base/message_loop/message_pump.h" -#include "content/public/app/content_jni_onload.h" -#include "content/public/app/content_main.h" -#include "content/public/test/nested_message_pump_android.h" -#include "testing/android/native_test/native_test_launcher.h" -#include "weblayer/app/content_main_delegate_impl.h" -#include "weblayer/shell/app/shell_main_params.h" - -// This is called by the VM when the shared library is first loaded. -JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { - base::android::InitVM(vm); - if (!content::android::OnJNIOnLoadInit()) - return -1; - - // This needs to be done before base::TestSuite::Initialize() is called, - // as it also tries to set MessagePumpForUIFactory. - base::MessagePump::OverrideMessagePumpForUIFactory( - []() -> std::unique_ptr<base::MessagePump> { - return std::make_unique<content::NestedMessagePumpAndroid>(); - }); - - content::SetContentMainDelegate( - new weblayer::ContentMainDelegateImpl(weblayer::CreateMainParams())); - return JNI_VERSION_1_4; -}
diff --git a/weblayer/shell/android/service_provider/AndroidManifest.xml b/weblayer/shell/android/service_provider/AndroidManifest.xml deleted file mode 100644 index baebad3..0000000 --- a/weblayer/shell/android/service_provider/AndroidManifest.xml +++ /dev/null
@@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2022 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chromium.webengine.sandbox"> - - <application android:label="WESandbox"> - - <service android:name="org.chromium.weblayer.BrowserSandboxService" - android:exported="true" > - <intent-filter> - <action android:name="org.chromium.weblayer.intent.action.BROWSERSANDBOX" /> - </intent-filter> - </service> - - <service android:name="org.chromium.weblayer.BrowserInProcessService" - android:exported="false" > - <intent-filter> - <action android:name="org.chromium.weblayer.intent.action.BROWSERINPROCESS" /> - </intent-filter> - </service> - <service android:name="org.chromium.weblayer.MediaSessionService" - android:foregroundServiceType="mediaPlayback" - android:exported="false"> - <intent-filter> - <action android:name="android.intent.action.MEDIA_BUTTON" /> - </intent-filter> - </service> - - - - <meta-data android:name="org.chromium.weblayer.skipOriginVerification" android:value="false" /> - <meta-data android:name="org.chromium.weblayer.strictLocalhostVerification" android:value="true" /> - - <!-- TODO(rayankans): Make this a template. --> - <meta-data android:name="org.chromium.weblayer.WebLayerPackage" - android:value="org.chromium.weblayer.support"/> - - </application> -</manifest>
diff --git a/weblayer/shell/android/support_apk/AndroidManifest.xml b/weblayer/shell/android/support_apk/AndroidManifest.xml deleted file mode 100644 index bd4d5ad3..0000000 --- a/weblayer/shell/android/support_apk/AndroidManifest.xml +++ /dev/null
@@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2019 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chromium.weblayer.support"> - - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - <uses-permission android:name="android.permission.CAMERA"/> - <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> - <uses-permission android:name="android.permission.NFC"/> - <uses-permission android:name="android.permission.RECORD_AUDIO"/> - <uses-permission android:name="android.permission.VIBRATE"/> - <uses-permission android:name="android.permission.WAKE_LOCK"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - - <application android:label="WebLayer support"> - <!-- AR (Augmented Reality) support. --> - <meta-data android:name="com.google.ar.core" android:value="optional" /> - </application> -</manifest>
diff --git a/weblayer/shell/android/webengine_shell_apk/AndroidManifest.xml b/weblayer/shell/android/webengine_shell_apk/AndroidManifest.xml deleted file mode 100644 index 695dd1af..0000000 --- a/weblayer/shell/android/webengine_shell_apk/AndroidManifest.xml +++ /dev/null
@@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2022 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="org.chromium.webengine.shell"> - - <application - android:name="WebEngineShellApplication" - android:label="WE shell" - tools:replace="android:label" - android:supportsRtl="true"> - <activity android:name="WebEngineShellActivity" - android:launchMode="singleTask" - android:theme="@style/ShellTheme" - android:windowSoftInputMode="adjustResize" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <activity android:name="WebEngineStateTestActivity" - android:launchMode="singleTask" - android:theme="@style/ShellTheme" - android:windowSoftInputMode="adjustResize" - android:exported="true"> - </activity> - <activity android:name="WebEngineNavigationTestActivity" - android:launchMode="singleTask" - android:theme="@style/ShellTheme" - android:windowSoftInputMode="adjustResize" - android:exported="true"> - </activity> - <activity android:name="WebEngineNavigationTestActivity$EmptyActivity" - android:launchMode="singleTask" - android:theme="@style/ShellTheme" - android:windowSoftInputMode="adjustResize" - android:exported="true"> - </activity> - <activity android:name="WebEngineSinglePageActivity" - android:launchMode="singleTask" - android:theme="@style/ShellTheme" - android:windowSoftInputMode="adjustResize" - android:exported="true"> - </activity> - - <meta-data android:name="org.chromium.webengine.shell.BrowserProcessMode" - android:value="{{ browser_process_mode }}"/> - </application> -</manifest>
diff --git a/weblayer/shell/android/webengine_shell_apk/res/drawable-night/ic_refresh.xml b/weblayer/shell/android/webengine_shell_apk/res/drawable-night/ic_refresh.xml deleted file mode 100644 index 7047dc9..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/drawable-night/ic_refresh.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24" > - <path - android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" - android:fillColor="@android:color/white" /> -</vector>
diff --git a/weblayer/shell/android/webengine_shell_apk/res/drawable-night/ic_stop.xml b/weblayer/shell/android/webengine_shell_apk/res/drawable-night/ic_stop.xml deleted file mode 100644 index effdfcc..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/drawable-night/ic_stop.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24" > - <path - android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" - android:fillColor="@android:color/white" /> -</vector>
diff --git a/weblayer/shell/android/webengine_shell_apk/res/drawable/ic_refresh.xml b/weblayer/shell/android/webengine_shell_apk/res/drawable/ic_refresh.xml deleted file mode 100644 index cc0605b..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/drawable/ic_refresh.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24" > - <path - android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" - android:fillColor="@android:color/black" /> -</vector>
diff --git a/weblayer/shell/android/webengine_shell_apk/res/drawable/ic_stop.xml b/weblayer/shell/android/webengine_shell_apk/res/drawable/ic_stop.xml deleted file mode 100644 index 5ae7291..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/drawable/ic_stop.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24" > - <path - android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" - android:fillColor="@android:color/black" /> -</vector>
diff --git a/weblayer/shell/android/webengine_shell_apk/res/layout/main.xml b/weblayer/shell/android/webengine_shell_apk/res/layout/main.xml deleted file mode 100644 index ad88dde..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/layout/main.xml +++ /dev/null
@@ -1,64 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2022 The Chromium Authors -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" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <Spinner - android:id="@+id/activity_nav" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - <TextView - android:id="@+id/version" - android:text="x.x.x" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - <LinearLayout - android:id="@+id/app_bar" - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:weightSum="6"> - <ImageButton - android:id="@+id/reload_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@drawable/ic_stop" /> - <EditText - android:id="@+id/url_bar" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="5" - android:inputType="textUri" - android:selectAllOnFocus="true" /> - <Button - android:id="@+id/tab_count" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" /> - <org.chromium.webengine.shell.topbar.CustomSpinner - android:id="@+id/tab_list" - android:layout_width="0dp" - android:layout_height="0dp" - android:spinnerMode="dialog" - android:visibility="invisible" /> - </LinearLayout> - <ProgressBar - android:id="@+id/progress_bar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:minHeight="3dp" - style="@android:style/Widget.ProgressBar.Horizontal" - android:progressBackgroundTint="#0fff" - android:progressTint="#4285F4" /> - <androidx.fragment.app.FragmentContainerView - android:id="@+id/fragment_container_view" - android:layout_width="match_parent" - android:layout_height="match_parent" /> -</LinearLayout> -
diff --git a/weblayer/shell/android/webengine_shell_apk/res/layout/navigation_test.xml b/weblayer/shell/android/webengine_shell_apk/res/layout/navigation_test.xml deleted file mode 100644 index 95185c05..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/layout/navigation_test.xml +++ /dev/null
@@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2022 The Chromium Authors -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" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <Spinner - android:id="@+id/activity_nav" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - <LinearLayout - android:orientation="horizontal" - android:layout_gravity="bottom" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <Button - android:id="@+id/open_activity" - android:text="Open Activity" - android:layout_weight="1" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> - <Button - android:id="@+id/replace_fragment" - android:text="Add Fragment" - android:layout_weight="1" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> - </LinearLayout> - <androidx.fragment.app.FragmentContainerView - android:id="@+id/fragment_container_view" - android:layout_width="match_parent" - android:layout_height="match_parent" /> -</LinearLayout> -
diff --git a/weblayer/shell/android/webengine_shell_apk/res/layout/spa.xml b/weblayer/shell/android/webengine_shell_apk/res/layout/spa.xml deleted file mode 100644 index b9dd750..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/layout/spa.xml +++ /dev/null
@@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2023 The Chromium Authors -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" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <androidx.fragment.app.FragmentContainerView - android:id="@+id/fragment_container_view" - android:layout_width="match_parent" - android:layout_height="match_parent" /> -</LinearLayout> \ No newline at end of file
diff --git a/weblayer/shell/android/webengine_shell_apk/res/layout/state_test.xml b/weblayer/shell/android/webengine_shell_apk/res/layout/state_test.xml deleted file mode 100644 index 00563b3..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/layout/state_test.xml +++ /dev/null
@@ -1,125 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2022 The Chromium Authors -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" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <Spinner - android:id="@+id/activity_nav" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - <LinearLayout - android:orientation="horizontal" - android:layout_gravity="bottom" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <TextView - android:id="@+id/sandbox_state" - android:text="Sandbox" - android:padding="16px" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - <Button - android:id="@+id/start_sandbox" - android:text="Start" - android:layout_weight="1" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> - <Button - android:id="@+id/shutdown_sandbox" - android:text="Shutdown" - android:enabled="true" - android:layout_weight="1" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> - </LinearLayout> - <LinearLayout - android:orientation="horizontal" - android:layout_gravity="bottom" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <TextView - android:id="@+id/engine_state" - android:padding="16px" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - <Button - android:id="@+id/start_engine" - android:text="Start" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - <Button - android:id="@+id/shutdown_engine" - android:text="Close" - android:enabled="true" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - </LinearLayout> - <LinearLayout - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <TextView - android:id="@+id/num_open_tabs" - android:padding="16px" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" - /> - <Button - android:id="@+id/open_tab" - android:text="Open Tab" - android:enabled="true" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - <Button - android:id="@+id/close_tab" - android:text="Close Tab" - android:enabled="true" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - </LinearLayout> - <LinearLayout - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <TextView - android:id="@+id/fragment_state" - android:padding="16px" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - <Button - android:id="@+id/inflate_fragment" - android:text="Inflate" - android:enabled="true" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent" /> - <Button - android:id="@+id/remove_fragment" - android:text="Remove" - android:enabled="true" - android:layout_weight="1" - android:layout_height="wrap_content" - android:layout_width="fill_parent"/> - - </LinearLayout> - <androidx.fragment.app.FragmentContainerView - android:id="@+id/fragment_container_view" - android:layout_width="match_parent" - android:layout_height="fill_parent" /> - -</LinearLayout> -
diff --git a/weblayer/shell/android/webengine_shell_apk/res/values/strings.xml b/weblayer/shell/android/webengine_shell_apk/res/values/strings.xml deleted file mode 100644 index babfe09..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/values/strings.xml +++ /dev/null
@@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2022 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<resources xmlns:tools="http://schemas.android.com/tools"> - <string-array name="activities_drop_down"> - <item>Shell</item> - <item>UI/WebEngine State Test</item> - <item>Navigation Test</item> - <item>SPA Test</item> - </string-array> -</resources> \ No newline at end of file
diff --git a/weblayer/shell/android/webengine_shell_apk/res/values/styles.xml b/weblayer/shell/android/webengine_shell_apk/res/values/styles.xml deleted file mode 100644 index 5396282..0000000 --- a/weblayer/shell/android/webengine_shell_apk/res/values/styles.xml +++ /dev/null
@@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2022 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<resources xmlns:tools="http://schemas.android.com/tools"> - <style name="ShellTheme" parent="Theme.AppCompat.DayNight.NoActionBar"/> -</resources> \ No newline at end of file
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/DefaultObservers.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/DefaultObservers.java deleted file mode 100644 index 10c1d97..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/DefaultObservers.java +++ /dev/null
@@ -1,109 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell; - -import android.graphics.Bitmap; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.base.Log; -import org.chromium.webengine.Navigation; -import org.chromium.webengine.NavigationObserver; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabListObserver; -import org.chromium.webengine.TabObserver; -import org.chromium.webengine.WebEngine; - -/** - * Default observers for Test Activities. - */ -public class DefaultObservers implements TabListObserver, TabObserver, NavigationObserver { - private static final String TAG = "WEDefaultObservers"; - - // TabObserver implementation. - - @Override - public void onVisibleUriChanged(@NonNull Tab tab, @NonNull String uri) { - Log.i(TAG, this + "received Tab Event: 'onVisibleUriChanged(" + uri + ")'"); - } - - @Override - public void onTitleUpdated(@NonNull Tab tab, @NonNull String title) { - Log.i(TAG, this + "received Tab Event: 'onTitleUpdated(" + title + ")'"); - } - - @Override - public void onRenderProcessGone(@NonNull Tab tab) { - Log.i(TAG, this + "received Tab Event: 'onRenderProcessGone()'"); - } - - @Override - public void onFaviconChanged(@NonNull Tab tab, @Nullable Bitmap favicon) { - Log.i(TAG, - this + "received Tab Event: 'onFaviconChanged(" - + (favicon == null ? "null" : favicon.toString()) + ")'"); - } - - // NavigationObserver implementation. - - @Override - public void onNavigationFailed(@NonNull Tab tab, @NonNull Navigation navigation) { - Log.i(TAG, this + "received NavigationEvent: 'onNavigationFailed()';"); - Log.i(TAG, - this + "Navigation: url:" + navigation.getUri() - + ", HTTP-StatusCode: " + navigation.getStatusCode() - + ", samePage: " + navigation.isSameDocument()); - } - - @Override - public void onNavigationCompleted(@NonNull Tab tab, @NonNull Navigation navigation) { - Log.i(TAG, this + "received NavigationEvent: 'onNavigationCompleted()';"); - Log.i(TAG, - this + "Navigation: url:" + navigation.getUri() - + ", HTTP-StatusCode: " + navigation.getStatusCode() - + ", samePage: " + navigation.isSameDocument()); - } - - @Override - public void onNavigationStarted(@NonNull Tab tab, @NonNull Navigation navigation) { - Log.i(TAG, this + "received NavigationEvent: 'onNavigationStarted()';"); - } - - @Override - public void onNavigationRedirected(@NonNull Tab tab, @NonNull Navigation navigation) { - Log.i(TAG, this + "received NavigationEvent: 'onNavigationRedirected()';"); - } - - @Override - public void onLoadProgressChanged(@NonNull Tab tab, double progress) { - Log.i(TAG, this + "received NavigationEvent: 'onLoadProgressChanged()';"); - } - - // TabListObserver implementation. - - @Override - public void onActiveTabChanged(@NonNull WebEngine webEngine, @Nullable Tab activeTab) { - Log.i(TAG, this + "received TabList Event: 'onActiveTabChanged'-event"); - } - - @Override - public void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) { - Log.i(TAG, this + "received TabList Event: 'onTabAdded'-event"); - // Recursively add tab and navigation observers to any new tab. - tab.registerTabObserver(this); - tab.getNavigationController().registerNavigationObserver(this); - } - - @Override - public void onTabRemoved(@NonNull WebEngine webEngine, @NonNull Tab tab) { - Log.i(TAG, this + "received TabList Event: 'onTabRemoved'-event"); - } - - @Override - public void onWillDestroyFragmentAndAllTabs(@NonNull WebEngine webEngine) { - Log.i(TAG, this + "received TabList Event: 'onWillDestroyFragmentAndAllTabs'-event"); - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineNavigationTestActivity.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineNavigationTestActivity.java deleted file mode 100644 index 8d66a4c..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineNavigationTestActivity.java +++ /dev/null
@@ -1,148 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell; - -import android.content.Context; -import android.content.Intent; -import android.graphics.Color; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.widget.Button; -import android.widget.Spinner; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabManager; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -/** - * Activity for testing navigations and state resumption. - */ -public class WebEngineNavigationTestActivity extends AppCompatActivity { - private static final String TAG = "WebEngineShell"; - - private static final String WEB_ENGINE_TAG = "WEB_ENGINE_TAG"; - - private Context mContext; - - private WebSandbox mWebSandbox; - - private DefaultObservers mDefaultObservers = new DefaultObservers(); - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.navigation_test); - mContext = getApplicationContext(); - - WebEngineShellActivity.setupActivitySpinner( - (Spinner) findViewById(R.id.activity_nav), this, 2); - - ListenableFuture<WebSandbox> webSandboxFuture = WebSandbox.create(mContext); - Futures.addCallback(webSandboxFuture, new FutureCallback<WebSandbox>() { - @Override - public void onSuccess(WebSandbox webSandbox) { - onWebSandboxReady(webSandbox, savedInstanceState); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - - Button openActivityButton = (Button) findViewById(R.id.open_activity); - openActivityButton.setOnClickListener( - (View v) -> { super.startActivity(new Intent(this, EmptyActivity.class)); }); - - Button replaceFragmentButton = (Button) findViewById(R.id.replace_fragment); - replaceFragmentButton.setOnClickListener((View v) -> { - getSupportFragmentManager() - .beginTransaction() - .setReorderingAllowed(true) - .add(R.id.fragment_container_view, new EmptyFragment()) - .addToBackStack(null) - .commit(); - }); - } - - @Override - public void startActivity(Intent intent) { - if (mWebSandbox != null) { - // Shutdown sandbox before another activity is opened. - mWebSandbox.shutdown(); - mWebSandbox = null; - } - super.startActivity(intent); - } - - private void onWebSandboxReady(WebSandbox webSandbox, Bundle savedInstanceState) { - mWebSandbox = webSandbox; - webSandbox.setRemoteDebuggingEnabled(true); - - WebEngine webEngine = webSandbox.getWebEngine(WEB_ENGINE_TAG); - if (webEngine != null) { - assert webSandbox.getWebEngines().size() == 1; - - return; - } - - ListenableFuture<WebEngine> webEngineFuture = webSandbox.createWebEngine(WEB_ENGINE_TAG); - Futures.addCallback(webEngineFuture, new FutureCallback<WebEngine>() { - @Override - public void onSuccess(WebEngine webEngine) { - onWebEngineReady(webEngine); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - } - - private void onWebEngineReady(WebEngine webEngine) { - TabManager tabManager = webEngine.getTabManager(); - - Tab activeTab = tabManager.getActiveTab(); - activeTab.getNavigationController().navigate("https://google.com"); - - activeTab.registerTabObserver(mDefaultObservers); - activeTab.getNavigationController().registerNavigationObserver(mDefaultObservers); - tabManager.registerTabListObserver(mDefaultObservers); - - getSupportFragmentManager() - .beginTransaction() - .setReorderingAllowed(true) - .add(R.id.fragment_container_view, webEngine.getFragment()) - .commit(); - } - - /** - * Empty Activity used to test back navigation to an Activity containing a WebFragment. - */ - public static class EmptyActivity extends AppCompatActivity {} - - /** - * Empty Fragment used to test back navigation to a WebFragment. - */ - public static class EmptyFragment extends Fragment { - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = new View(getActivity()); - v.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); - v.setBackgroundColor(Color.parseColor("#f1f1f1")); - return v; - } - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java deleted file mode 100644 index f33ccab..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java +++ /dev/null
@@ -1,475 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.util.Patterns; -import android.view.KeyEvent; -import android.view.View; -import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.ProgressBar; -import android.widget.Spinner; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.content.ContextCompat; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.base.Log; -import org.chromium.webengine.CookieManager; -import org.chromium.webengine.FullscreenCallback; -import org.chromium.webengine.FullscreenClient; -import org.chromium.webengine.Navigation; -import org.chromium.webengine.NavigationObserver; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabListObserver; -import org.chromium.webengine.TabManager; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebFragment; -import org.chromium.webengine.WebSandbox; -import org.chromium.webengine.shell.topbar.CustomSpinner; -import org.chromium.webengine.shell.topbar.TabEventsDelegate; -import org.chromium.webengine.shell.topbar.TabEventsObserver; - -import java.util.Arrays; - -/** - * Activity for managing the Demo Shell. - * - * TODO(swestphal): - * - UI to add/remove tabs - * - Expose some tab/navigation events in the UI - * - Move cookie test to manual-test activity - * - Move registerWebMessageCallback to manual-test activity - */ -public class WebEngineShellActivity - extends AppCompatActivity implements FullscreenCallback, TabEventsObserver { - private static final String TAG = "WebEngineShell"; - - private static final String WEB_FRAGMENT_TAG = "WEB_FRAGMENT_TAG"; - - private WebEngineShellApplication mApplication; - private Context mContext; - - private TabManager mTabManager; - private TabEventsDelegate mTabEventsDelegate; - - private ProgressBar mProgressBar; - private EditText mUrlBar; - private Button mTabCountButton; - private CustomSpinner mTabListSpinner; - private ArrayAdapter<TabWrapper> mTabListAdapter; - - private ImageButton mReloadButton; - private Drawable mRefreshDrawable; - private Drawable mStopDrawable; - - private DefaultObservers mDefaultObservers; - - private int mSystemVisibilityToRestore; - private boolean mIsTabListOpen; - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (savedInstanceState != null) { - mIsTabListOpen = savedInstanceState.getBoolean("isTabListOpen"); - } - setContentView(R.layout.main); - - mApplication = (WebEngineShellApplication) getApplication(); - mContext = getApplicationContext(); - mDefaultObservers = new DefaultObservers(); - - setupActivitySpinner((Spinner) findViewById(R.id.activity_nav), this, 0); - mProgressBar = findViewById(R.id.progress_bar); - mUrlBar = findViewById(R.id.url_bar); - mTabCountButton = findViewById(R.id.tab_count); - mTabListSpinner = findViewById(R.id.tab_list); - - mReloadButton = findViewById(R.id.reload_button); - mRefreshDrawable = getDrawable(R.drawable.ic_refresh); - mStopDrawable = getDrawable(R.drawable.ic_stop); - setProgress(1.0); - - mUrlBar.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - Uri query = Uri.parse(v.getText().toString()); - if (query.isAbsolute()) { - mTabManager.getActiveTab().getNavigationController().navigate( - query.normalizeScheme().toString()); - } else if (Patterns.DOMAIN_NAME.matcher(query.toString()).matches()) { - mTabManager.getActiveTab().getNavigationController().navigate( - "https://" + query); - } else { - mTabManager.getActiveTab().getNavigationController().navigate( - "https://www.google.com/search?q=" - + Uri.encode(v.getText().toString())); - } - // Hides keyboard on Enter key pressed - InputMethodManager imm = (InputMethodManager) mContext.getSystemService( - Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(v.getWindowToken(), 0); - return true; - } - }); - - mReloadButton.setOnClickListener(v -> { - if (mReloadButton.getDrawable().equals(mRefreshDrawable)) { - mTabManager.getActiveTab().getNavigationController().reload(); - } else if (mReloadButton.getDrawable().equals(mStopDrawable)) { - mTabManager.getActiveTab().getNavigationController().stop(); - } - }); - - mTabCountButton.setOnClickListener(v -> mTabListSpinner.performClick()); - - mTabListSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { - mTabListAdapter.getItem(pos).getTab().setActive(); - } - @Override - public void onNothingSelected(AdapterView<?> parent) {} - }); - - ListenableFuture<String> sandboxVersionFuture = WebSandbox.getVersion(mContext); - Futures.addCallback(sandboxVersionFuture, new FutureCallback<String>() { - @Override - public void onSuccess(String version) { - ((TextView) findViewById(R.id.version)).setText(version); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - - Futures.addCallback(mApplication.getWebEngine(), new FutureCallback<WebEngine>() { - @Override - public void onSuccess(WebEngine webEngine) { - onWebEngineReady(webEngine); - } - - @Override - public void onFailure(Throwable thrown) { - Toast.makeText(mContext, "Failed to start WebEngine.", Toast.LENGTH_LONG).show(); - } - }, ContextCompat.getMainExecutor(mContext)); - - Futures.addCallback( - mApplication.getTabEventsDelegate(), new FutureCallback<TabEventsDelegate>() { - @Override - public void onSuccess(TabEventsDelegate tabEventsDelegate) { - mTabEventsDelegate = tabEventsDelegate; - tabEventsDelegate.registerObserver(WebEngineShellActivity.this); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - outState.putBoolean("isTabListOpen", mTabListSpinner.isOpen()); - super.onSaveInstanceState(outState); - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (mTabManager == null) return; - for (Tab tab : mTabManager.getAllTabs()) { - tab.setFullscreenCallback(null); - } - if (mTabEventsDelegate != null) mTabEventsDelegate.unregisterObserver(); - } - - @Override - public void onBackPressed() { - WebFragment fragment = - (WebFragment) getSupportFragmentManager().findFragmentByTag(WEB_FRAGMENT_TAG); - if (fragment == null) { - super.onBackPressed(); - return; - } - ListenableFuture<Boolean> tryNavigateBackFuture = fragment.getWebEngine().tryNavigateBack(); - Futures.addCallback(tryNavigateBackFuture, new FutureCallback<Boolean>() { - @Override - public void onSuccess(Boolean didNavigate) { - if (!didNavigate) { - WebEngineShellActivity.super.onBackPressed(); - } - } - @Override - public void onFailure(Throwable thrown) { - WebEngineShellActivity.super.onBackPressed(); - } - }, ContextCompat.getMainExecutor(mContext)); - } - - // TODO(swestphal): Move this to a helper class. - static void setupActivitySpinner(Spinner spinner, Activity activity, int index) { - ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(activity, - R.array.activities_drop_down, android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - spinner.setSelection(index, false); - spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { - final Intent intent; - switch (pos) { - case 0: - intent = new Intent(activity, WebEngineShellActivity.class); - break; - case 1: - intent = new Intent(activity, WebEngineStateTestActivity.class); - break; - case 2: - intent = new Intent(activity, WebEngineNavigationTestActivity.class); - break; - case 3: - intent = new Intent(activity, WebEngineSinglePageActivity.class); - break; - default: - assert false : "Unhandled item: " + String.valueOf(pos); - intent = null; - } - activity.startActivity(intent); - activity.finish(); - } - @Override - public void onNothingSelected(AdapterView<?> parent) {} - }); - } - - @Override - public void onEnterFullscreen(WebEngine webEngine, Tab tab, FullscreenClient fullscreenClient) { - final WindowManager.LayoutParams attrs = getWindow().getAttributes(); - attrs.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; - getWindow().setAttributes(attrs); - - findViewById(R.id.activity_nav).setVisibility(View.GONE); - findViewById(R.id.version).setVisibility(View.GONE); - findViewById(R.id.app_bar).setVisibility(View.GONE); - findViewById(R.id.progress_bar).setVisibility(View.GONE); - - View decorView = getWindow().getDecorView(); - - mSystemVisibilityToRestore = decorView.getSystemUiVisibility(); - decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar - | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar - | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - } - - @Override - public void onExitFullscreen(WebEngine webEngine, Tab tab) { - View decorView = getWindow().getDecorView(); - decorView.setSystemUiVisibility(mSystemVisibilityToRestore); - - findViewById(R.id.activity_nav).setVisibility(View.VISIBLE); - findViewById(R.id.version).setVisibility(View.VISIBLE); - findViewById(R.id.app_bar).setVisibility(View.VISIBLE); - findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); - - final WindowManager.LayoutParams attrs = getWindow().getAttributes(); - if ((attrs.flags & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) != 0) { - attrs.flags &= ~WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; - getWindow().setAttributes(attrs); - } - } - - private void onWebEngineReady(WebEngine webEngine) { - mTabManager = webEngine.getTabManager(); - - CookieManager cookieManager = webEngine.getCookieManager(); - Tab activeTab = mTabManager.getActiveTab(); - - mTabCountButton.setText(String.valueOf(getTabsCount())); - mTabListAdapter = new ArrayAdapter<TabWrapper>( - mContext, android.R.layout.simple_spinner_dropdown_item); - mTabListSpinner.setAdapter(mTabListAdapter); - - for (Tab t : mTabManager.getAllTabs()) { - TabWrapper tabWrapper = new TabWrapper(t); - mTabListAdapter.add(tabWrapper); - if (t.equals(mTabManager.getActiveTab())) { - mTabListSpinner.setSelection(mTabListAdapter.getPosition(tabWrapper)); - } - } - - if (mIsTabListOpen) { - mTabListSpinner.performClick(); - } - - for (Tab tab : mTabManager.getAllTabs()) { - tab.setFullscreenCallback(WebEngineShellActivity.this); - } - - if (activeTab.getDisplayUri().toString().equals("")) { - mTabManager.registerTabListObserver(new TabListObserver() { - @Override - public void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) { - tab.setFullscreenCallback(WebEngineShellActivity.this); - } - }); - activeTab.registerTabObserver(mDefaultObservers); - activeTab.getNavigationController().registerNavigationObserver(mDefaultObservers); - - activeTab.getNavigationController().registerNavigationObserver( - new NavigationObserver() { - @Override - public void onNavigationCompleted( - @NonNull Tab tab, @NonNull Navigation navigation) { - ListenableFuture<String> scriptResultFuture = - activeTab.executeScript("1+1", true); - Futures.addCallback(scriptResultFuture, new FutureCallback<String>() { - @Override - public void onSuccess(String result) { - Log.w(TAG, "executeScript result: " + result); - } - @Override - public void onFailure(Throwable thrown) { - Log.w(TAG, "executeScript failed: " + thrown); - } - }, ContextCompat.getMainExecutor(mContext)); - } - }); - activeTab.getNavigationController().navigate("https://google.com"); - - activeTab.addMessageEventListener((Tab source, String message) -> { - Log.w(TAG, "Received post message from web content: " + message); - }, Arrays.asList("*")); - activeTab.postMessage("Hello!", "*"); - - ListenableFuture<Void> setCookieFuture = - cookieManager.setCookie("https://sadchonks.com", "foo=bar123"); - Futures.addCallback(setCookieFuture, new FutureCallback<Void>() { - @Override - public void onSuccess(Void v) { - ListenableFuture<String> cookieFuture = - cookieManager.getCookie("https://sadchonks.com"); - Futures.addCallback(cookieFuture, new FutureCallback<String>() { - @Override - public void onSuccess(String value) { - Log.w(TAG, "cookie: " + value); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - } - - @Override - public void onFailure(Throwable thrown) { - Log.w(TAG, "setCookie failed: " + thrown); - } - }, ContextCompat.getMainExecutor(mContext)); - } - if (getSupportFragmentManager().findFragmentByTag(WEB_FRAGMENT_TAG) == null) { - getSupportFragmentManager() - .beginTransaction() - .setReorderingAllowed(true) - .add(R.id.fragment_container_view, webEngine.getFragment(), WEB_FRAGMENT_TAG) - .commit(); - } - } - - int getTabsCount() { - if (mTabManager == null) { - return 0; - } - return mTabManager.getAllTabs().size(); - } - - void setProgress(double progress) { - int progressValue = (int) Math.rint(progress * 100); - if (progressValue != mProgressBar.getMax()) { - mReloadButton.setImageDrawable(mStopDrawable); - mProgressBar.setVisibility(View.VISIBLE); - } else { - mReloadButton.setImageDrawable(mRefreshDrawable); - mProgressBar.setVisibility(View.INVISIBLE); - } - mProgressBar.setProgress(progressValue); - } - - @Override - public void onVisibleUriChanged(String uri) { - mUrlBar.setText(uri); - } - - @Override - public void onActiveTabChanged(Tab activeTab) { - mUrlBar.setText(activeTab.getDisplayUri().toString()); - for (int position = 0; position < mTabListAdapter.getCount(); ++position) { - TabWrapper tabWrapper = mTabListAdapter.getItem(position); - if (tabWrapper.getTab().equals(activeTab)) { - mTabListSpinner.setSelection(position); - return; - } - } - } - - @Override - public void onTabAdded(Tab tab) { - mTabCountButton.setText(String.valueOf(getTabsCount())); - mTabListAdapter.add(new TabWrapper(tab)); - } - - @Override - public void onTabRemoved(Tab tab) { - mTabCountButton.setText(String.valueOf(getTabsCount())); - for (int position = 0; position < mTabListAdapter.getCount(); ++position) { - TabWrapper tabAdapter = mTabListAdapter.getItem(position); - if (tabAdapter.getTab().equals(tab)) { - mTabListAdapter.remove(tabAdapter); - return; - } - } - } - - @Override - public void onLoadProgressChanged(double progress) { - setProgress(progress); - } - - static class TabWrapper { - final Tab mTab; - public TabWrapper(Tab tab) { - mTab = tab; - } - - public Tab getTab() { - return mTab; - } - - @NonNull - @Override - public String toString() { - return mTab.getDisplayUri().getAuthority() + mTab.getDisplayUri().getPath(); - } - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java deleted file mode 100644 index 2b11d0c..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellApplication.java +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell; - -import android.app.Application; - -import androidx.core.content.ContextCompat; - -import com.google.common.base.Function; -import com.google.common.util.concurrent.AsyncFunction; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; -import org.chromium.webengine.shell.topbar.TabEventsDelegate; - -/** - * Application for managing WebSandbox and WebEngine in the Demo Shell. - */ -public class WebEngineShellApplication extends Application { - private ListenableFuture<WebEngine> mWebEngineFuture; - private ListenableFuture<TabEventsDelegate> mTabEventsDelegateFuture; - - private TabEventsDelegate mTabEventsDelegate; - - public ListenableFuture<WebEngine> getWebEngine() { - return mWebEngineFuture; - } - - public ListenableFuture<TabEventsDelegate> getTabEventsDelegate() { - if (mTabEventsDelegate != null) { - return Futures.immediateFuture(mTabEventsDelegate); - } - - if (mTabEventsDelegateFuture != null) { - return mTabEventsDelegateFuture; - } - - Function<WebEngine, TabEventsDelegate> getTabEventsDelegateTask = - webEngine -> new TabEventsDelegate(webEngine.getTabManager()); - - mTabEventsDelegateFuture = Futures.transform( - getWebEngine(), getTabEventsDelegateTask, ContextCompat.getMainExecutor(this)); - - return mTabEventsDelegateFuture; - } - - @Override - public void onCreate() { - super.onCreate(); - - AsyncFunction<WebSandbox, WebEngine> getWebEngineTask = - webSandbox -> webSandbox.createWebEngine("shell-engine"); - mWebEngineFuture = Futures.transformAsync( - WebSandbox.create(this), getWebEngineTask, ContextCompat.getMainExecutor(this)); - Futures.addCallback(mWebEngineFuture, new FutureCallback<WebEngine>() { - @Override - public void onSuccess(WebEngine webEngine) { - mTabEventsDelegate = new TabEventsDelegate(webEngine.getTabManager()); - } - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(this)); - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineSinglePageActivity.kt b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineSinglePageActivity.kt deleted file mode 100644 index 8cd9b82..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineSinglePageActivity.kt +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -package org.chromium.webengine.shell - -import android.os.Bundle - -import org.chromium.webengine.Tab -import org.chromium.webengine.TabListObserver -import org.chromium.webengine.WebEngine -import org.chromium.webengine.WebFragment -import org.chromium.webengine.WebSandbox - -import androidx.activity.addCallback -import androidx.appcompat.app.AppCompatActivity -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.guava.await - -class WebEngineSinglePageActivity : AppCompatActivity() { - - private lateinit var mWebEngine : WebEngine; - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.spa) - - lifecycleScope.launch { - val sandbox : WebSandbox = WebSandbox.create(getApplicationContext()).await() - mWebEngine = sandbox.createWebEngine().await() - - mWebEngine.getTabManager().registerTabListObserver(object : TabListObserver { - override fun onTabAdded(webEngine : WebEngine, tab : Tab) { - tab.setActive(); - } - }) - - mWebEngine.getTabManager().getActiveTab()!!.getNavigationController().navigate("https://sadchonks.com") - supportFragmentManager.beginTransaction() - .add(R.id.fragment_container_view, mWebEngine.getFragment()) - .setReorderingAllowed(true) - .commit() - } - } - - override fun onBackPressed() { - lifecycleScope.launch { - if (!mWebEngine.tryNavigateBack().await()) { - finish(); - } - } - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineStateTestActivity.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineStateTestActivity.java deleted file mode 100644 index 255bfff..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineStateTestActivity.java +++ /dev/null
@@ -1,346 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -import org.chromium.base.Log; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabListObserver; -import org.chromium.webengine.TabManager; -import org.chromium.webengine.WebEngine; -import org.chromium.webengine.WebSandbox; - -import java.util.List; -import java.util.Set; - -/** - * Activity for managing the Demo Shell. - */ -public class WebEngineStateTestActivity extends AppCompatActivity { - private static final String TAG = "WebEngineShell"; - - private static final String WEB_ENGINE_TAG = "WEB_ENGINE_TAG"; - - private Context mContext; - - private WebSandbox mWebSandbox; - - private DefaultObservers mDefaultObservers = new DefaultObservers(); - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.state_test); - mContext = getApplicationContext(); - - setSandboxStateText(false); - setEngineStateText(false); - setNumberOfTabsText(0); - setVisibilityText(false); - - WebEngineShellActivity.setupActivitySpinner( - (Spinner) findViewById(R.id.activity_nav), this, 1); - - final Button startSandboxButton = findViewById(R.id.start_sandbox); - startSandboxButton.setOnClickListener((View v) -> { startupSandbox(); }); - final Button shutdownSandboxButton = findViewById(R.id.shutdown_sandbox); - shutdownSandboxButton.setOnClickListener((View v) -> { - boolean shutdown = shutdownSandbox(); - Log.i(TAG, "Sandbox shutdown successful: " + shutdown); - }); - - final Button startEngineButton = findViewById(R.id.start_engine); - startEngineButton.setOnClickListener((View v) -> { startupWebEngine(); }); - final Button shutdownEngineButton = findViewById(R.id.shutdown_engine); - shutdownEngineButton.setOnClickListener((View v) -> { - boolean closed = closeWebEngine(); - Log.i(TAG, "WenEngine closed successfully: " + closed); - }); - - final Button openTabButton = findViewById(R.id.open_tab); - openTabButton.setOnClickListener( - (View v) -> { openNewTabAndNavigate("https://google.com"); }); - final Button closeTabButton = findViewById(R.id.close_tab); - closeTabButton.setOnClickListener((View v) -> { - boolean closed = closeTab(); - Log.i(TAG, "Closed tab successfully: " + closed); - }); - - final Button inflateFragmentButton = findViewById(R.id.inflate_fragment); - inflateFragmentButton.setOnClickListener((View v) -> { - boolean inflated = inflateFragment(); - Log.i(TAG, "Fragment inflation successful: " + inflated); - }); - final Button removeFragmentButton = findViewById(R.id.remove_fragment); - removeFragmentButton.setOnClickListener((View v) -> { - boolean removed = removeFragment(); - Log.i(TAG, "Fragment removal successful: " + removed); - }); - } - - @Override - public void startActivity(Intent intent) { - if (mWebSandbox != null) { - // Shutdown sandbox before another activity is opened. - mWebSandbox.shutdown(); - } - super.startActivity(intent); - } - - @Override - public void onBackPressed() { - if (mWebSandbox != null) { - mWebSandbox.shutdown(); - } - super.onBackPressed(); - } - - private void setNumberOfTabsText(int num) { - ((TextView) findViewById(R.id.num_open_tabs)).setText("Tabs: (" + num + ")"); - } - - private void setSandboxStateText(boolean on) { - ((TextView) findViewById(R.id.sandbox_state)) - .setText("Sandbox: (" + (on ? "on" : "off") + ")"); - } - - private void setEngineStateText(boolean on) { - ((TextView) findViewById(R.id.engine_state)) - .setText("Engine: (" + (on ? "started" : "closed") + ")"); - } - - private void setVisibilityText(boolean visible) { - ((TextView) findViewById(R.id.fragment_state)) - .setText("Fragment: (" + (visible ? "visible" : "gone") + ")"); - } - - private void startupSandbox() { - ListenableFuture<WebSandbox> webSandboxFuture = WebSandbox.create(mContext); - Futures.addCallback(webSandboxFuture, new FutureCallback<WebSandbox>() { - @Override - public void onSuccess(WebSandbox webSandbox) { - onWebSandboxReady(webSandbox); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - } - - private void onWebSandboxReady(WebSandbox webSandbox) { - setSandboxStateText(true); - mWebSandbox = webSandbox; - webSandbox.setRemoteDebuggingEnabled(true); - - WebEngine currentWebEngine = getCurrentWebEngine(); - if (currentWebEngine != null) { - Log.i(TAG, "Sandbox and WebEngine already created"); - return; - } - Log.i(TAG, "Sandbox ready"); - startupWebEngine(); - } - - private void startupWebEngine() { - if (mWebSandbox == null) { - Log.w(TAG, "WebSandbox not started"); - return; - } - WebEngine webEngine = getCurrentWebEngine(); - if (webEngine != null) { - Log.w(TAG, "WebEngine already created"); - return; - } - ListenableFuture<WebEngine> webEngineFuture = mWebSandbox.createWebEngine(WEB_ENGINE_TAG); - Futures.addCallback(webEngineFuture, new FutureCallback<WebEngine>() { - @Override - public void onSuccess(WebEngine webEngine) { - Log.i(TAG, "WebEngine started"); - onWebEngineReady(webEngine); - } - - @Override - public void onFailure(Throwable thrown) {} - }, ContextCompat.getMainExecutor(mContext)); - } - - private void onWebEngineReady(WebEngine webEngine) { - setEngineStateText(true); - TabManager tabManager = webEngine.getTabManager(); - setNumberOfTabsText(tabManager.getAllTabs().size()); - - tabManager.registerTabListObserver(new TabListObserver() { - @Override - public void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) { - setNumberOfTabsText(tabManager.getAllTabs().size()); - // Recursively add tab and navigation observers to any new tab. - tab.registerTabObserver(mDefaultObservers); - tab.getNavigationController().registerNavigationObserver(mDefaultObservers); - } - - @Override - public void onTabRemoved(@NonNull WebEngine webEngine, @NonNull Tab tab) { - setNumberOfTabsText(tabManager.getAllTabs().size()); - } - - @Override - public void onWillDestroyFragmentAndAllTabs(@NonNull WebEngine webEngine) { - setNumberOfTabsText(tabManager.getAllTabs().size()); - } - }); - - Tab activeTab = tabManager.getActiveTab(); - activeTab.registerTabObserver(mDefaultObservers); - activeTab.getNavigationController().registerNavigationObserver(mDefaultObservers); - tabManager.registerTabListObserver(mDefaultObservers); - - activeTab.getNavigationController().navigate("https://www.google.com"); - } - - /** - * Tries to shutdown WebEngine and returns if succeeded. - */ - private boolean closeWebEngine() { - setEngineStateText(false); - setVisibilityText(false); - WebEngine webEngine = getCurrentWebEngine(); - - if (webEngine != null) { - webEngine.close(); - return true; - } - return false; - } - - /** - * Tries to shutdown the Sandbox and returns if succeeded. - */ - private boolean shutdownSandbox() { - if (mWebSandbox == null) return false; - - mWebSandbox.shutdown(); - setEngineStateText(false); - setSandboxStateText(false); - setVisibilityText(false); - return true; - } - - private void openNewTabAndNavigate(String url) { - WebEngine webEngine = getCurrentWebEngine(); - if (webEngine == null) { - Log.w(TAG, "No WebEngine created"); - return; - } - ListenableFuture<Tab> newTabFuture = webEngine.getTabManager().createTab(); - Futures.addCallback(newTabFuture, new FutureCallback<Tab>() { - @Override - public void onSuccess(Tab newTab) { - newTab.setActive(); - newTab.getNavigationController().navigate(url); - Log.i(TAG, "Tab opened"); - } - @Override - public void onFailure(Throwable thrown) { - Log.i(TAG, "Opening Tab failed"); - } - }, ContextCompat.getMainExecutor(mContext)); - } - - private boolean closeTab() { - WebEngine webEngine = getCurrentWebEngine(); - if (webEngine == null) return false; - - Tab activeTab = webEngine.getTabManager().getActiveTab(); - - if (activeTab == null) return false; - activeTab.close(); - - Set<Tab> allTabs = webEngine.getTabManager().getAllTabs(); - allTabs.remove(activeTab); - if (allTabs.size() > 0) { - allTabs.iterator().next().setActive(); - } - - return true; - } - - // There could be more but we only have one in this test activity. - private WebEngine getCurrentWebEngine() { - if (mWebSandbox == null) return null; - - WebEngine webEngine = mWebSandbox.getWebEngine(WEB_ENGINE_TAG); - if (webEngine != null) { - assert mWebSandbox.getWebEngines().size() == 1; - return webEngine; - } - return null; - } - - /** - * Tries to inflate the fragment and returns if succeeded. - */ - private boolean inflateFragment() { - WebEngine webEngine = getCurrentWebEngine(); - if (webEngine == null) { - Log.w(TAG, "no WebEngine created"); - return false; - } - - FragmentManager fragmentManager = getSupportFragmentManager(); - List<Fragment> fragments = fragmentManager.getFragments(); - if (fragments.size() > 1) { - throw new IllegalStateException("More than one fragment added, shouldn't happen"); - } - if (fragments.size() == 1) { - // Fragment already inflated. - return false; - } - setVisibilityText(true); - getSupportFragmentManager() - .beginTransaction() - .setReorderingAllowed(true) - .add(R.id.fragment_container_view, webEngine.getFragment()) - .commit(); - return true; - } - - /** - * Tries to remove the WebFragment and returns if succeeded. - */ - private boolean removeFragment() { - FragmentManager fragmentManager = getSupportFragmentManager(); - List<Fragment> fragments = fragmentManager.getFragments(); - if (fragments.size() > 1) { - throw new IllegalStateException("More than one fragment added, shouldn't happen"); - } - if (fragments.size() == 0) return false; // Fragment not inflated. - - setVisibilityText(false); - getSupportFragmentManager() - .beginTransaction() - .setReorderingAllowed(true) - .remove(fragments.get(0)) - .commit(); - return true; - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/CustomSpinner.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/CustomSpinner.java deleted file mode 100644 index 8ac5975..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/CustomSpinner.java +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell.topbar; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.Spinner; - -/** - * A Spinner wrapper monitoring whether the dialog is open or closed. - */ -public class CustomSpinner extends Spinner { - private boolean mIsOpen; - - public CustomSpinner(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - public boolean performClick() { - mIsOpen = true; - return super.performClick(); - } - - @Override - public void onWindowFocusChanged(boolean hasFocus) { - if (isOpen() && hasFocus) { - performClose(); - } - } - - private void performClose() { - mIsOpen = false; - } - - public boolean isOpen() { - return mIsOpen; - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java deleted file mode 100644 index 9263e5b53..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsDelegate.java +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell.topbar; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.webengine.Navigation; -import org.chromium.webengine.NavigationObserver; -import org.chromium.webengine.Tab; -import org.chromium.webengine.TabListObserver; -import org.chromium.webengine.TabManager; -import org.chromium.webengine.TabObserver; -import org.chromium.webengine.WebEngine; - -/** - * Delegate for Tab Events. - */ -public class TabEventsDelegate implements TabObserver, NavigationObserver, TabListObserver { - private TabEventsObserver mTabEventsObserver; - private final TabManager mTabManager; - - public TabEventsDelegate(TabManager tabManager) { - mTabManager = tabManager; - mTabManager.registerTabListObserver(this); - for (Tab t : mTabManager.getAllTabs()) { - t.getNavigationController().registerNavigationObserver(this); - t.registerTabObserver(this); - } - } - - public void registerObserver(TabEventsObserver tabEventsObserver) { - mTabEventsObserver = tabEventsObserver; - } - - public void unregisterObserver() { - mTabEventsObserver = null; - } - - // TabObserver implementation. - - @Override - public void onVisibleUriChanged(@NonNull Tab tab, @NonNull String uri) { - if (mTabEventsObserver == null) { - return; - } - if (!isTabActive(tab)) { - return; - } - mTabEventsObserver.onVisibleUriChanged(uri); - } - - @Override - public void onTitleUpdated(Tab tab, @NonNull String title) {} - - @Override - public void onRenderProcessGone(Tab tab) {} - - // TabListObserver implementation. - - @Override - public void onActiveTabChanged(@NonNull WebEngine webEngine, @Nullable Tab activeTab) { - if (mTabEventsObserver == null) { - return; - } - if (activeTab == null) { - return; - } - mTabEventsObserver.onActiveTabChanged(activeTab); - } - - @Override - public void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) { - if (mTabEventsObserver == null) { - return; - } - mTabEventsObserver.onTabAdded(tab); - - tab.registerTabObserver(this); - tab.getNavigationController().registerNavigationObserver(this); - } - - @Override - public void onTabRemoved(@NonNull WebEngine webEngine, @NonNull Tab tab) { - if (mTabEventsObserver == null) { - return; - } - mTabEventsObserver.onTabRemoved(tab); - } - - @Override - public void onWillDestroyFragmentAndAllTabs(@NonNull WebEngine webEngine) {} - - // NavigationObserver implementation. - - @Override - public void onNavigationFailed(@NonNull Tab tab, @NonNull Navigation navigation) {} - @Override - public void onNavigationCompleted(@NonNull Tab tab, @NonNull Navigation navigation) {} - - @Override - public void onNavigationStarted(@NonNull Tab tab, @NonNull Navigation navigation) {} - - @Override - public void onNavigationRedirected(@NonNull Tab tab, @NonNull Navigation navigation) {} - - @Override - public void onLoadProgressChanged(@NonNull Tab tab, double progress) { - if (mTabEventsObserver == null) { - return; - } - if (!isTabActive(tab)) { - return; - } - mTabEventsObserver.onLoadProgressChanged(progress); - } - - boolean isTabActive(Tab tab) { - return mTabManager.getActiveTab() != null && mTabManager.getActiveTab().equals(tab); - } -}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java deleted file mode 100644 index 860aaa2..0000000 --- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.webengine.shell.topbar; - -import org.chromium.webengine.Tab; - -/** - * An interface for setting values in the Top Bar. - */ -public interface TabEventsObserver { - void onVisibleUriChanged(String uri); - - void onActiveTabChanged(Tab activeTab); - - void onTabAdded(Tab tab); - - void onTabRemoved(Tab tab); - - void onLoadProgressChanged(double progress); -}
diff --git a/weblayer/shell/app/resource.h b/weblayer/shell/app/resource.h deleted file mode 100644 index e53cd2d..0000000 --- a/weblayer/shell/app/resource.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_SHELL_APP_RESOURCE_H_ -#define WEBLAYER_SHELL_APP_RESOURCE_H_ - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by shell.rc -// - -#define IDR_MAINFRAME 128 -#define IDM_EXIT 105 -#define IDM_CLOSE_WINDOW 106 -#define IDM_NEW_WINDOW 107 -#define IDC_WEBLAYERSHELL 109 -#define IDD_ALERT 130 -#define IDD_CONFIRM 131 -#define IDD_PROMPT 132 -#define IDC_NAV_BACK 1001 -#define IDC_NAV_FORWARD 1002 -#define IDC_NAV_RELOAD 1003 -#define IDC_NAV_STOP 1004 -#define IDC_PROMPTEDIT 1005 -#define IDC_DIALOGTEXT 1006 - -#ifndef IDC_STATIC -#define IDC_STATIC -1 -#endif -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS - -#define _APS_NO_MFC 130 -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 117 -#endif -#endif - -#endif // WEBLAYER_SHELL_APP_RESOURCE_H_ \ No newline at end of file
diff --git a/weblayer/shell/app/shell.rc b/weblayer/shell/app/shell.rc deleted file mode 100644 index 72fd74d6..0000000 --- a/weblayer/shell/app/shell.rc +++ /dev/null
@@ -1,126 +0,0 @@ -//Microsoft Visual C++ generated resource script. -// -#include "weblayer/shell/app/resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE 9, 1 -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ALERT DIALOGEX 0, 0, 241, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Alert" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,184,55,50,14 - LTEXT "",IDC_DIALOGTEXT,16,17,210,30 -END - -IDD_CONFIRM DIALOGEX 0, 0, 241, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Confirm" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Cancel",IDCANCEL,184,55,50,14 - DEFPUSHBUTTON "OK",IDOK,131,55,50,14 - LTEXT "",IDC_DIALOGTEXT,16,17,210,30 -END - -IDD_PROMPT DIALOGEX 0, 0, 241, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Prompt" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,131,55,50,14 - LTEXT "",IDC_DIALOGTEXT,16,17,210,18 - PUSHBUTTON "Cancel",IDCANCEL,184,55,50,14 - EDITTEXT IDC_PROMPTEDIT,15,33,210,14,ES_AUTOHSCROLL -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_ALERT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 234 - TOPMARGIN, 7 - BOTTOMMARGIN, 69 - END - - IDD_CONFIRM, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 234 - TOPMARGIN, 7 - BOTTOMMARGIN, 69 - END - - IDD_PROMPT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 234 - TOPMARGIN, 7 - BOTTOMMARGIN, 69 - END -END -#endif // APSTUDIO_INVOKED - -#endif -///////////////////////////////////////////////////////////////////////////// - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED
diff --git a/weblayer/shell/app/shell_main.cc b/weblayer/shell/app/shell_main.cc deleted file mode 100644 index 83f23759..0000000 --- a/weblayer/shell/app/shell_main.cc +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "build/build_config.h" -#include "weblayer/public/main.h" -#include "weblayer/shell/app/shell_main_params.h" - -#if BUILDFLAG(IS_WIN) - -#if defined(WIN_CONSOLE_APP) -int main() { - return weblayer::Main(weblayer::CreateMainParams()); -#else -int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) { - return weblayer::Main(weblayer::CreateMainParams(), instance); -#endif -} - -#else - -int main(int argc, const char** argv) { - return weblayer::Main(weblayer::CreateMainParams(), argc, argv); -} - -#endif // BUILDFLAG(IS_WIN)
diff --git a/weblayer/shell/app/shell_main_params.cc b/weblayer/shell/app/shell_main_params.cc deleted file mode 100644 index 559d65a..0000000 --- a/weblayer/shell/app/shell_main_params.cc +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/shell/app/shell_main_params.h" - -#include "base/command_line.h" -#include "base/environment.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/functional/callback.h" -#include "base/path_service.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "net/base/filename_util.h" -#include "url/gurl.h" -#include "weblayer/public/main.h" -#include "weblayer/public/profile.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/shell/common/shell_switches.h" - -namespace weblayer { - -namespace { - -GURL GetStartupURL() { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kNoInitialNavigation)) - return GURL(); - -#if BUILDFLAG(IS_ANDROID) - // Delay renderer creation on Android until surface is ready. - return GURL(); -#else - const base::CommandLine::StringVector& args = command_line->GetArgs(); - - if (args.empty()) - return GURL("https://www.google.com/"); - -#if BUILDFLAG(IS_WIN) - GURL url(base::WideToUTF16(args[0])); -#else - GURL url(args[0]); -#endif - if (url.is_valid() && url.has_scheme()) - return url; - - return net::FilePathToFileURL( - base::MakeAbsoluteFilePath(base::FilePath(args[0]))); -#endif -} - -class MainDelegateImpl : public MainDelegate { - public: - void PreMainMessageLoopRun() override { - // On Android the Profile is created and owned in Java via an - // embedder-specific call to WebLayer.createBrowserFragment(). -#if !BUILDFLAG(IS_ANDROID) - InitializeProfile(); -#endif - - Shell::Initialize(); - -#if BUILDFLAG(IS_ANDROID) - Shell::CreateNewWindow(GetStartupURL(), gfx::Size()); -#else - Shell::CreateNewWindow(profile_.get(), GetStartupURL(), gfx::Size()); -#endif - } - - void PostMainMessageLoopRun() override { -#if !BUILDFLAG(IS_ANDROID) - DestroyProfile(); -#endif - } - - void SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) override { - Shell::SetMainMessageLoopQuitClosure(std::move(quit_closure)); - } - - private: -#if !BUILDFLAG(IS_ANDROID) - void InitializeProfile() { - auto* command_line = base::CommandLine::ForCurrentProcess(); - const bool is_incognito = - command_line->HasSwitch(switches::kStartInIncognito); - std::string profile_name = is_incognito ? "" : "web_shell"; - - profile_ = Profile::Create(profile_name, is_incognito); - } - - void DestroyProfile() { profile_.reset(); } - - std::unique_ptr<Profile> profile_; -#endif -}; - -} // namespace - -MainParams CreateMainParams() { - static MainDelegateImpl weblayer_delegate; - MainParams params; - params.delegate = &weblayer_delegate; - - base::PathService::Get(base::DIR_EXE, ¶ms.log_filename); - params.log_filename = params.log_filename.AppendASCII("weblayer_shell.log"); - - params.pak_name = "weblayer.pak"; - - return params; -} - -} // namespace weblayer
diff --git a/weblayer/shell/app/shell_main_params.h b/weblayer/shell/app/shell_main_params.h deleted file mode 100644 index c19f8c7..0000000 --- a/weblayer/shell/app/shell_main_params.h +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_SHELL_APP_SHELL_MAIN_PARAMS_H_ -#define WEBLAYER_SHELL_APP_SHELL_MAIN_PARAMS_H_ - -namespace weblayer { -struct MainParams; - -MainParams CreateMainParams(); - -} // namespace weblayer - -#endif // WEBLAYER_SHELL_APP_SHELL_MAIN_PARAMS_H_
diff --git a/weblayer/shell/browser/shell.cc b/weblayer/shell/browser/shell.cc deleted file mode 100644 index e82f349..0000000 --- a/weblayer/shell/browser/shell.cc +++ /dev/null
@@ -1,228 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/shell/browser/shell.h" - -#include <stddef.h> - -#include <string> -#include <utility> - -#include "base/command_line.h" -#include "base/no_destructor.h" -#include "base/run_loop.h" -#include "base/strings/string_util.h" -#include "build/build_config.h" -#include "url/gurl.h" -#include "weblayer/browser/browser_impl.h" -#include "weblayer/browser/browser_list.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/prerender_controller.h" - -namespace weblayer { - -// Null until/unless the default main message loop is running. -base::NoDestructor<base::OnceClosure> g_quit_main_message_loop; - -const int kDefaultTestWindowWidthDip = 1000; -const int kDefaultTestWindowHeightDip = 700; - -std::vector<Shell*> Shell::windows_; - -Shell::Shell(std::unique_ptr<Browser> browser) - : browser_(std::move(browser)), window_(nullptr) { - windows_.push_back(this); - if (tab()) { - tab()->AddObserver(this); - tab()->GetNavigationController()->AddObserver(this); -#if !BUILDFLAG(IS_ANDROID) // Android does this in Java. - static_cast<TabImpl*>(tab())->profile()->SetDownloadDelegate(this); -#endif - } -} - -Shell::~Shell() { - if (tab()) { - tab()->GetNavigationController()->RemoveObserver(this); - tab()->RemoveObserver(this); -#if !BUILDFLAG(IS_ANDROID) // Android does this in Java. - static_cast<TabImpl*>(tab())->profile()->SetDownloadDelegate(nullptr); -#endif - } - PlatformCleanUp(); - - for (size_t i = 0; i < windows_.size(); ++i) { - if (windows_[i] == this) { - windows_.erase(windows_.begin() + i); - break; - } - } - - // Always destroy WebContents before calling PlatformExit(). WebContents - // destruction sequence may depend on the resources destroyed in - // PlatformExit() (e.g. the display::Screen singleton). - if (tab()) { - auto* const profile = static_cast<TabImpl*>(tab())->profile(); - profile->GetPrerenderController()->DestroyAllContents(); - } - browser_.reset(); - - if (windows_.empty()) { - PlatformExit(); - - if (*g_quit_main_message_loop) - std::move(*g_quit_main_message_loop).Run(); - } -} - -Shell* Shell::CreateShell(std::unique_ptr<Browser> browser, - const gfx::Size& initial_size) { - Shell* shell = new Shell(std::move(browser)); - shell->PlatformCreateWindow(initial_size.width(), initial_size.height()); - - shell->PlatformSetContents(); - - shell->PlatformResizeSubViews(); - - return shell; -} - -void Shell::CloseAllWindows() { - std::vector<Shell*> open_windows(windows_); - for (size_t i = 0; i < open_windows.size(); ++i) - open_windows[i]->Close(); - - // Pump the message loop to allow window teardown tasks to run. - base::RunLoop().RunUntilIdle(); -} - -void Shell::SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) { - *g_quit_main_message_loop = std::move(quit_closure); -} - -Tab* Shell::tab() { - if (!browser()) - return nullptr; - if (browser()->GetTabs().empty()) - return nullptr; - return browser()->GetTabs()[0]; -} - -Browser* Shell::browser() { -#if BUILDFLAG(IS_ANDROID) - // TODO(jam): this won't work if we need more than one Shell in a test. - const auto& browsers = BrowserList::GetInstance()->browsers(); - if (browsers.empty()) - return nullptr; - return *(browsers.begin()); -#else - return browser_.get(); -#endif -} - -void Shell::Initialize() { - PlatformInitialize(GetShellDefaultSize()); -} - -void Shell::DisplayedUrlChanged(const GURL& url) { - PlatformSetAddressBarURL(url); -} - -void Shell::LoadStateChanged(bool is_loading, bool should_show_loading_ui) { - NavigationController* navigation_controller = - tab()->GetNavigationController(); - - PlatformEnableUIControl(STOP_BUTTON, is_loading && should_show_loading_ui); - - // TODO(estade): These should be updated in callbacks that correspond to the - // back/forward list changing, such as NavigationEntriesDeleted. - PlatformEnableUIControl(BACK_BUTTON, navigation_controller->CanGoBack()); - PlatformEnableUIControl(FORWARD_BUTTON, - navigation_controller->CanGoForward()); -} - -void Shell::LoadProgressChanged(double progress) { - PlatformSetLoadProgress(progress); -} - -bool Shell::InterceptDownload(const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - int64_t content_length) { - return false; -} - -void Shell::AllowDownload(Tab* tab, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - AllowDownloadCallback callback) { - std::move(callback).Run(true); -} - -gfx::Size Shell::AdjustWindowSize(const gfx::Size& initial_size) { - if (!initial_size.IsEmpty()) - return initial_size; - return GetShellDefaultSize(); -} - -#if BUILDFLAG(IS_ANDROID) -Shell* Shell::CreateNewWindow(const GURL& url, const gfx::Size& initial_size) { - // On Android, the browser is owned by the Java side. - return CreateNewWindowWithBrowser(nullptr, url, initial_size); -} -#else -Shell* Shell::CreateNewWindow(Profile* web_profile, - const GURL& url, - const gfx::Size& initial_size) { - auto browser = Browser::Create(web_profile, nullptr); - browser->CreateTab(); - return CreateNewWindowWithBrowser(std::move(browser), url, initial_size); -} -#endif - -Shell* Shell::CreateNewWindowWithBrowser(std::unique_ptr<Browser> browser, - const GURL& url, - const gfx::Size& initial_size) { - Shell* shell = - CreateShell(std::move(browser), AdjustWindowSize(initial_size)); - if (!url.is_empty()) - shell->LoadURL(url); - return shell; -} - -void Shell::LoadURL(const GURL& url) { - tab()->GetNavigationController()->Navigate(url); -} - -void Shell::GoBackOrForward(int offset) { - if (offset == -1) - tab()->GetNavigationController()->GoBack(); - else if (offset == 1) - tab()->GetNavigationController()->GoForward(); -} - -void Shell::Reload() { - tab()->GetNavigationController()->Reload(); -} - -void Shell::ReloadBypassingCache() {} - -void Shell::Stop() { - tab()->GetNavigationController()->Stop(); -} - -gfx::Size Shell::GetShellDefaultSize() { - static gfx::Size default_shell_size; - if (!default_shell_size.IsEmpty()) - return default_shell_size; - default_shell_size = - gfx::Size(kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip); - return default_shell_size; -} - -} // namespace weblayer
diff --git a/weblayer/shell/browser/shell.h b/weblayer/shell/browser/shell.h deleted file mode 100644 index 96bb2fe..0000000 --- a/weblayer/shell/browser/shell.h +++ /dev/null
@@ -1,184 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_SHELL_BROWSER_SHELL_H_ -#define WEBLAYER_SHELL_BROWSER_SHELL_H_ - -#include <stdint.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/functional/callback_forward.h" -#include "base/memory/raw_ptr.h" -#include "build/build_config.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/native_widget_types.h" -#include "weblayer/public/download_delegate.h" -#include "weblayer/public/navigation_observer.h" -#include "weblayer/public/tab_observer.h" - -#if BUILDFLAG(IS_ANDROID) -#include "base/android/scoped_java_ref.h" -#elif defined(USE_AURA) -namespace views { -class Widget; -class ViewsDelegate; -} // namespace views -#if !BUILDFLAG(IS_CHROMEOS) -namespace display { -class Screen; -} -namespace wm { -class WMState; -} -#endif -#endif // defined(USE_AURA) - -class GURL; - -namespace weblayer { -class Browser; -class Profile; -class Tab; - -// This represents one window of the Web Shell, i.e. all the UI including -// buttons and url bar, as well as the web content area. -class Shell : public TabObserver, - public NavigationObserver, - public DownloadDelegate { - public: - ~Shell() override; - - void LoadURL(const GURL& url); - void GoBackOrForward(int offset); - void Reload(); - void ReloadBypassingCache(); - void Stop(); - void Close(); - - // Do one time initialization at application startup. - static void Initialize(); - -#if BUILDFLAG(IS_ANDROID) - static Shell* CreateNewWindow(const GURL& url, const gfx::Size& initial_size); -#else - static Shell* CreateNewWindow(Profile* web_profile, - const GURL& url, - const gfx::Size& initial_size); -#endif - - // Returns the currently open windows. - static std::vector<Shell*>& windows() { return windows_; } - - // Closes all windows, pumps teardown tasks, then returns. The main message - // loop will be signalled to quit, before the call returns. - static void CloseAllWindows(); - - // Stores the supplied |quit_closure|, to be run when the last Shell - // instance is destroyed. - static void SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure); - - Tab* tab(); - Browser* browser(); - - gfx::NativeWindow window() { return window_; } - - static gfx::Size GetShellDefaultSize(); - - private: - enum UIControl { BACK_BUTTON, FORWARD_BUTTON, STOP_BUTTON }; - - static Shell* CreateNewWindowWithBrowser(std::unique_ptr<Browser> browser, - const GURL& url, - const gfx::Size& initial_size); - - explicit Shell(std::unique_ptr<Browser> browser); - - // TabObserver implementation: - void DisplayedUrlChanged(const GURL& url) override; - - // NavigationObserver implementation: - void LoadStateChanged(bool is_loading, bool should_show_loading_ui) override; - void LoadProgressChanged(double progress) override; - - // DownloadDelegate implementation: - bool InterceptDownload(const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - int64_t content_length) override; - void AllowDownload(Tab* tab, - const GURL& url, - const std::string& request_method, - absl::optional<url::Origin> request_initiator, - AllowDownloadCallback callback) override; - - // Helper to create a new Shell. - static Shell* CreateShell(std::unique_ptr<Browser> browser, - const gfx::Size& initial_size); - - // Helper for one time initialization of application - static void PlatformInitialize(const gfx::Size& default_window_size); - - // Helper for one time deinitialization of platform specific state. - static void PlatformExit(); - - // Adjust the size when Blink sends 0 for width and/or height. - // This happens when Blink requests a default-sized window. - static gfx::Size AdjustWindowSize(const gfx::Size& initial_size); - - // All the methods that begin with Platform need to be implemented by the - // platform specific Shell implementation. - // Called from the destructor to let each platform do any necessary cleanup. - void PlatformCleanUp(); - - // Creates the main window GUI. - void PlatformCreateWindow(int width, int height); - - // Links the WebContents into the newly created window. - void PlatformSetContents(); - - // Resize the content area and GUI. - void PlatformResizeSubViews(); - - // Enable/disable a button. - void PlatformEnableUIControl(UIControl control, bool is_enabled); - - // Updates the url in the url bar. - void PlatformSetAddressBarURL(const GURL& url); - - // Sets the load progress indicator in the UI. - void PlatformSetLoadProgress(double progress); - - // Set the title of shell window - void PlatformSetTitle(const std::u16string& title); - - std::unique_ptr<Browser> browser_; - - gfx::NativeWindow window_; - - gfx::Size content_size_; - -#if BUILDFLAG(IS_ANDROID) - base::android::ScopedJavaGlobalRef<jobject> java_object_; -#elif defined(USE_AURA) - static wm::WMState* wm_state_; - static display::Screen* screen_; -#if defined(TOOLKIT_VIEWS) - static views::ViewsDelegate* views_delegate_; - - raw_ptr<views::Widget> window_widget_; -#endif // defined(TOOLKIT_VIEWS) -#endif // defined(USE_AURA) - - // A container of all the open windows. We use a vector so we can keep track - // of ordering. - static std::vector<Shell*> windows_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_SHELL_BROWSER_SHELL_H_
diff --git a/weblayer/shell/browser/shell_android.cc b/weblayer/shell/browser/shell_android.cc deleted file mode 100644 index f1ab5b0..0000000 --- a/weblayer/shell/browser/shell_android.cc +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/shell/browser/shell.h" - -namespace weblayer { - -// Shell is only used on Android for weblayer_browsertests. So no need to -// implement these methods. -void Shell::PlatformInitialize(const gfx::Size& default_window_size) {} - -void Shell::PlatformExit() {} - -void Shell::PlatformCleanUp() {} - -void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {} - -void Shell::PlatformSetAddressBarURL(const GURL& url) {} - -void Shell::PlatformSetLoadProgress(double progress) {} - -void Shell::PlatformCreateWindow(int width, int height) {} - -void Shell::PlatformSetContents() {} - -void Shell::PlatformResizeSubViews() {} - -void Shell::Close() {} - -void Shell::PlatformSetTitle(const std::u16string& title) {} - -} // namespace weblayer
diff --git a/weblayer/shell/browser/shell_views.cc b/weblayer/shell/browser/shell_views.cc deleted file mode 100644 index 11ca5f5..0000000 --- a/weblayer/shell/browser/shell_views.cc +++ /dev/null
@@ -1,398 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> - -#include <memory> - -#include "base/command_line.h" -#include "base/functional/bind.h" -#include "base/memory/raw_ptr.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "ui/aura/env.h" -#include "ui/aura/window.h" -#include "ui/aura/window_event_dispatcher.h" -#include "ui/aura/window_tree_host.h" -#include "ui/base/clipboard/clipboard.h" -#include "ui/base/metadata/metadata_header_macros.h" -#include "ui/base/metadata/metadata_impl_macros.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/color/color_id.h" -#include "ui/events/event.h" -#include "ui/views/background.h" -#include "ui/views/controls/button/md_text_button.h" -#include "ui/views/controls/textfield/textfield.h" -#include "ui/views/controls/textfield/textfield_controller.h" -#include "ui/views/controls/webview/webview.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/flex_layout_view.h" -#include "ui/views/test/desktop_test_views_delegate.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_delegate.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" - -#if defined(USE_AURA) && !BUILDFLAG(IS_CHROMEOS) -#include "ui/display/screen.h" -#include "ui/views/widget/desktop_aura/desktop_screen.h" -#include "ui/wm/core/wm_state.h" -#endif - -#if BUILDFLAG(IS_WIN) -#include <fcntl.h> -#include <io.h> -#endif - -namespace weblayer { - -namespace { - -// Maintain the UI controls and web view for web shell -class ShellWindowDelegateView : public views::WidgetDelegateView, - public views::TextfieldController { - public: - METADATA_HEADER(ShellWindowDelegateView); - - enum UIControl { BACK_BUTTON, FORWARD_BUTTON, STOP_BUTTON }; - - explicit ShellWindowDelegateView(Shell* shell) : shell_(shell) { - SetHasWindowSizeControls(true); - InitShellWindow(); - } - - ShellWindowDelegateView(const ShellWindowDelegateView&) = delete; - ShellWindowDelegateView& operator=(const ShellWindowDelegateView&) = delete; - - ~ShellWindowDelegateView() override = default; - - // Update the state of UI controls - void SetAddressBarURL(const GURL& url) { - url_entry_->SetText(base::ASCIIToUTF16(url.spec())); - } - - void AttachTab(Tab* tab, const gfx::Size& size) { - contents_view_->SetUseDefaultFillLayout(true); - // If there was a previous WebView in this Shell it should be removed and - // deleted. - if (web_view_) - contents_view_->RemoveChildViewT(web_view_.get()); - - views::Builder<views::View>(contents_view_.get()) - .AddChild(views::Builder<views::WebView>() - .CopyAddressTo(&web_view_) - .SetPreferredSize(size)) - .BuildChildren(); - tab->AttachToView(web_view_); - web_view_->SizeToPreferredSize(); - - // Resize the widget, keeping the same origin. - gfx::Rect bounds = GetWidget()->GetWindowBoundsInScreen(); - bounds.set_size(GetWidget()->GetRootView()->GetPreferredSize()); - GetWidget()->SetBounds(bounds); - } - - void SetWindowTitle(const std::u16string& title) { title_ = title; } - - void EnableUIControl(UIControl control, bool is_enabled) { - if (control == BACK_BUTTON) { - back_button_->SetState(is_enabled ? views::Button::STATE_NORMAL - : views::Button::STATE_DISABLED); - } else if (control == FORWARD_BUTTON) { - forward_button_->SetState(is_enabled ? views::Button::STATE_NORMAL - : views::Button::STATE_DISABLED); - } else if (control == STOP_BUTTON) { - stop_button_->SetState(is_enabled ? views::Button::STATE_NORMAL - : views::Button::STATE_DISABLED); - if (!is_enabled) - UpdateLoadProgress(); - } - } - - void UpdateLoadProgress(double progress = 0.) { - std::string stop_text("Stop"); - if (stop_button_->GetState() == views::Button::STATE_NORMAL) - stop_text = base::StringPrintf("Stop (%.0f%%)", progress * 100); - stop_button_->SetText(base::ASCIIToUTF16(stop_text)); - } - - private: - // Initialize the UI control contained in shell window - void InitShellWindow() { - auto toolbar_button_rule = [](const views::View* view, - const views::SizeBounds& size_bounds) { - gfx::Size preferred_size = view->GetPreferredSize(); - if (size_bounds != views::SizeBounds() && - size_bounds.width().is_bounded()) { - preferred_size.set_width(std::max( - std::min(size_bounds.width().value(), preferred_size.width()), - preferred_size.width() / 2)); - } - return preferred_size; - }; - - auto* box_layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical)); - - views::Builder<views::WidgetDelegateView>(this) - .SetBackground( - views::CreateThemedSolidBackground(ui::kColorWindowBackground)) - .AddChildren( - views::Builder<views::FlexLayoutView>() - .CopyAddressTo(&toolbar_view_) - .SetOrientation(views::LayoutOrientation::kHorizontal) - // Top/Left/Right padding = 2, Bottom padding = 5 - .SetProperty(views::kMarginsKey, gfx::Insets::TLBR(2, 2, 5, 2)) - .AddChildren( - views::Builder<views::MdTextButton>() - .CopyAddressTo(&back_button_) - .SetText(u"Back") - .SetCallback(base::BindRepeating( - &Shell::GoBackOrForward, - base::Unretained(shell_.get()), -1)) - .SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification( - base::BindRepeating(toolbar_button_rule))), - views::Builder<views::MdTextButton>() - .CopyAddressTo(&forward_button_) - .SetText(u"Forward") - .SetCallback(base::BindRepeating( - &Shell::GoBackOrForward, - base::Unretained(shell_.get()), 1)) - .SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification( - base::BindRepeating(toolbar_button_rule))), - views::Builder<views::MdTextButton>() - .CopyAddressTo(&refresh_button_) - .SetText(u"Refresh") - .SetCallback(base::BindRepeating( - &Shell::Reload, base::Unretained(shell_.get()))) - .SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification( - base::BindRepeating(toolbar_button_rule))), - views::Builder<views::MdTextButton>() - .CopyAddressTo(&stop_button_) - .SetText(u"Stop (100%)") - .SetCallback(base::BindRepeating( - &Shell::Stop, base::Unretained(shell_.get()))) - .SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification( - base::BindRepeating(toolbar_button_rule))), - views::Builder<views::Textfield>() - .CopyAddressTo(&url_entry_) - .SetAccessibleName(u"Enter URL") - .SetController(this) - .SetTextInputType( - ui::TextInputType::TEXT_INPUT_TYPE_URL) - .SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification( - views::MinimumFlexSizeRule::kScaleToMinimum, - views::MaximumFlexSizeRule::kUnbounded)) - // Left padding = 2, Right padding = 2 - .SetProperty(views::kMarginsKey, - gfx::Insets::TLBR(0, 2, 0, 2))), - views::Builder<views::View>() - .CopyAddressTo(&contents_view_) - .SetUseDefaultFillLayout(true) - .SetProperty(views::kMarginsKey, gfx::Insets::TLBR(0, 2, 0, 2)), - views::Builder<views::View>().SetProperty( - views::kMarginsKey, gfx::Insets::TLBR(0, 0, 5, 0))) - .BuildChildren(); - box_layout->SetFlexForView(contents_view_, 1); - } - - void InitAccelerators() { - // This function must be called when part of the widget hierarchy. - DCHECK(GetWidget()); - static const ui::KeyboardCode keys[] = {ui::VKEY_F5, ui::VKEY_BROWSER_BACK, - ui::VKEY_BROWSER_FORWARD}; - for (size_t i = 0; i < std::size(keys); ++i) { - GetFocusManager()->RegisterAccelerator( - ui::Accelerator(keys[i], ui::EF_NONE), - ui::AcceleratorManager::kNormalPriority, this); - } - } - - // Overridden from TextfieldController - void ContentsChanged(views::Textfield* sender, - const std::u16string& new_contents) override {} - - bool HandleKeyEvent(views::Textfield* sender, - const ui::KeyEvent& key_event) override { - if (key_event.type() == ui::ET_KEY_PRESSED && sender == url_entry_ && - key_event.key_code() == ui::VKEY_RETURN) { - std::string text = base::UTF16ToUTF8(url_entry_->GetText()); - GURL url(text); - if (!url.has_scheme()) { - url = GURL(std::string("http://") + std::string(text)); - url_entry_->SetText(base::ASCIIToUTF16(url.spec())); - } - shell_->LoadURL(url); - return true; - } - return false; - } - - // Overridden from WidgetDelegateView - std::u16string GetWindowTitle() const override { return title_; } - - // Overridden from View - gfx::Size GetMinimumSize() const override { - // We want to be able to make the window smaller than its initial - // (preferred) size. - return gfx::Size(); - } - void AddedToWidget() override { InitAccelerators(); } - - // Overridden from AcceleratorTarget: - bool AcceleratorPressed(const ui::Accelerator& accelerator) override { - switch (accelerator.key_code()) { - case ui::VKEY_F5: - shell_->Reload(); - return true; - case ui::VKEY_BROWSER_BACK: - shell_->GoBackOrForward(-1); - return true; - case ui::VKEY_BROWSER_FORWARD: - shell_->GoBackOrForward(1); - return true; - default: - return views::WidgetDelegateView::AcceleratorPressed(accelerator); - } - } - - private: - std::unique_ptr<Shell> shell_; - - // Window title - std::u16string title_; - - // Toolbar view contains forward/backward/reload button and URL entry - raw_ptr<views::View> toolbar_view_ = nullptr; - raw_ptr<views::Button> back_button_ = nullptr; - raw_ptr<views::Button> forward_button_ = nullptr; - raw_ptr<views::Button> refresh_button_ = nullptr; - raw_ptr<views::MdTextButton> stop_button_ = nullptr; - raw_ptr<views::Textfield> url_entry_ = nullptr; - - // Contents view contains the WebBrowser view - raw_ptr<views::View> contents_view_ = nullptr; - raw_ptr<views::WebView> web_view_ = nullptr; -}; - -BEGIN_METADATA(ShellWindowDelegateView, views::WidgetDelegateView) -END_METADATA - -} // namespace - -#if defined(USE_AURA) && !BUILDFLAG(IS_CHROMEOS) -// static -wm::WMState* Shell::wm_state_ = nullptr; -display::Screen* Shell::screen_ = nullptr; -#endif -// static -views::ViewsDelegate* Shell::views_delegate_ = nullptr; - -// static -void Shell::PlatformInitialize(const gfx::Size& default_window_size) { -#if BUILDFLAG(IS_WIN) - _setmode(_fileno(stdout), _O_BINARY); - _setmode(_fileno(stderr), _O_BINARY); -#endif -#if defined(USE_AURA) && !BUILDFLAG(IS_CHROMEOS) - wm_state_ = new wm::WMState; - CHECK(!display::Screen::GetScreen()); - screen_ = views::CreateDesktopScreen().release(); -#endif - views_delegate_ = new views::DesktopTestViewsDelegate(); -} - -void Shell::PlatformExit() { - delete views_delegate_; - views_delegate_ = nullptr; - // delete platform_; - // platform_ = nullptr; -#if defined(USE_AURA) - delete screen_; - screen_ = nullptr; - delete wm_state_; - wm_state_ = nullptr; -#endif -} - -void Shell::PlatformCleanUp() {} - -void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { - ShellWindowDelegateView* delegate_view = - static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); - if (control == BACK_BUTTON) { - delegate_view->EnableUIControl(ShellWindowDelegateView::BACK_BUTTON, - is_enabled); - } else if (control == FORWARD_BUTTON) { - delegate_view->EnableUIControl(ShellWindowDelegateView::FORWARD_BUTTON, - is_enabled); - } else if (control == STOP_BUTTON) { - delegate_view->EnableUIControl(ShellWindowDelegateView::STOP_BUTTON, - is_enabled); - } -} - -void Shell::PlatformSetAddressBarURL(const GURL& url) { - ShellWindowDelegateView* delegate_view = - static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); - delegate_view->SetAddressBarURL(url); -} - -void Shell::PlatformSetLoadProgress(double progress) { - ShellWindowDelegateView* delegate_view = - static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); - delegate_view->UpdateLoadProgress(progress); -} - -void Shell::PlatformCreateWindow(int width, int height) { - window_widget_ = new views::Widget; - views::Widget::InitParams params; - params.bounds = gfx::Rect(0, 0, width, height); - params.delegate = new ShellWindowDelegateView(this); - params.wm_class_class = "chromium-web_shell"; - params.wm_class_name = params.wm_class_class; - window_widget_->Init(std::move(params)); - - content_size_ = gfx::Size(width, height); - - // |window_widget_| is made visible in PlatformSetContents(), so that the - // platform-window size does not need to change due to layout again. - window_ = window_widget_->GetNativeWindow(); -} - -void Shell::PlatformSetContents() { - views::WidgetDelegate* widget_delegate = window_widget_->widget_delegate(); - ShellWindowDelegateView* delegate_view = - static_cast<ShellWindowDelegateView*>(widget_delegate); - delegate_view->AttachTab(tab(), content_size_); - window_->GetHost()->Show(); - window_widget_->Show(); -} - -void Shell::PlatformResizeSubViews() {} - -void Shell::Close() { - window_widget_->CloseNow(); -} - -void Shell::PlatformSetTitle(const std::u16string& title) { - ShellWindowDelegateView* delegate_view = - static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); - delegate_view->SetWindowTitle(title); - window_widget_->UpdateWindowTitle(); -} - -} // namespace weblayer
diff --git a/weblayer/shell/common/shell_switches.cc b/weblayer/shell/common/shell_switches.cc deleted file mode 100644 index 874d079..0000000 --- a/weblayer/shell/common/shell_switches.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/shell/common/shell_switches.h" - -namespace weblayer { -namespace switches { - -// Stops new Shell objects from navigating to a default url. -const char kNoInitialNavigation[] = "no-initial-navigation"; - -// Starts the shell with the profile in incognito mode. -const char kStartInIncognito[] = "start-in-incognito"; - -} // namespace switches -} // namespace weblayer
diff --git a/weblayer/shell/common/shell_switches.h b/weblayer/shell/common/shell_switches.h deleted file mode 100644 index 15000c56..0000000 --- a/weblayer/shell/common/shell_switches.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_SHELL_COMMON_SHELL_SWITCHES_H_ -#define WEBLAYER_SHELL_COMMON_SHELL_SWITCHES_H_ - -namespace weblayer { -namespace switches { - -extern const char kNoInitialNavigation[]; - -extern const char kStartInIncognito[]; - -} // namespace switches -} // namespace weblayer - -#endif // WEBLAYER_SHELL_COMMON_SHELL_SWITCHES_H_
diff --git a/weblayer/shell/shell_resources.grd b/weblayer/shell/shell_resources.grd deleted file mode 100644 index c0de926..0000000 --- a/weblayer/shell/shell_resources.grd +++ /dev/null
@@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> - <outputs> - <output filename="grit/shell_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="webengine_shell_resources.pak" type="data_package" /> - </outputs> - <translations /> -</grit>
diff --git a/weblayer/test/BUILD.gn b/weblayer/test/BUILD.gn deleted file mode 100644 index 94a46ae..0000000 --- a/weblayer/test/BUILD.gn +++ /dev/null
@@ -1,328 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/features.gni") -import("//build/config/ui.gni") -import("//testing/test.gni") -import("//tools/grit/grit_rule.gni") -import("//weblayer/variables.gni") - -if (is_android) { - import("//build/config/android/rules.gni") - import("//components/safe_browsing/buildflags.gni") - import("//third_party/jni_zero/jni_zero.gni") - - weblayer_browsertests_manifest = - "${target_gen_dir}/weblayer_browsertests_manifest/AndroidManifest.xml" - - jinja_template("weblayer_browsertests_manifest") { - testonly = true - input = "//weblayer/shell/android/browsertests_apk/AndroidManifest.xml" - output = weblayer_browsertests_manifest - } - - android_library("weblayer_browsertests_java") { - testonly = true - sources = [ - "../shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsApplication.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/AccessTokenFetchTestBridge.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherTestStub.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/TranslateTestBridge.java", - ] - deps = [ - ":weblayer_browsertests_jni", - ":weblayer_browsertests_manifest", - "//base:base_java", - "//base:base_java_test_support", - "//base:jni_java", - "//build/android:build_java", - "//components/embedder_support/android:application_java", - "//components/safe_browsing/android:safe_browsing_java", - "//components/translate/content/android:java", - "//content/public/android:content_java", - "//content/public/test/android:content_java_test_support", - "//testing/android/native_test:native_test_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//ui/android:ui_java", - "//weblayer/browser/java", - "//weblayer/browser/java:base_module_interfaces_java", - "//weblayer/browser/java:gms_bridge_java", - "//weblayer/browser/java:interfaces_java", - "//weblayer/public/java", - "//weblayer/public/javatestutil:test_java", - ] - srcjar_deps = [ - ":generated_enums", - ":weblayer_browsertests_jni", - ] - } - - generate_jni("weblayer_browsertests_jni") { - sources = [ - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/AccessTokenFetchTestBridge.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/GoogleAccountAccessTokenFetcherTestStub.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java", - "../shell/android/browsertests_apk/src/org/chromium/weblayer_private/TranslateTestBridge.java", - ] - } - - java_group("weblayer_test_assets") { - testonly = true - deps = [ - "//gin:v8_snapshot_assets", - "//third_party/icu:icu_assets", - ] - } - - java_cpp_enum("generated_enums") { - sources = [ "//weblayer/browser/android/metrics/metrics_test_helper.h" ] - } -} - -test("weblayer_browsertests") { - use_xvfb = use_xvfb_in_this_config - - data = [ - "$root_out_dir/webengine_shell.pak", - "data/", - "//components/test/data", - "//net/tools/testserver/", - "//third_party/pywebsocket3/src/mod_pywebsocket/", - ] - - data_deps = [ - "//third_party/mesa_headers", - "//weblayer/shell:pak", - ] - - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] - - deps = [ - "//base", - "//base/test:test_support", - "//components/autofill/core/browser", - "//components/autofill/core/common", - "//components/background_sync", - "//components/blocked_content", - "//components/browsing_data/content:content", - "//components/content_settings/core/browser", - "//components/embedder_support", - "//components/error_page/content/browser", - "//components/favicon/content", - "//components/heavy_ad_intervention", - "//components/infobars/content", - "//components/language/core/browser", - "//components/network_session_configurator/common", - "//components/network_time", - "//components/no_state_prefetch/browser", - "//components/page_load_metrics/browser:browser", - "//components/page_load_metrics/browser:test_support", - "//components/page_load_metrics/browser/observers/ad_metrics", - "//components/page_load_metrics/browser/observers/ad_metrics:test_support", - "//components/permissions", - "//components/permissions:test_support", - "//components/prefs", - "//components/reduce_accept_language/browser:browser", - "//components/reduce_accept_language/browser:test_support", - "//components/security_interstitials/content:security_interstitial_page", - "//components/sessions:test_support", - "//components/signin/core/browser", - "//components/site_isolation", - "//components/strings", - "//components/subresource_filter/content/browser", - "//components/subresource_filter/content/browser:test_support", - "//components/subresource_filter/core/browser", - "//components/subresource_filter/core/common", - "//components/subresource_filter/core/common:test_support", - "//components/translate/content/browser", - "//components/translate/content/browser:test_support", - "//components/ukm:test_support", - "//components/ukm:ukm_test_helper", - "//components/url_pattern_index/proto:url_pattern_index", - "//components/user_prefs", - "//components/variations", - "//components/variations/net", - "//content/public/browser", - "//content/public/common", - "//content/test:test_support", - "//google_apis", - "//net:test_support", - "//testing/gtest", - "//ui/base", - "//ui/display", - "//ui/gfx:test_support", - "//weblayer:resources", - "//weblayer/shell:webengine_shell_lib", - ] - - sources = [ - "../browser/ad_tagging_browsertest.cc", - "../browser/ads_page_load_metrics_observer_browsertest.cc", - "../browser/background_sync/background_sync_browsertest.cc", - "../browser/client_hints_browsertest.cc", - "../browser/clipboard_browsertest.cc", - "../browser/content_settings_browsertest.cc", - "../browser/cookie_manager_browsertest.cc", - "../browser/download_browsertest.cc", - "../browser/errorpage_browsertest.cc", - "../browser/favicon/favicon_fetcher_browsertest.cc", - "../browser/favicon/test_favicon_fetcher_delegate.cc", - "../browser/favicon/test_favicon_fetcher_delegate.h", - "../browser/fullscreen_browsertest.cc", - "../browser/google_accounts_browsertest.cc", - "../browser/large_sticky_ad_intervention_browsertest.cc", - "../browser/navigation_browsertest.cc", - "../browser/navigation_error_navigation_throttle_browsertest.cc", - "../browser/new_tab_delegate_browsertest.cc", - "../browser/no_state_prefetch/no_state_prefetch_browsertest.cc", - "../browser/overlay_popup_ad_intervention_browsertest.cc", - "../browser/page_load_metrics_browsertest.cc", - "../browser/permissions/permissions_browsertest.cc", - "../browser/popup_blocker_browsertest.cc", - "../browser/prefetch_browsertest.cc", - "../browser/profile_browsertest.cc", - "../browser/reduce_accept_language_service_browsertest.cc", - "../browser/site_isolation_browsertest.cc", - "../browser/ssl_browsertest.cc", - "../browser/subresource_filter_browsertest.cc", - "../browser/translate_browsertest.cc", - "../browser/weblayer_variations_http_browsertest.cc", - "../browser/webui/webui_browsertest.cc", - "browsertests_main.cc", - "interstitial_utils.cc", - "interstitial_utils.h", - "load_completion_observer.cc", - "load_completion_observer.h", - "subresource_filter_browser_test_harness.cc", - "subresource_filter_browser_test_harness.h", - "test_launcher_delegate_impl.cc", - "test_launcher_delegate_impl.h", - "test_navigation_observer.cc", - "test_navigation_observer.h", - "weblayer_browser_test.cc", - "weblayer_browser_test.h", - "weblayer_browser_test_test.cc", - "weblayer_browser_test_utils.cc", - "weblayer_browser_test_utils.h", - ] - - if (is_android) { - sources += [ - "../browser/android/access_token_fetch_browsertest.cc", - "../browser/android/ad_density_intervention_browsertest.cc", - "../browser/android/metrics/metrics_browsertest.cc", - "../browser/android/metrics/metrics_test_helper.cc", - "../browser/android/metrics/metrics_test_helper.h", - "../browser/android/metrics/ukm_browsertest.cc", - "../browser/autofill_browsertest.cc", - "../browser/origin_trials_browsertest.cc", - "../browser/safe_browsing/client_side_detection_service_browsertest.cc", - "../browser/safe_browsing/client_side_detection_service_factory_browsertest.cc", - "../browser/safe_browsing/safe_browsing_browsertest.cc", - "../browser/safe_browsing/weblayer_ping_manager_factory_browsertest.cc", - "../browser/webapps/webapk_install_scheduler_browsertest.cc", - "../shell/android/browsertests_apk/translate_test_bridge.cc", - "../shell/android/browsertests_apk/translate_test_bridge.h", - "../shell/android/browsertests_apk/weblayer_browser_tests_jni_onload.cc", - "stub_autofill_provider.cc", - "stub_autofill_provider.h", - ] - deps += [ - ":weblayer_browsertests_java", - ":weblayer_browsertests_jni", - ":weblayer_test_assets", - "//android_webview:locale_pak_assets", - "//android_webview:pak_file_assets", - "//components/android_autofill/browser:test_support", - "//components/infobars/core", - "//components/metrics", - "//components/origin_trials:browser", - "//components/page_info", - "//components/page_info/android", - "//components/safe_browsing/android:safe_browsing_api_handler", - "//components/safe_browsing/content/browser", - "//components/safe_browsing/content/browser:client_side_detection", - "//components/safe_browsing/content/browser/web_ui", - "//components/safe_browsing/content/common:interfaces", - "//components/safe_browsing/core/browser:token_fetcher", - "//components/safe_browsing/core/common", - "//components/safe_browsing/core/common/proto:client_model_proto", - "//components/viz/service:service_java", - "//components/webapps/browser:browser", - "//content/public/test/android:android_test_message_pump_support_java", - "//content/test:android_test_message_pump_support", - "//content/test:android_test_message_pump_support", - "//services/metrics/public/cpp:ukm_builders", - "//services/network:test_support", - "//services/tracing:test_utils", - "//testing/android/native_test:native_test_support", - "//third_party/metrics_proto", - "//ui/android:android", - "//ui/touch_selection:touch_selection", - "//weblayer:locale_pak_assets", - - # Needed for WebLayerImpl. - "//weblayer/browser/java", - - # default upstream classes - "//weblayer/browser/java:upstream_java", - ] - - # Necessary to avoid GN errors in Cast builds, where this target isn't defined. - if (safe_browsing_mode > 0) { - deps += [ "//components/safe_browsing/content/browser:safe_browsing_blocking_page" ] - } - android_manifest = - "${target_gen_dir}/weblayer_browsertests_manifest/AndroidManifest.xml" - android_manifest_dep = ":weblayer_browsertests_manifest" - use_default_launcher = false - app_as_shared_lib = true - product_config_java_packages = [ weblayer_product_config_java_package ] - } else { - sources += [ - # These tests create Browser objects from C++, which the Java side is not - # setup for. Persistence related tests for Java will be done as - # integration tests. - "../browser/persistence/browser_persister_browsertest.cc", - ] - - deps += [ "//components/keep_alive_registry" ] - } -} - -source_set("run_all_unittests") { - testonly = true - sources = [ "run_all_unittests.cc" ] - public_deps = [ - "//base/test:test_support", - "//content/test:test_support", - "//weblayer:weblayer_lib_base", - ] -} - -test("weblayer_unittests") { - deps = [ - ":run_all_unittests", - "//components/favicon/core:database", - "//components/site_isolation", - "//google_apis", - ] - sources = [ - "../browser/favicon/favicon_backend_wrapper_unittest.cc", - "../browser/profile_disk_operations_unittests.cc", - "../browser/site_isolation_policy_unittest.cc", - ] - if (is_android) { - deps += [ - ":weblayer_test_assets", - "//ui/android:ui_full_java", - ] - sources += [ - "../browser/safe_browsing/safe_browsing_token_fetcher_impl_unittest.cc", - ] - } -}
diff --git a/weblayer/test/DEPS b/weblayer/test/DEPS deleted file mode 100644 index 10cc909..0000000 --- a/weblayer/test/DEPS +++ /dev/null
@@ -1,17 +0,0 @@ -include_rules = [ - "+components/android_autofill/browser", - "+components/autofill/core/browser", - "+components/browsing_data/content", - "+components/embedder_support", - "+components/heavy_ad_intervention", - "+components/security_interstitials", - "+components/subresource_filter/content/browser", - "+components/subresource_filter/core/browser", - "+components/subresource_filter/core/common", - "+components/url_pattern_index/proto", - "+content/public/common", - "+content/public/browser", - "+content/public/test", - "+net/dns/mock_host_resolver.h", - "+net/test", -]
diff --git a/weblayer/test/browsertests_main.cc b/weblayer/test/browsertests_main.cc deleted file mode 100644 index 2d93ccc..0000000 --- a/weblayer/test/browsertests_main.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/command_line.h" -#include "base/test/launcher/test_launcher.h" -#include "build/build_config.h" -#include "content/public/common/content_switches.h" -#include "content/public/test/network_service_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "weblayer/test/test_launcher_delegate_impl.h" - -#if BUILDFLAG(IS_WIN) -#include "base/win/win_util.h" -#endif // BUILDFLAG(IS_WIN) - -int main(int argc, char** argv) { - base::CommandLine::Init(argc, argv); - size_t parallel_jobs = base::NumParallelJobs(/*cores_per_job=*/1); - if (parallel_jobs == 0U) - return 1; - -#if BUILDFLAG(IS_WIN) - // Load and pin user32.dll to avoid having to load it once tests start while - // on the main thread loop where blocking calls are disallowed. - base::win::PinUser32(); -#endif // BUILDFLAG(IS_WIN) - - // Set up a working test environment for the network service in case it's - // used. Only create this object in the utility process, so that its members - // don't interfere with other test objects in the browser process. - std::unique_ptr<content::NetworkServiceTestHelper> - network_service_test_helper = content::NetworkServiceTestHelper::Create(); - - weblayer::TestLauncherDelegateImpl launcher_delegate; - return content::LaunchTests(&launcher_delegate, parallel_jobs, argc, argv); -}
diff --git a/weblayer/test/data/alert.html b/weblayer/test/data/alert.html deleted file mode 100644 index ce622e6..0000000 --- a/weblayer/test/data/alert.html +++ /dev/null
@@ -1,5 +0,0 @@ -<html> - <body onclick="window.alert('tab modal overlay');"> - <p id='x'>XXXX</p> - </body> -</html>
diff --git a/weblayer/test/data/autoplay.html b/weblayer/test/data/autoplay.html deleted file mode 100644 index 933a004..0000000 --- a/weblayer/test/data/autoplay.html +++ /dev/null
@@ -1,7 +0,0 @@ -<html> -<body> -<video id="vid" controls autoplay> - <source src="bear.webm" type="video/mp4"> -</video> -</body> -</html>
diff --git a/weblayer/test/data/background_fetch/index.html b/weblayer/test/data/background_fetch/index.html deleted file mode 100644 index 1fdc2ff7..0000000 --- a/weblayer/test/data/background_fetch/index.html +++ /dev/null
@@ -1,11 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8" /> - <title>A page</title> - <script src="main.js"></script> - </head> - <body> - Hello world. - </body> -</html>
diff --git a/weblayer/test/data/background_fetch/main.js b/weblayer/test/data/background_fetch/main.js deleted file mode 100644 index 12afc37..0000000 --- a/weblayer/test/data/background_fetch/main.js +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -const kBackgroundFetchId = 'bg-fetch-id'; -const kBackgroundFetchResource = - ['/weblayer/test/data/background_fetch/types_of_cheese.txt']; - -function RegisterServiceWorker() { - navigator.serviceWorker.register('sw.js').then(() => { - console.log('service worker registered'); - }); -} - -// Starts a Background Fetch request for a single to-be-downloaded file. -function StartSingleFileDownload() { - navigator.serviceWorker.ready - .then(swRegistration => { - const options = {title: 'Single-file Background Fetch'}; - - return swRegistration.backgroundFetch.fetch( - kBackgroundFetchId, kBackgroundFetchResource, options); - }) - .then(bgFetchRegistration => { - console.log('bg fetch started'); - }) - .catch(error => { - console.log(error); - }); -} - -document.addEventListener('touchend', function(e) { - RegisterServiceWorker(); - StartSingleFileDownload(); -}, false);
diff --git a/weblayer/test/data/background_fetch/new_page.html b/weblayer/test/data/background_fetch/new_page.html deleted file mode 100644 index cb53d47..0000000 --- a/weblayer/test/data/background_fetch/new_page.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8" /> - <title>Another page</title> - </head> -</html>
diff --git a/weblayer/test/data/background_fetch/sw.js b/weblayer/test/data/background_fetch/sw.js deleted file mode 100644 index 676c3c27..0000000 --- a/weblayer/test/data/background_fetch/sw.js +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Service Worker initialization listeners. -self.addEventListener('install', e => e.waitUntil(skipWaiting())); -self.addEventListener('activate', e => e.waitUntil(clients.claim())); - -// Posts |msg| to background_fetch.js. -function postToWindowClients(msg) { - return clients.matchAll({ type: 'window' }).then(clientWindows => { - for (const client of clientWindows) client.postMessage(msg); - }); -} - -self.addEventListener('backgroundfetchsuccess', e => { - console.log('background fetch succeeded'); - e.waitUntil(e.updateUI({title: 'New Fetched Title!'})); -}); - -self.addEventListener('backgroundfetchclick', e => { - e.waitUntil(clients.openWindow( - '/weblayer/test/data/service_worker/new_window.html')); -});
diff --git a/weblayer/test/data/background_fetch/types_of_cheese.txt b/weblayer/test/data/background_fetch/types_of_cheese.txt deleted file mode 100644 index 6059cc6..0000000 --- a/weblayer/test/data/background_fetch/types_of_cheese.txt +++ /dev/null
@@ -1,7 +0,0 @@ -mozzarella -cheddar -brie -goat's cheese -cream cheese -blue cheese -non-dairy "cheese"
diff --git a/weblayer/test/data/background_sync_browsertest.html b/weblayer/test/data/background_sync_browsertest.html deleted file mode 100644 index 6227ec4b..0000000 --- a/weblayer/test/data/background_sync_browsertest.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8" /> - <title>BackgroundSyncBrowserTest helper page</title> - <script> - window.onload = async () => { - let registration = await navigator.serviceWorker.register('/background_sync_sw.js'); - navigator.serviceWorker.ready.then((registration) => { - registration.sync.register('test-tag'); - }); - } - </script> - </head> - <body> - BackgroundSyncBrowserTest helper page - </body> -</html>
diff --git a/weblayer/test/data/background_sync_sw.js b/weblayer/test/data/background_sync_sw.js deleted file mode 100644 index 3b07be88..0000000 --- a/weblayer/test/data/background_sync_sw.js +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -'use strict'; - -// Service Worker initialization listeners. -self.addEventListener('install', event => event.waitUntil(skipWaiting())); -self.addEventListener('activate', event => event.waitUntil(clients.claim())); - -self.addEventListener('sync', event => { - event.waitUntil(fetch( - '/background_sync_browsertest.html?syncreceived')); -});
diff --git a/weblayer/test/data/bear.webm b/weblayer/test/data/bear.webm deleted file mode 100644 index 422df3f..0000000 --- a/weblayer/test/data/bear.webm +++ /dev/null Binary files differ
diff --git a/weblayer/test/data/before_unload.html b/weblayer/test/data/before_unload.html deleted file mode 100644 index d79f378..0000000 --- a/weblayer/test/data/before_unload.html +++ /dev/null
@@ -1,10 +0,0 @@ -<html> - <body onbeforeunload="return runBeforeUnload()"> - <p>Some text so the document is ready for input.</p> - </body> - <script> - function runBeforeUnload() { - return "foo"; - } - </script> -</html>
diff --git a/weblayer/test/data/clear_site_data.html b/weblayer/test/data/clear_site_data.html deleted file mode 100644 index 727f1b89..0000000 --- a/weblayer/test/data/clear_site_data.html +++ /dev/null
@@ -1,5 +0,0 @@ -<html> -<head><title>Clear-Site-Data Test Page</title></head> -<body>Clear-Site-Data test body</body> -</html> -
diff --git a/weblayer/test/data/clear_site_data.html.mock-http-headers b/weblayer/test/data/clear_site_data.html.mock-http-headers deleted file mode 100644 index 4757bc4..0000000 --- a/weblayer/test/data/clear_site_data.html.mock-http-headers +++ /dev/null
@@ -1,2 +0,0 @@ -HTTP/1.1 200 OK -Clear-Site-Data: "cache", "cookies", "storage"
diff --git a/weblayer/test/data/clipboard.html b/weblayer/test/data/clipboard.html deleted file mode 100644 index 850a17e5..0000000 --- a/weblayer/test/data/clipboard.html +++ /dev/null
@@ -1,19 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8" /> - <title>Clipboard API helper page</title> - <script> - function tryClipboardReadText() { - navigator.clipboard.readText() - .then(() => document.title = 'success') - .catch(() => document.title = 'fail'); - } - function tryClipboardWriteText() { - navigator.clipboard.writeText('test') - .then(() => document.title = 'success') - .catch(() => document.title = 'fail'); - } - </script> - </head> -</html>
diff --git a/weblayer/test/data/content-disposition.html b/weblayer/test/data/content-disposition.html deleted file mode 100644 index 5c11777..0000000 --- a/weblayer/test/data/content-disposition.html +++ /dev/null
@@ -1,5 +0,0 @@ -<html> -<body> -test -</body> -</html>
diff --git a/weblayer/test/data/content-disposition.html.mock-http-headers b/weblayer/test/data/content-disposition.html.mock-http-headers deleted file mode 100644 index edd7629..0000000 --- a/weblayer/test/data/content-disposition.html.mock-http-headers +++ /dev/null
@@ -1,2 +0,0 @@ -HTTP/1.0 200 OK -Content-Disposition: attachment; filename=test.html
diff --git a/weblayer/test/data/dark_mode.html b/weblayer/test/data/dark_mode.html deleted file mode 100644 index 89ecc16..0000000 --- a/weblayer/test/data/dark_mode.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> - <head> - <meta name="color-scheme" content="dark light"> - </head> - <body></body> -</html>
diff --git a/weblayer/test/data/display_cutout.html b/weblayer/test/data/display_cutout.html deleted file mode 100644 index 891f92d..0000000 --- a/weblayer/test/data/display_cutout.html +++ /dev/null
@@ -1,29 +0,0 @@ -<html> - <head> - <meta name="viewport" content="width=device-width, initial-scale=1"></meta> - </head> - <body> - <p>Greetings planet</p> - </body> - <script> - function toggleFullscreen() { - if (!document.fullscreenElement) { - document.documentElement.requestFullscreen(); - } else { - document.exitFullscreen(); - } - } - document.addEventListener('click', function(e) { toggleFullscreen(); }, false); - - const viewport = document.getElementsByTagName('meta')[0]; - const defaultValue = viewport.getAttribute('content'); - - function setViewportFit(fit) { - if (fit) { - viewport.setAttribute('content', defaultValue + ', viewport-fit=' + fit); - } else { - viewport.setAttribute('content', defaultValue); - } - } - </script> -</html>
diff --git a/weblayer/test/data/done.html b/weblayer/test/data/done.html deleted file mode 100644 index 772a2fa..0000000 --- a/weblayer/test/data/done.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<body> -Navigation complete. -This file should not contain any forms. -</body> -</html> \ No newline at end of file
diff --git a/weblayer/test/data/download.html b/weblayer/test/data/download.html deleted file mode 100644 index bb9423d..0000000 --- a/weblayer/test/data/download.html +++ /dev/null
@@ -1,18 +0,0 @@ -<html> - <head> - <style> - body, html { - height: 100%; - } - - a { - display: block; - height: 100%; - width: 100%; - } - </style> - </head> - <body> - <a href="lorem_ipsum.txt" download>anchor text</a> - </body> -</html>
diff --git a/weblayer/test/data/empty404.html b/weblayer/test/data/empty404.html deleted file mode 100644 index e69de29..0000000 --- a/weblayer/test/data/empty404.html +++ /dev/null
diff --git a/weblayer/test/data/empty404.html.mock-http-headers b/weblayer/test/data/empty404.html.mock-http-headers deleted file mode 100644 index 0590363..0000000 --- a/weblayer/test/data/empty404.html.mock-http-headers +++ /dev/null
@@ -1,2 +0,0 @@ -HTTP/1.0 404 Not Found -Content-type: text/html
diff --git a/weblayer/test/data/english_page.html b/weblayer/test/data/english_page.html deleted file mode 100644 index 30b0d42..0000000 --- a/weblayer/test/data/english_page.html +++ /dev/null
@@ -1,7 +0,0 @@ -<html> -<head><title>This page is in English</title></head> -<body> -No joke! This is a page written in English. Awesome don't you think? -It has to be more than 100 bytes long for the CLD to detect the language correctly. -</body> -</html>
diff --git a/weblayer/test/data/external_intents.html b/weblayer/test/data/external_intents.html deleted file mode 100644 index 192e4106..0000000 --- a/weblayer/test/data/external_intents.html +++ /dev/null
@@ -1,11 +0,0 @@ -<!DOCTYPE html> -<html> - <body> - <a id="button"> - launch state activity - </a> - <script type="text/javascript"> - document.getElementById('button').href = 'intent://state.app?return_to=' + window.location.href.split('#')[1] + '#Intent;scheme=webenginetest;action=android.intent.action.VIEW;package=org.chromium.webengine.test.external.intents;end;'; - </script> - </body> -</html>
diff --git a/weblayer/test/data/favicon.png b/weblayer/test/data/favicon.png deleted file mode 100644 index 85f38b2..0000000 --- a/weblayer/test/data/favicon.png +++ /dev/null Binary files differ
diff --git a/weblayer/test/data/form.html b/weblayer/test/data/form.html deleted file mode 100644 index a957bd1..0000000 --- a/weblayer/test/data/form.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> - <body onclick="document.forms['form1'].submit();"> - <form id="form1" action="simple_page.html" method="post"> - <input type="text" name="name" value="Name"><br> - <input type="text" name="address" value="Address"><br> - <input type="text" name="city" value="City"><br> - </form> - </body> -</html>
diff --git a/weblayer/test/data/fr_test.html b/weblayer/test/data/fr_test.html deleted file mode 100644 index f7456ca4..0000000 --- a/weblayer/test/data/fr_test.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> -<head> - <title>fr_test.html</title> - <meta http-equiv="content-language" content="fr"> -</head> -<body> - <div>bonjour WebLayer.</div> -</body> -</html>
diff --git a/weblayer/test/data/french_page.html b/weblayer/test/data/french_page.html deleted file mode 100644 index a9d7eaf..0000000 --- a/weblayer/test/data/french_page.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> -<head><title>Cette page est en Français</title></head> -<body> -Cette page a été rédigée en français. Saviez-vous que le Français est la langue officielle des jeux olympiques? Ça vous en bouche un coin, pas vrai? -<a id='link_to_french_page2' href="/weblayer/test/data/french_page2.html"> -Une autre page en français -</a> -</body> -</html>
diff --git a/weblayer/test/data/french_page2.html b/weblayer/test/data/french_page2.html deleted file mode 100644 index 7fcf684..0000000 --- a/weblayer/test/data/french_page2.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<head><title>Cette page est en Français</title></head> -<body> -Cette page a été rédigée en français. Saviez-vous que le Français est la langue officielle des jeux olympiques? Ça vous en bouche un coin, pas vrai? -</body> -</html>
diff --git a/weblayer/test/data/french_page_no_translate.html b/weblayer/test/data/french_page_no_translate.html deleted file mode 100644 index 1808269..0000000 --- a/weblayer/test/data/french_page_no_translate.html +++ /dev/null
@@ -1,7 +0,0 @@ -<html> -<meta name="google" value="notranslate"> -<head><title>Cette page est en Français</title></head> -<body> -Cette page a été rédigée en français. Saviez-vous que le Français est la langue officielle des jeux olympiques? Ça vous en bouche un coin, pas vrai? -</body> -</html>
diff --git a/weblayer/test/data/fullscreen.html b/weblayer/test/data/fullscreen.html deleted file mode 100644 index a45922f..0000000 --- a/weblayer/test/data/fullscreen.html +++ /dev/null
@@ -1,14 +0,0 @@ -<html> - <script> - function toggleFullscreen() { - if (!document.fullscreenElement) { - document.getElementById('x').requestFullscreen(); - } else { - document.exitFullscreen(); - } - } - </script> - <body onclick="toggleFullscreen();"> - <p id='x'>X</p> - </body> -</html>
diff --git a/weblayer/test/data/fullscreen_with_input.html b/weblayer/test/data/fullscreen_with_input.html deleted file mode 100644 index 0229fa2..0000000 --- a/weblayer/test/data/fullscreen_with_input.html +++ /dev/null
@@ -1,17 +0,0 @@ -<html> - <body> - <input id="x" type="text"/> - <p>Content for on screen keyboard testing.</p> - </body> - <script> - var actionCount = 0; - function doAction() { - if (actionCount++ == 1) { - document.documentElement.requestFullscreen(); - } else { - document.getElementById("x").focus(); - } - } - document.addEventListener('click', function(e) { doAction(); }, false); - </script> -</html>
diff --git a/weblayer/test/data/geolocation.html b/weblayer/test/data/geolocation.html deleted file mode 100644 index fd81a5b..0000000 --- a/weblayer/test/data/geolocation.html +++ /dev/null
@@ -1,24 +0,0 @@ -<html> -<head> - <title>Geolocation</title> - <script> - var positionCount = 0; - var errorCount = 0; - function gotPos(position) { - positionCount++; - } - function errorCallback(error) { - errorCount++; - } - function initiate_getCurrentPosition() { - navigator.geolocation.getCurrentPosition( - gotPos, errorCallback, {}); - } - function initiate_watchPosition() { - navigator.geolocation.watchPosition( - gotPos, errorCallback, {}); - } - </script> - <body></body> -</head> -</html>
diff --git a/weblayer/test/data/german_page.html b/weblayer/test/data/german_page.html deleted file mode 100644 index 67811839..0000000 --- a/weblayer/test/data/german_page.html +++ /dev/null
@@ -1,7 +0,0 @@ -<html> -<head><title>Diese Seite ist in deutsch</title></head> -<body> -Kein Witz! Dies ist eine Seite in Deutsch. Großartig, findest du nicht? -Deutsch wird in vielen Ländern gesprochen und ist eine schöne Sprache. Ich hoffe, das ist genug Text, um CLD auszulösen. -</body> -</html>
diff --git a/weblayer/test/data/getusermedia.html b/weblayer/test/data/getusermedia.html deleted file mode 100644 index 2eeca17..0000000 --- a/weblayer/test/data/getusermedia.html +++ /dev/null
@@ -1,17 +0,0 @@ -<!doctype html> -<html> - <head> - <script> - (async () => { - let stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true}); - audio.srcObject = new MediaStream(stream.getAudioTracks()); - video.srcObject = new MediaStream(stream.getVideoTracks()); - })(); - </script> - </head> - <body> - <audio id="audio" controls autoplay></audio><br> - <video id="video" width="160" height="120" controls autoplay></video> - <div id="div"></div> - </body> -</html>
diff --git a/weblayer/test/data/getusermedia2.html b/weblayer/test/data/getusermedia2.html deleted file mode 100644 index cbdf1d09..0000000 --- a/weblayer/test/data/getusermedia2.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!doctype html> -<html> - <head> - <script> - (async () => { - let stream = await navigator.mediaDevices.getUserMedia({video: false, audio: true}); - audio.srcObject = new MediaStream(stream.getAudioTracks()); - let streamV = await navigator.mediaDevices.getUserMedia({video: true, audio: false}); - video.srcObject = new MediaStream(stream2.getVideoTracks()); - })(); - </script> - </head> - <body> - <audio id="audio" controls autoplay></audio><br> - <video id="video" width="160" height="120" controls autoplay></video> - <div id="div"></div> - </body> -</html>
diff --git a/weblayer/test/data/google_accounts.html b/weblayer/test/data/google_accounts.html deleted file mode 100644 index 822bfce..0000000 --- a/weblayer/test/data/google_accounts.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<head><title>Google accounts</title></head> -<body> -Google accounts page. -</body> -</html>
diff --git a/weblayer/test/data/google_accounts.html.mock-http-headers b/weblayer/test/data/google_accounts.html.mock-http-headers deleted file mode 100644 index c3b5008..0000000 --- a/weblayer/test/data/google_accounts.html.mock-http-headers +++ /dev/null
@@ -1,2 +0,0 @@ -HTTP/1.0 200 OK -X-Chrome-Manage-Accounts: action=ADDSESSION,email=foo@bar.com,continue_url=https://blah.com,is_same_tab=true
diff --git a/weblayer/test/data/iframe_blank.html b/weblayer/test/data/iframe_blank.html deleted file mode 100644 index 9e37525..0000000 --- a/weblayer/test/data/iframe_blank.html +++ /dev/null
@@ -1,4 +0,0 @@ -<html><head><title>Blank iframe test</title></head> -<body> -<iframe id="test"></iframe> -</body></html>
diff --git a/weblayer/test/data/img.html b/weblayer/test/data/img.html deleted file mode 100644 index e7731f7..0000000 --- a/weblayer/test/data/img.html +++ /dev/null
@@ -1,19 +0,0 @@ -<html> - <head> - <style> - body, html { - height: 100%; - } - - img { - display: block; - height: 100%; - width: 100%; - } - </style> - </head> - <body> - <img src="favicon.png" alt="alt_text" /> - </body> -</html> -
diff --git a/weblayer/test/data/input_types.html b/weblayer/test/data/input_types.html deleted file mode 100644 index d8d7d3d..0000000 --- a/weblayer/test/data/input_types.html +++ /dev/null
@@ -1,14 +0,0 @@ -<html> - <body> - <form action="about:blank"> - <input id="input_file" type="file" /> - <input id="input_text" type="file" accept="text/plain" /> - <input id="input_any" type="file" accept="*/*" /> - <input id="input_file_multiple" type="file" multiple /> - <input id="input_image" type="file" accept="image/*" capture /> - <input id="input_audio" type="file" accept="audio/*" capture /> - <input id="input_color" type="color" /> - </form> - <p>Some text so the document is ready for input.</p> - </body> -</html>
diff --git a/weblayer/test/data/insecure_form.html b/weblayer/test/data/insecure_form.html deleted file mode 100644 index d4b22d4..0000000 --- a/weblayer/test/data/insecure_form.html +++ /dev/null
@@ -1,18 +0,0 @@ -<html> -<head><title>Page that displays an insecure form</title> -<script> - function submitForm() { - form = document.getElementById("insecureForm"); - form.submit(); - } -</script> -</head> -<body> -This page contains a form which targets a non-secure URL, -causing insecure content (when this page is loaded over https).<br> -<form id="insecureForm" action="http://does-not-exist.test/form_target.html"> -<input type="submit" /> -</form> - -</body> -</html>
diff --git a/weblayer/test/data/link_rel_next_parent.html b/weblayer/test/data/link_rel_next_parent.html deleted file mode 100644 index 97ce230e..0000000 --- a/weblayer/test/data/link_rel_next_parent.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> -<body> -This page will prerender something. -<link rel="next" href="/prerendered_page.html"> -</body> - -<!-- Order is important for tests. --> -<head><title>Parent Page</title></head> -</html>
diff --git a/weblayer/test/data/link_to_page_that_intents_to_package_on_load.html b/weblayer/test/data/link_to_page_that_intents_to_package_on_load.html deleted file mode 100644 index e31ef486..0000000 --- a/weblayer/test/data/link_to_page_that_intents_to_package_on_load.html +++ /dev/null
@@ -1,15 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" - content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> -</head> -<body> - <a id='link'> - <script type="text/javascript"> - document.getElementById('link').href = '/weblayer/test/data/page_that_intents_to_package_on_load.html' + window.location.hash; - </script> - Click to go to page that intents to the package specified in the URL hash on load -</a> -</body> -</html>
diff --git a/weblayer/test/data/link_with_intent_to_package_in_new_tab.html b/weblayer/test/data/link_with_intent_to_package_in_new_tab.html deleted file mode 100644 index f5741bc..0000000 --- a/weblayer/test/data/link_with_intent_to_package_in_new_tab.html +++ /dev/null
@@ -1,15 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" - content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> -</head> -<body> - <a id='link' target='_blank'> - Click to intent to the package specified in the URL hash in a new tab - </a> - <script type="text/javascript"> - document.getElementById('link').href = 'intent://example.test#Intent;scheme=https;action=android.intent.action.VIEW;package=' + window.location.href.split('#')[1] + ';end'; - </script> -</body> -</html>
diff --git a/weblayer/test/data/link_with_intent_to_package_in_same_tab.html b/weblayer/test/data/link_with_intent_to_package_in_same_tab.html deleted file mode 100644 index c6b8592..0000000 --- a/weblayer/test/data/link_with_intent_to_package_in_same_tab.html +++ /dev/null
@@ -1,15 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" - content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> -</head> -<body> - <a id='link'> - Click to intent to the package specified in the URL hash in this tab - </a> - <script type="text/javascript"> - document.getElementById('link').href = 'intent://example.test#Intent;scheme=https;action=android.intent.action.VIEW;package=' + window.location.href.split('#')[1] + ';end'; - </script> -</body> -</html>
diff --git a/weblayer/test/data/lorem_ipsum.txt b/weblayer/test/data/lorem_ipsum.txt deleted file mode 100644 index cc8ae61..0000000 --- a/weblayer/test/data/lorem_ipsum.txt +++ /dev/null
@@ -1,6 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
diff --git a/weblayer/test/data/media_router/basic_test.html b/weblayer/test/data/media_router/basic_test.html deleted file mode 100644 index e4fbda20..0000000 --- a/weblayer/test/data/media_router/basic_test.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE HTML> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>MR Integration Basic Test</title> - <script type="text/javascript" src="common.js"></script> - </head> - <body> - </body> -</html>
diff --git a/weblayer/test/data/media_router/common.js b/weblayer/test/data/media_router/common.js deleted file mode 100644 index 6c0fa53..0000000 --- a/weblayer/test/data/media_router/common.js +++ /dev/null
@@ -1,324 +0,0 @@ -/* - * Copyright 2020 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* - * @fileoverview Test utilities for presentation integration tests. - */ - -var startPresentationPromise = null; -var startedConnection = null; -var reconnectedConnection = null; -var presentationUrl = "cast:CCCCCCCC"; -let params = (new URL(window.location.href)).searchParams; - -var presentationRequest = new PresentationRequest([presentationUrl]); -var defaultRequestConnectionId = null; -var lastExecutionResult = null; - -window.navigator.presentation.defaultRequest = presentationRequest; -window.navigator.presentation.defaultRequest.onconnectionavailable = function( - e) { - defaultRequestConnectionId = e.connection.id; -}; - -/** - * Waits until one sink is available. - */ -function waitUntilDeviceAvailable() { - presentationRequest.getAvailability(presentationUrl) - .then(function(availability) { - console.log('availability ' + availability.value + '\n'); - if (availability.value) { - sendResult(true, ''); - } else { - availability.onchange = function(newAvailability) { - if (newAvailability) - sendResult(true, ''); - } - } - }) - .catch(function(e) { - sendResult(false, 'got error: ' + e); - }); -} - -/** - * Starts presentation. - */ -function startPresentation() { - startPresentationPromise = presentationRequest.start(); - console.log('start presentation'); - sendResult(true, ''); -} - -/** - * Checks if the presentation has been started successfully. - */ -function checkConnection() { - if (!startPresentationPromise) { - sendResult(false, 'Did not attempt to start presentation'); - } else { - startPresentationPromise - .then(function(connection) { - if (!connection) { - sendResult( - false, 'Failed to start presentation: connection is null'); - } else { - // set the new connection - startedConnection = connection; - waitForConnectedStateAndSendResult(startedConnection); - } - }) - .catch(function(e) { - // terminate old connection if exists - startedConnection && startedConnection.terminate(); - sendResult( - false, 'Failed to start connection: encountered exception ' + e); - }) - } -} - -/** - * Asserts the current state of the connection is 'connected' or 'connecting'. - * If the current state is connecting, waits for it to become 'connected'. - * @param {!PresentationConnection} connection - */ -function waitForConnectedStateAndSendResult(connection) { - console.log('connection state is "' + connection.state + '"'); - if (connection.state == 'connected') { - sendResult(true, ''); - } else if (connection.state == 'connecting') { - connection.onconnect = () => { - sendResult(true, ''); - }; - } else { - sendResult( - false, - 'Expect connection state to be "connecting" or "connected", actual: ' + - connection.state); - } -} - -/** - * Checks the start() request fails with expected error and message substring. - * @param {!string} expectedErrorName - * @param {!string} expectedErrorMessageSubstring - */ -function checkStartFailed(expectedErrorName, expectedErrorMessageSubstring) { - if (!startPresentationPromise) { - sendResult(false, 'Did not attempt to start presentation'); - } else { - startPresentationPromise - .then(function(connection) { - sendResult(false, 'start() unexpectedly succeeded.'); - }) - .catch(function(e) { - if (expectedErrorName != e.name) { - sendResult( - false, 'Got unexpected error. ' + e.name + ': ' + e.message); - } else if (e.message.indexOf(expectedErrorMessageSubstring) == -1) { - sendResult( - false, - 'Error message is not correct, it should contain "' + - expectedErrorMessageSubstring + '"'); - } else { - sendResult(true, ''); - } - }) - } -} - -/** - * Terminates current presentation. - */ -function terminateConnectionAndWaitForStateChange() { - if (startedConnection) { - startedConnection.onterminate = function() { - sendResult(true, ''); - }; - startedConnection.terminate(); - } else { - sendResult(false, 'startedConnection does not exist.'); - } -} - -/** - * Closes |startedConnection| and waits for its onclose event. - */ -function closeConnectionAndWaitForStateChange() { - if (startedConnection) { - if (startedConnection.state == 'closed') { - sendResult(false, 'startedConnection is unexpectedly closed.'); - return; - } - startedConnection.onclose = function() { - sendResult(true, ''); - }; - startedConnection.close(); - } else { - sendResult(false, 'startedConnection does not exist.'); - } -} - -/** - * Sends a message to |startedConnection| and expects InvalidStateError to be - * thrown. Requires |startedConnection.state| to not equal |initialState|. - */ -function checkSendMessageFailed(initialState) { - if (!startedConnection) { - sendResult(false, 'startedConnection does not exist.'); - return; - } - if (startedConnection.state != initialState) { - sendResult( - false, - 'startedConnection.state is "' + startedConnection.state + - '", but we expected "' + initialState + '".'); - return; - } - - try { - startedConnection.send('test message'); - } catch (e) { - if (e.name == 'InvalidStateError') { - sendResult(true, ''); - } else { - sendResult(false, 'Got an unexpected error: ' + e.name); - } - } - sendResult(false, 'Expected InvalidStateError but it was never thrown.'); -} - -/** - * Sends a message, and expects the connection to close on error. - */ -function sendMessageAndExpectConnectionCloseOnError() { - if (!startedConnection) { - sendResult(false, 'startedConnection does not exist.'); - return; - } - startedConnection.onclose = function(event) { - var reason = event.reason; - if (reason != 'error') { - sendResult(false, 'Unexpected close reason: ' + reason); - return; - } - sendResult(true, ''); - }; - startedConnection.send('foo'); -} - -/** - * Sends the given message, and expects response from the receiver. - * @param {!string} message - */ -function sendMessageAndExpectResponse(message) { - if (!startedConnection) { - sendResult(false, 'startedConnection does not exist.'); - return; - } - if (startedConnection.state != 'connected') { - sendResult( - false, - 'Expected the connection state to be connected but it was ' + - startedConnection.state); - return; - } - startedConnection.onmessage = function(receivedMessage) { - var expectedResponse = 'Pong: ' + message; - var actualResponse = receivedMessage.data; - if (actualResponse != expectedResponse) { - sendResult( - false, - 'Expected message: ' + expectedResponse + - ', but got: ' + actualResponse); - return; - } - sendResult(true, ''); - }; - startedConnection.send(message); -} - -/** - * Sends 'close' to receiver page, and expects receiver page closing - * the connection. - */ -function initiateCloseFromReceiverPage() { - if (!startedConnection) { - sendResult(false, 'startedConnection does not exist.'); - return; - } - if (startedConnection.state != 'connected') { - sendResult( - false, - 'Expected the connection state to be connected but it was ' + - startedConnection.state); - return; - } - startedConnection.onclose = (event) => { - const reason = event.reason; - if (reason != 'closed') { - sendResult(false, 'Unexpected close reason: ' + reason); - return; - } - sendResult(true, ''); - }; - startedConnection.send('close'); -} - -/** - * Reconnects to |connectionId| and verifies that it succeeds. - * @param {!string} connectionId ID of connection to reconnect. - */ -function reconnectConnection(connectionId) { - var reconnectConnectionRequest = new PresentationRequest(presentationUrl); - reconnectConnectionRequest.reconnect(connectionId) - .then(function(connection) { - if (!connection) { - sendResult(false, 'reconnectConnection returned null connection'); - } else { - reconnectedConnection = connection; - waitForConnectedStateAndSendResult(reconnectedConnection); - } - }) - .catch(function(error) { - sendResult(false, 'reconnectConnection failed: ' + error.message); - }); -} - -/** - * Calls reconnect(connectionId) and verifies that it fails. - * @param {!string} connectionId ID of connection to reconnect. - */ -function reconnectConnectionAndExpectFailure( - connectionId) { - var reconnectConnectionRequest = new PresentationRequest(presentationUrl); - var expectedErrorMessage = 'Unknown route'; - reconnectConnectionRequest.reconnect(connectionId) - .then(function(connection) { - sendResult(false, 'reconnect() unexpectedly succeeded.'); - }) - .catch(function(error) { - if (error.message.indexOf(expectedErrorMessage) > -1) { - sendResult(true, ''); - } else { - sendResult( - false, - 'Error message mismatch. Expected: ' + expectedErrorMessage + - ', actual: ' + error.message); - } - }); -} - -/** - * Sends the test result back to browser test. - * @param passed true if test passes, otherwise false. - * @param errorMessage empty string if test passes, error message if test - * fails. - */ -function sendResult(passed, errorMessage) { - lastExecutionResult = passed ? 'passed' : errorMessage; -}
diff --git a/weblayer/test/data/media_session.html b/weblayer/test/data/media_session.html deleted file mode 100644 index 23433240..0000000 --- a/weblayer/test/data/media_session.html +++ /dev/null
@@ -1,12 +0,0 @@ -<html> - <script> - function playAudio() { - let audio = document.createElement('audio'); - audio.src = 'test_audio.ogg'; - audio.play(); - } - </script> - <body onclick="playAudio();"> - <p>Some text so the document is ready for input.</p> - </body> -</html>
diff --git a/weblayer/test/data/new_browser.html b/weblayer/test/data/new_browser.html deleted file mode 100644 index b2eacd7..0000000 --- a/weblayer/test/data/new_browser.html +++ /dev/null
@@ -1,5 +0,0 @@ -<html> - <body onclick="window.open('about:blank', '');"> - <p id='x'>XXXX</p> - </body> -</html>
diff --git a/weblayer/test/data/new_tab_then_close.html b/weblayer/test/data/new_tab_then_close.html deleted file mode 100644 index bc22379..0000000 --- a/weblayer/test/data/new_tab_then_close.html +++ /dev/null
@@ -1,16 +0,0 @@ -<html> - <script> - var openedWindow = null; - function openNewWindowOrClose() { - if (openedWindow == null) { - openedWindow = window.open('about:blank', ''); - } else { - openedWindow.close(); - openedWindow = null; - } - } - </script> - <body onclick="openNewWindowOrClose();"> - <p>some content</p> - </body> -</html>
diff --git a/weblayer/test/data/non_empty404.html b/weblayer/test/data/non_empty404.html deleted file mode 100644 index ebf944d..0000000 --- a/weblayer/test/data/non_empty404.html +++ /dev/null
@@ -1,5 +0,0 @@ -<html> -<body> -404 with some body. -</body> -</html> \ No newline at end of file
diff --git a/weblayer/test/data/non_empty404.html.mock-http-headers b/weblayer/test/data/non_empty404.html.mock-http-headers deleted file mode 100644 index 0590363..0000000 --- a/weblayer/test/data/non_empty404.html.mock-http-headers +++ /dev/null
@@ -1,2 +0,0 @@ -HTTP/1.0 404 Not Found -Content-type: text/html
diff --git a/weblayer/test/data/page_that_intents_to_package_on_load.html b/weblayer/test/data/page_that_intents_to_package_on_load.html deleted file mode 100644 index e46dfe1..0000000 --- a/weblayer/test/data/page_that_intents_to_package_on_load.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" - content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> -</head> -<body> - <a id='link'> - Click to intent to the package specified in the URL hash in this tab - </a> -<script> - document.getElementById('link').href = 'intent://example.test#Intent;scheme=https;action=android.intent.action.VIEW;package=' + window.location.href.split('#')[1] + ';end'; - window.addEventListener("load", function() { - document.getElementById("link").click(); - }, false); -</script> -</body> -</html>
diff --git a/weblayer/test/data/parent_page.html b/weblayer/test/data/parent_page.html deleted file mode 100644 index 50d810fd7..0000000 --- a/weblayer/test/data/parent_page.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> -<body> -This page will prerender something. -<link rel="prerender" href="/prerendered_page.html"> -</body> - -<!-- Order is important for tests. --> -<head><title>Parent Page</title></head> -</html>
diff --git a/weblayer/test/data/postmessage.html b/weblayer/test/data/postmessage.html deleted file mode 100644 index 5c64248..0000000 --- a/weblayer/test/data/postmessage.html +++ /dev/null
@@ -1,24 +0,0 @@ -<html> - -<head><title>Page</title></head> -<body> - <h1>post message test page</h1> -</body> - -<script> - let numMessages = 0; - window.addEventListener('message', e => { - - numMessages++; - document.title = `postMessage: ${numMessages}`; - - e.ports[0].postMessage(`message: ${e.data}, source: ${e.origin}`); - - if (e.data.includes('delayed')) { - setTimeout(() => e.ports[0].postMessage(`message: ${e.data}2, source: ${e.origin}`), 1000); - setTimeout(() => e.ports[0].postMessage(`message: ${e.data}3, source: ${e.origin}`), 2000); - } - }); - -</script> -</html>
diff --git a/weblayer/test/data/prefetch.js b/weblayer/test/data/prefetch.js deleted file mode 100644 index 6f867aa3..0000000 --- a/weblayer/test/data/prefetch.js +++ /dev/null
@@ -1,6 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This isn't used anywhere. -var theScriptHasExecuted = true;
diff --git a/weblayer/test/data/prefetch_meta.js b/weblayer/test/data/prefetch_meta.js deleted file mode 100644 index 338e395..0000000 --- a/weblayer/test/data/prefetch_meta.js +++ /dev/null
@@ -1,6 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This isn't used anywhere. -var theMetaScriptHasExecuted = true;
diff --git a/weblayer/test/data/prefetch_target.lnk b/weblayer/test/data/prefetch_target.lnk deleted file mode 100644 index e69de29..0000000 --- a/weblayer/test/data/prefetch_target.lnk +++ /dev/null
diff --git a/weblayer/test/data/prerendered_page.html b/weblayer/test/data/prerendered_page.html deleted file mode 100644 index badd30a2..0000000 --- a/weblayer/test/data/prerendered_page.html +++ /dev/null
@@ -1,35 +0,0 @@ -<html> -<!-- -A page that fetches only "prefetch.js" when scanned by NoStatePrefetch, and -fetches "prefetch_meta.js" in addition to that if javascript execution happens -on the page. In all cases the scripts are executed in a blocking manner. - -By prefetching this page, a browsertest can verify that javascript was not -executed (prefetch_meta.js should not be requested to load even after the page -has been fully prefetched (or loaded)). - -Note: there is no way to ensure that the script loaded via .appendChild() or a -sync XHR happens before a preload-scannable request because preload scanner is -racy and often fetches resources it sees before the inline script has a chance -to execute. ---> -<body> - <script> - var s = document.createElement("script"); - s.src = "prefetch_meta.js"; - document.body.appendChild(s); - </script> - - <!-- Ordering is imporant here because the test harness relies on sequential - parsing of this page. When a fetch request for prefetch.js happens, it can - be safely assumed that the browser has parsed the inline script above. --> - <script src="prefetch.js"></script> - - Some content that is necessary for registering paint metrics. -</body> - -<head> - <!-- Ordering on the page is important. --> - <title>Prefetch Page</title> -</head> -</html>
diff --git a/weblayer/test/data/quadrant_colors.html b/weblayer/test/data/quadrant_colors.html deleted file mode 100644 index fb1ace5..0000000 --- a/weblayer/test/data/quadrant_colors.html +++ /dev/null
@@ -1,8 +0,0 @@ -<html> - <body style="padding: 0; margin: 0; display: grid; display: grid; grid-template-columns: 50% 50%; grid-template-rows: 50% 50%;\"> - <div style="background-color: rgb(255, 0, 0);"></div> - <div style="background-color: rgb(0, 255, 0);"></div> - <div style="background-color: rgb(0, 0, 255);"></div> - <div style="background-color: rgb(128, 128, 128);"></div> - </body> -</html>
diff --git a/weblayer/test/data/rotation.html b/weblayer/test/data/rotation.html deleted file mode 100644 index fc8ab98..0000000 --- a/weblayer/test/data/rotation.html +++ /dev/null
@@ -1,32 +0,0 @@ -<html> - <script> - var gotHide = false; - var gotOrientationChange = false; - var attachedListeners = false; - async function doRequestFullscreen() { - return document.documentElement.requestFullscreen(); - } - async function toggleFullscreen() { - if (!attachedListeners) { - attachedListeners = true; - document.addEventListener("visibilitychange", function() { - if (document.visibilityState !== 'visible') { - gotHide = true; - } - }); - window.addEventListener("orientationchange", function() { - gotOrientationChange = true; - }); - } - if (!document.fullscreenElement) { - await doRequestFullscreen(); - await screen.orientation.lock("landscape"); - } else { - document.exitFullscreen(); - } - } - </script> - <body style="height:5000px" onclick="toggleFullscreen();"> - <p>A (mostly) empty page.</p> - </body> -</html>
diff --git a/weblayer/test/data/rotation2.html b/weblayer/test/data/rotation2.html deleted file mode 100644 index 00bc330..0000000 --- a/weblayer/test/data/rotation2.html +++ /dev/null
@@ -1,15 +0,0 @@ -<html> - <script> - async function toggleFullscreen() { - if (!document.fullscreenElement) { - await document.documentElement.requestFullscreen(); - await screen.orientation.lock("landscape-primary"); - } else { - document.exitFullscreen(); - } - } - </script> - <body style="height:5000px" onclick="toggleFullscreen();"> - <p>A page that will rotate on touch.</p> - </body> -</html>
diff --git a/weblayer/test/data/shakespeare.html b/weblayer/test/data/shakespeare.html deleted file mode 100644 index 2120243..0000000 --- a/weblayer/test/data/shakespeare.html +++ /dev/null
@@ -1,20 +0,0 @@ -<html> - <body> - <p> - No, Time, thou shalt not boast that I do change: - Thy pyramids built up with newer might - To me are nothing novel, nothing strange; - They are but dressings of a former sight. - Our dates are brief, and therefore we admire - What thou dost foist upon us that is old, - And rather make them born to our desire - Than think that we before have heard them told. - Thy registers and thee I both defy, - Not wondering at the present nor the past, - For thy records and what we see doth lie, - Made more or less by thy continual haste. - This I do vow and this shall ever be; - I will be true, despite thy scythe and thee. - </p> - </body> -</html>
diff --git a/weblayer/test/data/simple_page.html b/weblayer/test/data/simple_page.html deleted file mode 100644 index 6170792..0000000 --- a/weblayer/test/data/simple_page.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<head><title>OK</title></head> -<body> -Basic html test. -</body> -</html>
diff --git a/weblayer/test/data/simple_page2.html b/weblayer/test/data/simple_page2.html deleted file mode 100644 index 7383cf5..0000000 --- a/weblayer/test/data/simple_page2.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<head><title>Yet another simple page</title></head> -<body> -Basic html test. -</body> -</html>
diff --git a/weblayer/test/data/simple_page3.html b/weblayer/test/data/simple_page3.html deleted file mode 100644 index a1049c4..0000000 --- a/weblayer/test/data/simple_page3.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<head><title>OK</title></head> -<body> -Basic html test2. -</body> -</html>
diff --git a/weblayer/test/data/simple_page4.html b/weblayer/test/data/simple_page4.html deleted file mode 100644 index 52e1a4d..0000000 --- a/weblayer/test/data/simple_page4.html +++ /dev/null
@@ -1,6 +0,0 @@ -<html> -<head><title>OK</title></head> -<body> - <meta http-equiv = "refresh" content = "2; url = simple_page.html" /> -</body> -</html>
diff --git a/weblayer/test/data/simple_page_with_delayed_favicon.html b/weblayer/test/data/simple_page_with_delayed_favicon.html deleted file mode 100644 index ef04aae..0000000 --- a/weblayer/test/data/simple_page_with_delayed_favicon.html +++ /dev/null
@@ -1,19 +0,0 @@ -<html> - <head> - <title>OK</title> - </head> -<body> -Basic html test. -</body> -<script> -function createFavicon() { - const link = document.createElement('link'); - link.rel = 'icon'; - link.href = 'favicon.png'; - document.head.appendChild(link); -} -window.addEventListener('message', () => { - createFavicon(); -}); -</script> -</html>
diff --git a/weblayer/test/data/simple_page_with_deleted_favicon.html b/weblayer/test/data/simple_page_with_deleted_favicon.html deleted file mode 100644 index 542daacd..0000000 --- a/weblayer/test/data/simple_page_with_deleted_favicon.html +++ /dev/null
@@ -1,15 +0,0 @@ -<html> - <head> - <title>OK</title> - <link rel="icon" id="fi" type="image/png" href="favicon.png"/> - </head> -<body> -Basic html test. -</body> -<script> -setTimeout(() => { - const link = document.getElementById('fi'); - document.head.removeChild(link); -}, 5000); -</script> -</html>
diff --git a/weblayer/test/data/simple_page_with_favicon.html b/weblayer/test/data/simple_page_with_favicon.html deleted file mode 100644 index 02e72fd..0000000 --- a/weblayer/test/data/simple_page_with_favicon.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> - <head> - <title>OK</title> - <link rel="icon" type="image/png" href="favicon.png"/> - </head> -<body> -Basic html test. -</body> -</html>
diff --git a/weblayer/test/data/simple_page_with_favicon2.html b/weblayer/test/data/simple_page_with_favicon2.html deleted file mode 100644 index 02e72fd..0000000 --- a/weblayer/test/data/simple_page_with_favicon2.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> - <head> - <title>OK</title> - <link rel="icon" type="image/png" href="favicon.png"/> - </head> -<body> -Basic html test. -</body> -</html>
diff --git a/weblayer/test/data/simple_page_with_favicon_and_before_unload.html b/weblayer/test/data/simple_page_with_favicon_and_before_unload.html deleted file mode 100644 index c46efaf..0000000 --- a/weblayer/test/data/simple_page_with_favicon_and_before_unload.html +++ /dev/null
@@ -1,14 +0,0 @@ -<html> - <head> - <title>OK</title> - <link rel="icon" type="image/png" href="favicon.png"/> - </head> -<body onbeforeunload="return runBeforeUnload()"> -Basic html test with before unload and favicon -</body> -<script> - function runBeforeUnload() { - return "foo"; - } -</script> -</html>
diff --git a/weblayer/test/data/simple_page_with_script.html b/weblayer/test/data/simple_page_with_script.html deleted file mode 100644 index e84aee5..0000000 --- a/weblayer/test/data/simple_page_with_script.html +++ /dev/null
@@ -1,7 +0,0 @@ -<html> -<head><title>OK</title></head> -<body> -Basic html with script test. -<script type="text/javascript" src="script.js"></script> -</body> -</html>
diff --git a/weblayer/test/data/simple_password_form.html b/weblayer/test/data/simple_password_form.html deleted file mode 100644 index 7608c78..0000000 --- a/weblayer/test/data/simple_password_form.html +++ /dev/null
@@ -1,9 +0,0 @@ -<html> -<body> -<form method="POST" action="done.html" onsubmit="return true;" id="testform"> - <input type="text" id="username_field" name="username_field"> - <input type="password" id="password_field" name="password_field"> - <input type="submit" id="input_submit_button" name="input_submit_button"> -</form> -</body> -</html>
diff --git a/weblayer/test/data/simple_prefetch.html b/weblayer/test/data/simple_prefetch.html deleted file mode 100644 index 7e27313..0000000 --- a/weblayer/test/data/simple_prefetch.html +++ /dev/null
@@ -1,20 +0,0 @@ -<html> -<head> -<title>Simple Prefetch Page</title> -<script> -function linkOnload() { - document.title = 'link onload'; -} - -function linkOnerror() { - document.title = 'link onerror'; -} -</script> -<link rel="prefetch" - href="prefetch_target.lnk" - onload="linkOnload()" - onerror="linkOnerror()"/> -</head> -<body> -</body> -</html> \ No newline at end of file
diff --git a/weblayer/test/data/tall_page.html b/weblayer/test/data/tall_page.html deleted file mode 100644 index 51b1a1b..0000000 --- a/weblayer/test/data/tall_page.html +++ /dev/null
@@ -1 +0,0 @@ -<p style='height:5000px'>Some text to paint</p>
diff --git a/weblayer/test/data/test_audio.ogg b/weblayer/test/data/test_audio.ogg deleted file mode 100644 index 39c302aa..0000000 --- a/weblayer/test/data/test_audio.ogg +++ /dev/null Binary files differ
diff --git a/weblayer/test/data/visibility.html b/weblayer/test/data/visibility.html deleted file mode 100644 index 820b925..0000000 --- a/weblayer/test/data/visibility.html +++ /dev/null
@@ -1,13 +0,0 @@ -<html> - <body> - <p>A (mostly) empty page.</p> - </body> - <script> - var gotHide = false; - document.addEventListener("visibilitychange", function() { - if (document.visibilityState !== 'visible') { - gotHide = true; - } - }); - </script> -</html>
diff --git a/weblayer/test/data/web_message_test.html b/weblayer/test/data/web_message_test.html deleted file mode 100644 index ec30527..0000000 --- a/weblayer/test/data/web_message_test.html +++ /dev/null
@@ -1,11 +0,0 @@ -<html> - <head><title>OK</title></head> - <script> - x.postMessage("from page"); - x.addEventListener("message", function(event) { - x.postMessage("bouncing " + event.data); - }); - </script> -<body> -</body> -</html>
diff --git a/weblayer/test/data/web_message_test2.html b/weblayer/test/data/web_message_test2.html deleted file mode 100644 index d60e185..0000000 --- a/weblayer/test/data/web_message_test2.html +++ /dev/null
@@ -1,17 +0,0 @@ -<html> - <head><title>OK</title></head> - <script> - x.postMessage("from page"); - var handler2 = function(event) { - x.postMessage("bouncing " + event.data); - }; - var handler1 = function(event) { - x.postMessage("bouncing " + event.data); - x.removeEventListener("message", handler2); - }; - x.addEventListener("message", handler1); - x.addEventListener("message", handler2); - </script> -<body> -</body> -</html>
diff --git a/weblayer/test/interstitial_utils.cc b/weblayer/test/interstitial_utils.cc deleted file mode 100644 index a45cc5d..0000000 --- a/weblayer/test/interstitial_utils.cc +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/interstitial_utils.h" - -#include "components/security_interstitials/content/bad_clock_blocking_page.h" -#include "components/security_interstitials/content/captive_portal_blocking_page.h" -#include "components/security_interstitials/content/insecure_form_blocking_page.h" -#include "components/security_interstitials/content/security_interstitial_page.h" -#include "components/security_interstitials/content/security_interstitial_tab_helper.h" -#include "components/security_interstitials/content/ssl_blocking_page.h" -#include "weblayer/browser/tab_impl.h" - -namespace weblayer { - -namespace { - -// Returns the security interstitial currently showing in |tab|, or null if -// there is no such interstitial. -security_interstitials::SecurityInterstitialPage* -GetCurrentlyShowingInterstitial(Tab* tab) { - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - - security_interstitials::SecurityInterstitialTabHelper* helper = - security_interstitials::SecurityInterstitialTabHelper::FromWebContents( - tab_impl->web_contents()); - - return helper - ? helper - ->GetBlockingPageForCurrentlyCommittedNavigationForTesting() - : nullptr; -} - -// Returns true if a security interstitial of type |type| is currently showing -// in |tab|. -bool IsShowingInterstitialOfType( - Tab* tab, - security_interstitials::SecurityInterstitialPage::TypeID type) { - auto* blocking_page = GetCurrentlyShowingInterstitial(tab); - - if (!blocking_page) - return false; - - return blocking_page->GetTypeForTesting() == type; -} - -} // namespace - -bool IsShowingSecurityInterstitial(Tab* tab) { - return GetCurrentlyShowingInterstitial(tab) != nullptr; -} - -bool IsShowingSSLInterstitial(Tab* tab) { - return IsShowingInterstitialOfType(tab, SSLBlockingPage::kTypeForTesting); -} - -bool IsShowingCaptivePortalInterstitial(Tab* tab) { - return IsShowingInterstitialOfType( - tab, CaptivePortalBlockingPage::kTypeForTesting); -} - -bool IsShowingBadClockInterstitial(Tab* tab) { - return IsShowingInterstitialOfType(tab, - BadClockBlockingPage::kTypeForTesting); -} - -bool IsShowingInsecureFormInterstitial(Tab* tab) { - return IsShowingInterstitialOfType( - tab, security_interstitials::InsecureFormBlockingPage::kTypeForTesting); -} - -} // namespace weblayer
diff --git a/weblayer/test/interstitial_utils.h b/weblayer/test/interstitial_utils.h deleted file mode 100644 index aaa176dd..0000000 --- a/weblayer/test/interstitial_utils.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_INTERSTITIAL_UTILS_H_ -#define WEBLAYER_TEST_INTERSTITIAL_UTILS_H_ - -namespace weblayer { - -class Tab; - -// Contains utilities for aiding in testing an embedder's integration of -// WebLayer's interstitial functionality. - -// Returns true iff a security interstitial is currently displaying in -// |tab|. -bool IsShowingSecurityInterstitial(Tab* tab); - -// Returns true iff an SSL error-related interstitial is currently displaying in -// |tab|. -bool IsShowingSSLInterstitial(Tab* tab); - -// Returns true iff a captive portal interstitial is currently displaying in -// |tab|. -bool IsShowingCaptivePortalInterstitial(Tab* tab); - -// Returns true iff a bad clock interstitial is currently displaying in |tab|. -bool IsShowingBadClockInterstitial(Tab* tab); - -// Returns true iff an insecure form interstitial is currently displaying in -// |tab|. -bool IsShowingInsecureFormInterstitial(Tab* tab); - -} // namespace weblayer - -#endif // WEBLAYER_TEST_INTERSTITIAL_UTILS_H_
diff --git a/weblayer/test/load_completion_observer.cc b/weblayer/test/load_completion_observer.cc deleted file mode 100644 index 31be9d4c3..0000000 --- a/weblayer/test/load_completion_observer.cc +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/load_completion_observer.h" - -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" - -namespace weblayer { - -LoadCompletionObserver::LoadCompletionObserver(Shell* shell) - : tab_(shell->tab()) { - tab_->GetNavigationController()->AddObserver(this); -} - -LoadCompletionObserver::~LoadCompletionObserver() { - tab_->GetNavigationController()->RemoveObserver(this); -} - -void LoadCompletionObserver::LoadStateChanged(bool is_loading, - bool should_show_loading_ui) { - if (!is_loading) - run_loop_.Quit(); -} - -void LoadCompletionObserver::Wait() { - run_loop_.Run(); -} - -} // namespace weblayer
diff --git a/weblayer/test/load_completion_observer.h b/weblayer/test/load_completion_observer.h deleted file mode 100644 index 321a414..0000000 --- a/weblayer/test/load_completion_observer.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_LOAD_COMPLETION_OBSERVER_H_ -#define WEBLAYER_TEST_LOAD_COMPLETION_OBSERVER_H_ - -#include "base/memory/raw_ptr.h" -#include "base/run_loop.h" -#include "weblayer/public/navigation_observer.h" - -namespace weblayer { - -class Shell; -class Tab; - -// A helper that waits for the next load to complete. -class LoadCompletionObserver : public NavigationObserver { - public: - // Creates an instance that begins waiting for a load within |shell| to - // complete. - explicit LoadCompletionObserver(Shell* shell); - - LoadCompletionObserver(const LoadCompletionObserver&) = delete; - LoadCompletionObserver& operator=(const LoadCompletionObserver&) = delete; - - ~LoadCompletionObserver() override; - - // Spins a RunLoop until the next load completes. - void Wait(); - - private: - // NavigationObserver implementation: - void LoadStateChanged(bool is_loading, bool should_show_loading_ui) override; - - raw_ptr<Tab> tab_; - base::RunLoop run_loop_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_TEST_LOAD_COMPLETION_OBSERVER_H_
diff --git a/weblayer/test/run_all_unittests.cc b/weblayer/test/run_all_unittests.cc deleted file mode 100644 index 6951e03..0000000 --- a/weblayer/test/run_all_unittests.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/functional/bind.h" -#include "base/test/launcher/unit_test_launcher.h" -#include "content/public/test/content_test_suite_base.h" -#include "content/public/test/unittest_test_suite.h" -#include "weblayer/browser/content_browser_client_impl.h" -#include "weblayer/common/content_client_impl.h" - -namespace weblayer { -namespace { - -std::unique_ptr<content::UnitTestTestSuite::ContentClients> -CreateContentClients() { - auto clients = std::make_unique<content::UnitTestTestSuite::ContentClients>(); - clients->content_client = std::make_unique<ContentClientImpl>(); - clients->content_browser_client = - std::make_unique<ContentBrowserClientImpl>(nullptr); - return clients; -} - -} // namespace - -class WebLayerTestSuite : public content::ContentTestSuiteBase { - public: - WebLayerTestSuite(int argc, char** argv) : ContentTestSuiteBase(argc, argv) {} - ~WebLayerTestSuite() override = default; - - WebLayerTestSuite(const WebLayerTestSuite&) = delete; - WebLayerTestSuite& operator=(const WebLayerTestSuite&) = delete; - - void Initialize() override { - InitializeResourceBundle(); - ContentTestSuiteBase::Initialize(); - } -}; - -} // namespace weblayer - -int main(int argc, char** argv) { - content::UnitTestTestSuite test_suite( - new weblayer::WebLayerTestSuite(argc, argv), - base::BindRepeating(weblayer::CreateContentClients)); - return base::LaunchUnitTests(argc, argv, - base::BindOnce(&content::UnitTestTestSuite::Run, - base::Unretained(&test_suite))); -}
diff --git a/weblayer/test/stub_autofill_provider.cc b/weblayer/test/stub_autofill_provider.cc deleted file mode 100644 index be4ea8f..0000000 --- a/weblayer/test/stub_autofill_provider.cc +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/stub_autofill_provider.h" - -namespace weblayer { - -StubAutofillProvider::StubAutofillProvider( - content::WebContents* web_contents, - const base::RepeatingCallback<void(const autofill::FormData&)>& - on_received_form_data) - : autofill::TestAutofillProvider(web_contents), - on_received_form_data_(on_received_form_data) {} - -StubAutofillProvider::~StubAutofillProvider() = default; - -void StubAutofillProvider::OnAskForValuesToFill( - autofill::AndroidAutofillManager* manager, - const autofill::FormData& form, - const autofill::FormFieldData& field, - const gfx::RectF& bounding_box, - autofill::AutofillSuggestionTriggerSource /*unused_trigger_source*/) { - on_received_form_data_.Run(form); -} - -} // namespace weblayer
diff --git a/weblayer/test/stub_autofill_provider.h b/weblayer/test/stub_autofill_provider.h deleted file mode 100644 index 956dc14..0000000 --- a/weblayer/test/stub_autofill_provider.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_STUB_AUTOFILL_PROVIDER_H_ -#define WEBLAYER_TEST_STUB_AUTOFILL_PROVIDER_H_ - -#include "base/functional/callback_forward.h" -#include "components/android_autofill/browser/test_autofill_provider.h" -#include "content/public/browser/web_contents.h" - -namespace weblayer { - -// A stub AutofillProvider implementation that is used in cross-platform -// integration tests of renderer-side autofill detection and communication to -// the browser. -class StubAutofillProvider : public autofill::TestAutofillProvider { - public: - // WebContents takes the ownership of StubAutofillProvider. - explicit StubAutofillProvider( - content::WebContents* web_contents, - const base::RepeatingCallback<void(const autofill::FormData&)>& - on_received_form_data); - - StubAutofillProvider(const StubAutofillProvider&) = delete; - StubAutofillProvider& operator=(const StubAutofillProvider&) = delete; - - ~StubAutofillProvider() override; - - // AutofillProvider: - void OnAskForValuesToFill( - autofill::AndroidAutofillManager* manager, - const autofill::FormData& form, - const autofill::FormFieldData& field, - const gfx::RectF& bounding_box, - autofill::AutofillSuggestionTriggerSource /*unused_trigger_source*/) - override; - - private: - base::RepeatingCallback<void(const autofill::FormData&)> - on_received_form_data_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_TEST_STUB_AUTOFILL_PROVIDER_H_
diff --git a/weblayer/test/subresource_filter_browser_test_harness.cc b/weblayer/test/subresource_filter_browser_test_harness.cc deleted file mode 100644 index 288e06c..0000000 --- a/weblayer/test/subresource_filter_browser_test_harness.cc +++ /dev/null
@@ -1,153 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/subresource_filter_browser_test_harness.h" - -#include "build/build_config.h" -#include "components/heavy_ad_intervention/heavy_ad_service.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_web_contents_helper.h" -#include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" -#include "components/subresource_filter/content/browser/ruleset_service.h" -#include "components/subresource_filter/content/browser/test_ruleset_publisher.h" -#include "components/subresource_filter/core/browser/subresource_filter_features.h" -#include "net/dns/mock_host_resolver.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/heavy_ad_service_factory.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -namespace { - -// Waits for the subresource filter ruleset data to be published as part of -// WebLayer startup. Returns immediately if ruleset data has already been -// published. -void WaitForSubresourceFilterRulesetDataToBePublished() { - auto* ruleset_service = - BrowserProcess::GetInstance()->subresource_filter_ruleset_service(); - - if (!ruleset_service->GetMostRecentlyIndexedVersion().IsValid()) { - base::RunLoop run_loop; - ruleset_service->SetRulesetPublishedCallbackForTesting( - run_loop.QuitClosure()); - - run_loop.Run(); - } -} - -// Waits for the heavy ad blocklist data to be loaded as part of -// WebLayer startup. -void WaitForHeavyAdBlocklistToBeLoaded(content::WebContents* web_contents) { - auto* heavy_ad_service = HeavyAdServiceFactory::GetForBrowserContext( - web_contents->GetBrowserContext()); - - base::RunLoop run_loop; - heavy_ad_service->NotifyOnBlocklistLoaded(run_loop.QuitClosure()); - run_loop.Run(); -} - -#if !BUILDFLAG(IS_ANDROID) -// Installs a fake database manager so that the safe browsing activation -// throttle will be created (WebLayer currently has a safe browsing database -// available in production only on Android). -void InstallFakeSafeBrowsingDatabaseManagerInWebContents( - content::WebContents* web_contents) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> database_manager = - base::MakeRefCounted<FakeSafeBrowsingDatabaseManager>(); - - subresource_filter::ContentSubresourceFilterWebContentsHelper:: - FromWebContents(web_contents) - ->SetDatabaseManagerForTesting(std::move(database_manager)); -} -#endif - -} // namespace - -SubresourceFilterBrowserTest::SubresourceFilterBrowserTest() { - feature_list_.InitAndEnableFeature( - subresource_filter::kAdsInterventionsEnforced); -} - -SubresourceFilterBrowserTest::~SubresourceFilterBrowserTest() = default; - -void SubresourceFilterBrowserTest::SetUpOnMainThread() { - // Wait for the initial publishing of production data that occurs as part of - // startup to complete. This is crucial for tests that inject test ruleset - // data and wait for it to be published via TestRulesetPublisher: if the - // initial publishing is still in process when those tests start running, - // they can end up incorrectly proceeding on the publishing of the - // production data rather than their test data. - WaitForSubresourceFilterRulesetDataToBePublished(); - - // Wait for the heavy ad blocklist loading that occurs as part of ProfileImpl - // creation to complete. This is crucial for tests of heavy ad interventions: - // if the blocklist isn't loaded all hosts are treated as blocklisted, which - // interferes with the operation of those tests. - WaitForHeavyAdBlocklistToBeLoaded(web_contents()); - -#if !BUILDFLAG(IS_ANDROID) - // Install a fake database manager so that the safe browsing activation - // throttle will be created, as that throttle is a core requirement for the - // operation of the subresource filter. - InstallFakeSafeBrowsingDatabaseManagerInWebContents(web_contents()); -#endif - - embedded_test_server()->ServeFilesFromSourceDirectory("components/test/data"); - - // This test suite does "cross-site" navigations to various domains that - // must all resolve to localhost. - host_resolver()->AddRule("*", "127.0.0.1"); - - if (StartEmbeddedTestServerAutomatically()) - ASSERT_TRUE(embedded_test_server()->Start()); -} - -void SubresourceFilterBrowserTest::SetRulesetToDisallowURLsWithPathSuffix( - const std::string& suffix) { - subresource_filter::testing::TestRulesetPair test_ruleset_pair; - test_ruleset_creator_.CreateRulesetToDisallowURLsWithPathSuffix( - suffix, &test_ruleset_pair); - - subresource_filter::testing::TestRulesetPublisher test_ruleset_publisher( - BrowserProcess::GetInstance()->subresource_filter_ruleset_service()); - ASSERT_NO_FATAL_FAILURE( - test_ruleset_publisher.SetRuleset(test_ruleset_pair.unindexed)); -} - -void SubresourceFilterBrowserTest::SetRulesetWithRules( - const std::vector<url_pattern_index::proto::UrlRule>& rules) { - subresource_filter::testing::TestRulesetPair test_ruleset_pair; - test_ruleset_creator_.CreateRulesetWithRules(rules, &test_ruleset_pair); - - subresource_filter::testing::TestRulesetPublisher test_ruleset_publisher( - BrowserProcess::GetInstance()->subresource_filter_ruleset_service()); - ASSERT_NO_FATAL_FAILURE( - test_ruleset_publisher.SetRuleset(test_ruleset_pair.unindexed)); -} - -content::WebContents* SubresourceFilterBrowserTest::web_contents() { - return static_cast<TabImpl*>(shell()->tab())->web_contents(); -} - -bool SubresourceFilterBrowserTest::WasParsedScriptElementLoaded( - content::RenderFrameHost* rfh) { - DCHECK(rfh); - return content::EvalJs(rfh, "!!document.scriptExecuted").ExtractBool(); -} - -bool SubresourceFilterBrowserTest::StartEmbeddedTestServerAutomatically() { - return true; -} - -subresource_filter::ContentSubresourceFilterThrottleManager* -SubresourceFilterBrowserTest::GetPrimaryPageThrottleManager() { - return subresource_filter::ContentSubresourceFilterThrottleManager::FromPage( - web_contents()->GetPrimaryPage()); -} - -} // namespace weblayer
diff --git a/weblayer/test/subresource_filter_browser_test_harness.h b/weblayer/test/subresource_filter_browser_test_harness.h deleted file mode 100644 index d3b37c60..0000000 --- a/weblayer/test/subresource_filter_browser_test_harness.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_SUBRESOURCE_FILTER_BROWSER_TEST_HARNESS_H_ -#define WEBLAYER_TEST_SUBRESOURCE_FILTER_BROWSER_TEST_HARNESS_H_ - -#include <string> -#include <vector> - -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/subresource_filter/core/common/test_ruleset_creator.h" -#include "components/url_pattern_index/proto/rules.pb.h" -#include "weblayer/test/weblayer_browser_test.h" - -namespace content { -class WebContents; -} - -namespace subresource_filter { -class ContentSubresourceFilterThrottleManager; -} - -namespace weblayer { - -// A base class for //weblayer browsertests that directly test or rely on -// subresource filter functionality. -class SubresourceFilterBrowserTest : public WebLayerBrowserTest { - public: - SubresourceFilterBrowserTest(); - ~SubresourceFilterBrowserTest() override; - - SubresourceFilterBrowserTest(const SubresourceFilterBrowserTest&) = delete; - SubresourceFilterBrowserTest& operator=(const SubresourceFilterBrowserTest&) = - delete; - - void SetUpOnMainThread() override; - - protected: - void SetRulesetToDisallowURLsWithPathSuffix(const std::string& suffix); - void SetRulesetWithRules( - const std::vector<url_pattern_index::proto::UrlRule>& rules); - - content::WebContents* web_contents(); - - // Returns whether a script resource that sets document.scriptExecuted to true - // on load was loaded. - bool WasParsedScriptElementLoaded(content::RenderFrameHost* rfh); - - // By default SubresourceFilterBrowsertest starts the embedded test server in - // SetUpOnMainThread(). Tests that wish to control the starting of the - // embedded test server themselves should override this method to return - // false. - virtual bool StartEmbeddedTestServerAutomatically(); - - // The ContentSubresourceFilterthrottleManager class is per-page, meaning - // each Page object will create its own instance. This method returns the - // throttle manager associated with the currently primary Page in the - // web_contents() (i.e. the one the user is currently seeing and interacting - // with, as opposed to a prerendering or BFCached page). - subresource_filter::ContentSubresourceFilterThrottleManager* - GetPrimaryPageThrottleManager(); - - private: - subresource_filter::testing::TestRulesetCreator test_ruleset_creator_; - base::test::ScopedFeatureList feature_list_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_TEST_SUBRESOURCE_FILTER_BROWSER_TEST_HARNESS_H_
diff --git a/weblayer/test/test_launcher_delegate_impl.cc b/weblayer/test/test_launcher_delegate_impl.cc deleted file mode 100644 index 7bc690c..0000000 --- a/weblayer/test/test_launcher_delegate_impl.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/test_launcher_delegate_impl.h" - -#include "base/command_line.h" -#include "base/test/test_suite.h" -#include "build/build_config.h" -#include "weblayer/app/content_main_delegate_impl.h" -#include "weblayer/public/common/switches.h" -#include "weblayer/shell/app/shell_main_params.h" - -namespace weblayer { - -int TestLauncherDelegateImpl::RunTestSuite(int argc, char** argv) { - base::TestSuite test_suite(argc, argv); - // Browser tests are expected not to tear-down various globals. - test_suite.DisableCheckForLeakedGlobals(); - return test_suite.Run(); -} - -std::string TestLauncherDelegateImpl::GetUserDataDirectoryCommandLineSwitch() { - return switches::kWebEngineUserDataDir; -} - -#if !BUILDFLAG(IS_ANDROID) -content::ContentMainDelegate* -TestLauncherDelegateImpl::CreateContentMainDelegate() { - return new ContentMainDelegateImpl(CreateMainParams()); -} -#endif - -} // namespace weblayer
diff --git a/weblayer/test/test_launcher_delegate_impl.h b/weblayer/test/test_launcher_delegate_impl.h deleted file mode 100644 index 888a1688..0000000 --- a/weblayer/test/test_launcher_delegate_impl.h +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_TEST_LAUNCHER_DELEGATE_IMPL_H_ -#define WEBLAYER_TEST_TEST_LAUNCHER_DELEGATE_IMPL_H_ - -#include "build/build_config.h" -#include "content/public/test/test_launcher.h" - -namespace weblayer { - -class TestLauncherDelegateImpl : public content::TestLauncherDelegate { - public: - int RunTestSuite(int argc, char** argv) override; - std::string GetUserDataDirectoryCommandLineSwitch() override; -#if !BUILDFLAG(IS_ANDROID) - content::ContentMainDelegate* CreateContentMainDelegate() override; -#endif -}; - -} // namespace weblayer - -#endif // WEBLAYER_TEST_TEST_LAUNCHER_DELEGATE_IMPL_H_
diff --git a/weblayer/test/test_navigation_observer.cc b/weblayer/test/test_navigation_observer.cc deleted file mode 100644 index 749ad561..0000000 --- a/weblayer/test/test_navigation_observer.cc +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/test_navigation_observer.h" - -#include "base/test/bind.h" -#include "url/gurl.h" -#include "weblayer/public/navigation.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" - -namespace weblayer { - -TestNavigationObserver::TestNavigationObserver(const GURL& url, - NavigationEvent target_event, - Shell* shell) - : TestNavigationObserver(url, target_event, shell->tab()) {} - -TestNavigationObserver::TestNavigationObserver(const GURL& url, - NavigationEvent target_event, - Tab* tab) - : url_(url), target_event_(target_event), tab_(tab) { - tab_->GetNavigationController()->AddObserver(this); -} - -TestNavigationObserver::~TestNavigationObserver() { - tab_->GetNavigationController()->RemoveObserver(this); -} - -void TestNavigationObserver::NavigationStarted(Navigation* navigation) { - // Note: We don't go through CheckNavigationCompleted() here as that waits - // for the load to be complete, which isn't appropriate when just waiting for - // the navigation to be started. - if (navigation->GetURL() == url_ && - target_event_ == NavigationEvent::kStart) { - run_loop_.Quit(); - } -} - -void TestNavigationObserver::NavigationCompleted(Navigation* navigation) { - if (navigation->GetURL() == url_) - observed_event_ = NavigationEvent::kCompletion; - CheckNavigationCompleted(); -} - -void TestNavigationObserver::NavigationFailed(Navigation* navigation) { - if (navigation->GetURL() == url_) - observed_event_ = NavigationEvent::kFailure; - CheckNavigationCompleted(); -} - -void TestNavigationObserver::LoadStateChanged(bool is_loading, - bool should_show_loading_ui) { - done_loading_ = !is_loading; - CheckNavigationCompleted(); -} - -void TestNavigationObserver::CheckNavigationCompleted() { - if (done_loading_ && observed_event_ == target_event_) - run_loop_.Quit(); -} - -void TestNavigationObserver::Wait() { - run_loop_.Run(); -} - -} // namespace weblayer
diff --git a/weblayer/test/test_navigation_observer.h b/weblayer/test/test_navigation_observer.h deleted file mode 100644 index 0846561..0000000 --- a/weblayer/test/test_navigation_observer.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_TEST_NAVIGATION_OBSERVER_H_ -#define WEBLAYER_TEST_TEST_NAVIGATION_OBSERVER_H_ - -#include "base/memory/raw_ptr.h" -#include "base/run_loop.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "url/gurl.h" -#include "weblayer/public/navigation_observer.h" - -namespace weblayer { - -class Shell; -class Tab; - -// A helper that waits for a navigation to finish. -class TestNavigationObserver : public NavigationObserver { - public: - enum class NavigationEvent { kStart, kCompletion, kFailure }; - - // Creates an instance that begins waiting for a Navigation within |shell| and - // to |url| to reach the specified |target_event|. - TestNavigationObserver(const GURL& url, - NavigationEvent target_event, - Shell* shell); - TestNavigationObserver(const GURL& url, - NavigationEvent target_event, - Tab* tab); - - TestNavigationObserver(const TestNavigationObserver&) = delete; - TestNavigationObserver& operator=(const TestNavigationObserver&) = delete; - - ~TestNavigationObserver() override; - - // Spins a RunLoop until the requested type of navigation event is observed. - void Wait(); - - private: - // NavigationObserver implementation: - void NavigationStarted(Navigation* navigation) override; - void NavigationCompleted(Navigation* navigation) override; - void NavigationFailed(Navigation* navigation) override; - void LoadStateChanged(bool is_loading, bool should_show_loading_ui) override; - - void CheckNavigationCompleted(); - - const GURL url_; - absl::optional<NavigationEvent> observed_event_; - NavigationEvent target_event_; - raw_ptr<Tab> tab_; - bool done_loading_ = false; - base::RunLoop run_loop_; -}; - -} // namespace weblayer - -#endif // WEBLAYER_TEST_TEST_NAVIGATION_OBSERVER_H_
diff --git a/weblayer/test/weblayer_browser_test.cc b/weblayer/test/weblayer_browser_test.cc deleted file mode 100644 index 2b7405d..0000000 --- a/weblayer/test/weblayer_browser_test.cc +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/base_paths.h" -#include "base/command_line.h" -#include "components/embedder_support/switches.h" -#include "content/public/browser/browser_context.h" -#include "weblayer/browser/browser_context_impl.h" -#include "weblayer/browser/profile_impl.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/common/features.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/shell/common/shell_switches.h" - -namespace weblayer { - -WebLayerBrowserTest::WebLayerBrowserTest() { - CreateTestServer(base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); -} - -WebLayerBrowserTest::~WebLayerBrowserTest() = default; - -void WebLayerBrowserTest::SetUp() { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitch(switches::kNoInitialNavigation); - - // Disable auto reload since most browser tests do not expect error pages to - // reload automatically. Tests that want auto reload can explicitly append - // embedder_support::kEnableAutoReload, which will override the disable here. - command_line->AppendSwitch(embedder_support::kDisableAutoReload); - - if (start_in_incognito_mode_) - command_line->AppendSwitch(switches::kStartInIncognito); - - SetUpCommandLine(command_line); - content::BrowserTestBase::SetUp(); -} - -void WebLayerBrowserTest::PreRunTestOnMainThread() { - ASSERT_EQ(Shell::windows().size(), 1u); - shell_ = Shell::windows()[0]; - - // Don't fill machine's download directory from tests; instead place downloads - // in the temporary user-data-dir for this test. - auto* tab_impl = static_cast<TabImpl*>(shell_->tab()); - auto* browser_context = tab_impl->web_contents()->GetBrowserContext(); - auto* browser_context_impl = - static_cast<BrowserContextImpl*>(browser_context); - browser_context_impl->profile_impl()->SetDownloadDirectory( - browser_context->GetPath()); - // Accessing a browser context may involve storage partition initialization. - // Wait for the initialization to be completed. - base::RunLoop().RunUntilIdle(); -} - -void WebLayerBrowserTest::PostRunTestOnMainThread() { - Shell::CloseAllWindows(); -} - -void WebLayerBrowserTest::SetShellStartsInIncognitoMode() { - DCHECK(!set_up_called()); - start_in_incognito_mode_ = true; -} - -ProfileImpl* WebLayerBrowserTest::GetProfile() { - return static_cast<TabImpl*>(shell_->tab())->profile(); -} - -content::BrowserContext* WebLayerBrowserTest::GetBrowserContext() { - return GetProfile()->GetBrowserContext(); -} - -} // namespace weblayer
diff --git a/weblayer/test/weblayer_browser_test.h b/weblayer/test/weblayer_browser_test.h deleted file mode 100644 index 1deea0a6..0000000 --- a/weblayer/test/weblayer_browser_test.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_H_ -#define WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_H_ - -#include "base/memory/raw_ptr.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_base.h" - -namespace content { -class BrowserContext; -} - -namespace weblayer { -class ProfileImpl; -class Shell; - -class WebLayerBrowserTest : public content::BrowserTestBase { - public: - WebLayerBrowserTest(); - - WebLayerBrowserTest(const WebLayerBrowserTest&) = delete; - WebLayerBrowserTest& operator=(const WebLayerBrowserTest&) = delete; - - ~WebLayerBrowserTest() override; - - // content::BrowserTestBase implementation. - void SetUp() override; - void PreRunTestOnMainThread() override; - void PostRunTestOnMainThread() override; - - // Configures this object such that when it starts the shell it does so in - // incognito mode. Must be invoked before SetUp() has been called. - void SetShellStartsInIncognitoMode(); - - // Returns the window for the test. - Shell* shell() const { return shell_; } - - ProfileImpl* GetProfile(); - content::BrowserContext* GetBrowserContext(); - - private: - raw_ptr<Shell> shell_ = nullptr; - bool start_in_incognito_mode_ = false; -}; - -} // namespace weblayer - -#endif // WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_H_
diff --git a/weblayer/test/weblayer_browser_test_test.cc b/weblayer/test/weblayer_browser_test_test.cc deleted file mode 100644 index 5e2a35b2..0000000 --- a/weblayer/test/weblayer_browser_test_test.cc +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test.h" - -#include "base/allocator/partition_allocator/tagging.h" -#include "base/cpu.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "weblayer/test/weblayer_browser_test_utils.h" - -namespace weblayer { - -IN_PROC_BROWSER_TEST_F(WebLayerBrowserTest, SynchronousMemoryTagging) { - // weblayer_browsertests should start up in synchronous MTE mode - base::CPU cpu; - if (cpu.has_mte()) { - ASSERT_EQ(partition_alloc::internal::GetMemoryTaggingModeForCurrentThread(), - partition_alloc::TagViolationReportingMode::kSynchronous); - - } else { - GTEST_SKIP(); - } -} - -IN_PROC_BROWSER_TEST_F(WebLayerBrowserTest, Basic) { - ASSERT_TRUE(embedded_test_server()->Start()); - GURL url = embedded_test_server()->GetURL("/simple_page.html"); - - NavigateAndWaitForCompletion(url, shell()); -} - -} // namespace weblayer
diff --git a/weblayer/test/weblayer_browser_test_utils.cc b/weblayer/test/weblayer_browser_test_utils.cc deleted file mode 100644 index 82b2f72f..0000000 --- a/weblayer/test/weblayer_browser_test_utils.cc +++ /dev/null
@@ -1,157 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "weblayer/test/weblayer_browser_test_utils.h" - -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/bind.h" -#include "build/build_config.h" -#include "components/subresource_filter/content/browser/content_subresource_filter_web_contents_helper.h" -#include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" -#include "url/gurl.h" -#include "weblayer/browser/browser_process.h" -#include "weblayer/browser/tab_impl.h" -#include "weblayer/public/navigation_controller.h" -#include "weblayer/public/tab.h" -#include "weblayer/shell/browser/shell.h" -#include "weblayer/test/test_navigation_observer.h" - -#if BUILDFLAG(IS_ANDROID) -#include "weblayer/test/stub_autofill_provider.h" -#endif // BUILDFLAG(IS_ANDROID) - -namespace weblayer { - -namespace { - -// Navigates to |url| in |tab| and waits for |event| to occur. -void NavigateAndWaitForEvent(const GURL& url, - Tab* tab, - TestNavigationObserver::NavigationEvent event) { - TestNavigationObserver test_observer(url, event, tab); - tab->GetNavigationController()->Navigate(url); - test_observer.Wait(); -} - -} // namespace - -void NavigateAndWaitForCompletion(const GURL& url, Shell* shell) { - NavigateAndWaitForEvent(url, shell->tab(), - TestNavigationObserver::NavigationEvent::kCompletion); -} - -void NavigateAndWaitForCompletion(const GURL& url, Tab* tab) { - NavigateAndWaitForEvent(url, tab, - TestNavigationObserver::NavigationEvent::kCompletion); -} - -void NavigateAndWaitForFailure(const GURL& url, Shell* shell) { - NavigateAndWaitForEvent(url, shell->tab(), - TestNavigationObserver::NavigationEvent::kFailure); -} - -void NavigateAndWaitForStart(const GURL& url, Tab* tab) { - NavigateAndWaitForEvent(url, tab, - TestNavigationObserver::NavigationEvent::kStart); -} - -base::Value ExecuteScript(Shell* shell, - const std::string& script, - bool use_separate_isolate) { - return ExecuteScript(shell->tab(), script, use_separate_isolate); -} - -base::Value ExecuteScript(Tab* tab, - const std::string& script, - bool use_separate_isolate) { - base::Value final_result; - base::RunLoop run_loop; - tab->ExecuteScript(base::ASCIIToUTF16(script), use_separate_isolate, - base::BindLambdaForTesting( - [&run_loop, &final_result](base::Value result) { - final_result = std::move(result); - run_loop.Quit(); - })); - run_loop.Run(); - return final_result; -} - -void ExecuteScriptWithUserGesture(Shell* shell, const std::string& script) { - ExecuteScriptWithUserGesture(shell->tab(), script); -} - -void ExecuteScriptWithUserGesture(Tab* tab, const std::string& script) { - TabImpl* tab_impl = static_cast<TabImpl*>(tab); - tab_impl->ExecuteScriptWithUserGestureForTests(base::ASCIIToUTF16(script)); -} - -const std::u16string& GetTitle(Shell* shell) { - TabImpl* tab_impl = static_cast<TabImpl*>(shell->tab()); - - return tab_impl->web_contents()->GetTitle(); -} - -#if BUILDFLAG(IS_ANDROID) -void InitializeAutofillWithEventForwarding( - Shell* shell, - const base::RepeatingCallback<void(const autofill::FormData&)>& - on_received_form_data) { - TabImpl* tab_impl = static_cast<TabImpl*>(shell->tab()); - new StubAutofillProvider(tab_impl->web_contents(), on_received_form_data); - tab_impl->InitializeAutofillForTests(); -} -#endif // BUILDFLAG(IS_ANDROID) - -void ActivateSubresourceFilterInWebContentsForURL( - content::WebContents* web_contents, - const GURL& url) { - scoped_refptr<FakeSafeBrowsingDatabaseManager> database_manager = - base::MakeRefCounted<FakeSafeBrowsingDatabaseManager>(); - database_manager->AddBlocklistedUrl( - url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING); - - subresource_filter::ContentSubresourceFilterWebContentsHelper:: - FromWebContents(web_contents) - ->SetDatabaseManagerForTesting(std::move(database_manager)); -} - -OneShotNavigationObserver::OneShotNavigationObserver(Shell* shell) - : tab_(shell->tab()) { - tab_->GetNavigationController()->AddObserver(this); -} - -OneShotNavigationObserver::~OneShotNavigationObserver() { - tab_->GetNavigationController()->RemoveObserver(this); -} - -void OneShotNavigationObserver::WaitForNavigation() { - run_loop_.Run(); -} - -void OneShotNavigationObserver::NavigationStarted(Navigation* navigation) { - is_page_initiated_ = navigation->IsPageInitiated(); -} - -void OneShotNavigationObserver::NavigationCompleted(Navigation* navigation) { - completed_ = true; - Finish(navigation); -} - -void OneShotNavigationObserver::NavigationFailed(Navigation* navigation) { - Finish(navigation); -} - -void OneShotNavigationObserver::Finish(Navigation* navigation) { - is_error_page_ = navigation->IsErrorPage(); - is_download_ = navigation->IsDownload(); - is_reload_ = navigation->IsReload(); - was_stop_called_ = navigation->WasStopCalled(); - load_error_ = navigation->GetLoadError(); - http_status_code_ = navigation->GetHttpStatusCode(); - navigation_state_ = navigation->GetState(); - run_loop_.Quit(); -} - -} // namespace weblayer
diff --git a/weblayer/test/weblayer_browser_test_utils.h b/weblayer/test/weblayer_browser_test_utils.h deleted file mode 100644 index 5904c7de..0000000 --- a/weblayer/test/weblayer_browser_test_utils.h +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_UTILS_H_ -#define WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_UTILS_H_ - -#include <string> - -#include "base/functional/callback_forward.h" -#include "base/memory/raw_ptr.h" -#include "base/run_loop.h" -#include "base/values.h" -#include "build/build_config.h" -#include "weblayer/public/navigation.h" -#include "weblayer/public/navigation_observer.h" - -class GURL; - -namespace autofill { -struct FormData; -} - -namespace content { -class WebContents; -} - -namespace weblayer { -class Shell; -class Tab; - -// Navigates |shell| to |url| and wait for completed navigation. -void NavigateAndWaitForCompletion(const GURL& url, Shell* shell); - -void NavigateAndWaitForCompletion(const GURL& url, Tab* tab); - -// Navigates |shell| to |url| and wait for failed navigation. -void NavigateAndWaitForFailure(const GURL& url, Shell* shell); - -// Initiates navigation to |url| in |tab| and waits for it to start. -void NavigateAndWaitForStart(const GURL& url, Tab* tab); - -// Executes |script| in |shell| and returns the result. -base::Value ExecuteScript(Shell* shell, - const std::string& script, - bool use_separate_isolate); -base::Value ExecuteScript(Tab* tab, - const std::string& script, - bool use_separate_isolate); - -// Executes |script| in |shell| with a user gesture. Useful for tests of -// functionality that gates action on a user gesture having occurred. -// Differs from ExecuteScript() as follows: -// - Does not notify the caller of the result as the underlying implementation -// does not. Thus, unlike the above, the caller of this function will need to -// explicitly listen *after* making this call for any expected event to -// occur. -// - Does not allow running in a separate isolate as the machinery for -// setting a user gesture works only in the main isolate. -void ExecuteScriptWithUserGesture(Shell* shell, const std::string& script); -void ExecuteScriptWithUserGesture(Tab* tab, const std::string& script); - -/// Gets the title of the current webpage in |shell|. -const std::u16string& GetTitle(Shell* shell); - -#if BUILDFLAG(IS_ANDROID) -// Sets up the autofill system to be one that simply forwards detected forms to -// the passed-in callback. -void InitializeAutofillWithEventForwarding( - Shell* shell, - const base::RepeatingCallback<void(const autofill::FormData&)>& - on_received_form_data); -#endif // BUILDFLAG(IS_ANDROID) - -// Configures the subresource filter to activate on |url| in |web_contents|. -void ActivateSubresourceFilterInWebContentsForURL( - content::WebContents* web_contents, - const GURL& url); - -class OneShotNavigationObserver : public NavigationObserver { - public: - explicit OneShotNavigationObserver(Shell* shell); - - ~OneShotNavigationObserver() override; - - void WaitForNavigation(); - - bool completed() { return completed_; } - bool is_error_page() { return is_error_page_; } - bool is_download() { return is_download_; } - bool is_reload() { return is_reload_; } - bool was_stop_called() { return was_stop_called_; } - Navigation::LoadError load_error() { return load_error_; } - int http_status_code() { return http_status_code_; } - NavigationState navigation_state() { return navigation_state_; } - bool is_page_initiated() const { return is_page_initiated_; } - - private: - // NavigationObserver implementation: - void NavigationStarted(Navigation* navigation) override; - void NavigationCompleted(Navigation* navigation) override; - void NavigationFailed(Navigation* navigation) override; - - void Finish(Navigation* navigation); - - base::RunLoop run_loop_; - raw_ptr<Tab> tab_; - bool completed_ = false; - bool is_error_page_ = false; - bool is_download_ = false; - bool is_reload_ = false; - bool was_stop_called_ = false; - bool is_page_initiated_ = false; - Navigation::LoadError load_error_ = Navigation::kNoError; - int http_status_code_ = 0; - NavigationState navigation_state_ = NavigationState::kWaitingResponse; -}; - -} // namespace weblayer - -#endif // WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_UTILS_H_
diff --git a/weblayer/tools/run_webengine_shell.py b/weblayer/tools/run_webengine_shell.py deleted file mode 100755 index 0bcf880..0000000 --- a/weblayer/tools/run_webengine_shell.py +++ /dev/null
@@ -1,80 +0,0 @@ -#!/usr/bin/env python -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from __future__ import absolute_import -from __future__ import print_function -import argparse -import os -import subprocess -import sys - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, - 'build', 'android')) -import devil_chromium -from devil.android import apk_helper -from devil.android import device_utils - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--shell-apk-path', type=os.path.abspath, required=True, - help='Absolute path to the WebEngine shell APK to use.') - parser.add_argument('--support-apk-path', action='append', - type=os.path.abspath, default=[], - help='Absolute path to the WebLayer support APKs to ' - 'use. Specify multiple times for multiple paths.') - parser.add_argument('--switch-webview-to', type=str, required=False, - help='APK to set as the WebView implementation.') - parser.add_argument('-d', '--device', dest='devices', action='append', - default=[], - help='Target device for apk to install on. Enter multiple' - ' times for multiple devices.') - parser.add_argument('remaining_args', nargs=argparse.REMAINDER, - help='Flags to be passed to WebLayer should be appended' - ' as --args="--myflag"') - args = parser.parse_args() - - devil_chromium.Initialize() - devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices) - - def install(device): - print('Installing %s...' % args.shell_apk_path) - device.Install(args.shell_apk_path, reinstall=True, allow_downgrade=True) - print('Success') - for path in args.support_apk_path: - print('Installing %s...' % path) - device.Install(path, reinstall=True, allow_downgrade=True) - print('Success') - if args.switch_webview_to: - print('Installing %s...' % args.switch_webview_to) - device.Install(args.switch_webview_to, reinstall=True, - allow_downgrade=True) - package = apk_helper.GetPackageName(args.switch_webview_to) - print('Setting WebView implementation to %s' % package) - device.SetWebViewImplementation(package) - print('Done') - - if (os.path.basename(args.shell_apk_path) == "WEShellLocal.apk"): - launch_cmd = [ - os.path.join(os.path.dirname(args.shell_apk_path), - os.pardir, 'bin', 'webengine_shell_local_apk'), - 'launch' - ] - launch_cmd.extend(args.remaining_args) - subprocess.call(launch_cmd) - elif (os.path.basename(args.shell_apk_path) == "WEShellSandbox.apk"): - launch_cmd = [ - os.path.join(os.path.dirname(args.shell_apk_path), - os.pardir, 'bin', 'webengine_shell_sandbox_apk'), - 'launch' - ] - launch_cmd.extend(args.remaining_args) - subprocess.call(launch_cmd) - else: - device.adb.Shell('monkey -p org.chromium.webengine.shell 1') - - device_utils.DeviceUtils.parallel(devices).pMap(install) - -if __name__ == '__main__': - sys.exit(main())
diff --git a/weblayer/variables.gni b/weblayer/variables.gni deleted file mode 100644 index b10d15b5..0000000 --- a/weblayer/variables.gni +++ /dev/null
@@ -1,12 +0,0 @@ -# Copyright 2019 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/android/channel.gni") - -declare_args() { - # Include the //weblayer code in WebView implementation APKs. - webview_includes_weblayer = false -} - -weblayer_product_config_java_package = "org.chromium.weblayer_private"
diff --git a/weblayer/weblayer_module.gni b/weblayer/weblayer_module.gni deleted file mode 100644 index b2215e3..0000000 --- a/weblayer/weblayer_module.gni +++ /dev/null
@@ -1,8 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -weblayer_module_desc = { - name = "weblayer" - android_manifest = "//weblayer/browser/java/AndroidManifest_monochrome.xml" -}
diff --git a/weblayer/weblayer_resource_exclusions.gni b/weblayer/weblayer_resource_exclusions.gni deleted file mode 100644 index 3d6aa22..0000000 --- a/weblayer/weblayer_resource_exclusions.gni +++ /dev/null
@@ -1,67 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -_material_package = "*com_google_android_material*" - -weblayer_resource_exclusion_exceptions = [ - # TextInputLayout (used for HTTP Auth dialog) - "${_material_package}/design_text_*", - "${_material_package}/text_*", - - # Used for the translate infobar - "${_material_package}/design_layout_tab_*", - - # Referenced by Widget.Material3.AutoCompleteTextView. For context: - # https://crbug.com/1298549 - "${_material_package}/layout/m3_auto_complete_simple_item.xml", - "${_material_package}/layout/mtrl_auto_complete_simple_item.xml", - - # Referenced by Base.ThemeOverlay.Material3.Dialog. For context: - # https://crbug.com/1392477 - "${_material_package}/layout/m*_alert_*dialog*", -] - -# Copied from chrome_public_apk_tmpl.gni. - -# resource_values_filter_rules: Filters per-resource, after "aapt2 compile". -# Before ":" matches .zip path. -# After ":" matches resource name (e.g. "attr/selectorSize"). -# -# resource_exclusion_regex: Filters per-file, before "aapt2 compile". - -# Remove unneeded entries from material design values.xml files. -weblayer_resource_values_filter_rules = [ - "${_material_package}:[Bb]adge", - "${_material_package}:[Bb]ottomNavigation", - "${_material_package}:[Bb]ottomSheet", - "${_material_package}:[Bb]uttonToggleGroup", - "${_material_package}:[Cc]alendar", - "${_material_package}:design_snackbar", - "${_material_package}:[Ff]loatingActionButton", - "${_material_package}:mtrl_slider", - "${_material_package}:[Nn]avigationView", - "${_material_package}:[Pp]icker", - "${_material_package}:[Ss]nackbar", - "${_material_package}:[Ss]lider", - "${_material_package}:[Tt]oolbarLayout", -] - -_material_package = "com_google_android_material.*" - -# Used only by alert dialog on tiny screens. -weblayer_resource_exclusion_regex = "${_material_package}values-small" - -# Used only by date picker (which chrome doesn't use). -weblayer_resource_exclusion_regex += - "|${_material_package}-(w480dp-port|w360dp-port|h480dp-land|h360dp-land)" - -# Material design layouts that cause views to be kept that we don't use. -# Instead of manually filtering, unused resource removal would be better: -# https://crbug.com/636448 -weblayer_resource_exclusion_regex += "|${_material_package}/layout" -weblayer_resource_exclusion_regex += - "|${_material_package}/color.*(calendar_|bottom_nav_|picker_|slider_)" -weblayer_resource_exclusion_regex += - "|${_material_package}/drawable.*design_snackbar" -weblayer_resource_exclusion_regex += "|${_material_package}/xml.*badge_"
diff --git a/weblayer/weblayer_resources.grd b/weblayer/weblayer_resources.grd deleted file mode 100644 index a5ae275c..0000000 --- a/weblayer/weblayer_resources.grd +++ /dev/null
@@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> - <outputs> - <output filename="grit/weblayer_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="weblayer_resources.pak" type="data_package" /> - </outputs> - <translations /> - <release seq="1"> - <includes> - <include name="IDR_NET_LOG_NET_EXPORT_CSS" file="../components/net_log/resources/net_export.css" type="BINDATA" /> - <include name="IDR_NET_LOG_NET_EXPORT_HTML" file="../components/net_log/resources/net_export.html" preprocess="true" type="BINDATA" /> - <include name="IDR_NET_LOG_NET_EXPORT_JS" file="../components/net_log/resources/net_export.js" preprocess="true" type="BINDATA" /> - <include name="IDR_WEBLAYER_INTERNALS_HTML" file="browser/resources/weblayer_internals/weblayer_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_WEBLAYER_INTERNALS_JS" file="browser/resources/weblayer_internals/weblayer_internals.js" flattenhtml="true" type="BINDATA" /> - <include name="IDR_WEBLAYER_INTERNALS_MOJO_JS" file="${root_gen_dir}/mojom-webui/weblayer/browser/webui/weblayer_internals.mojom-webui.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET" file="../third_party/subresource-filter-ruleset/data/UnindexedRules" type="BINDATA" compress="brotli" /> - <include name="IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON" file="../third_party/subresource-filter-ruleset/manifest.json" type="BINDATA" /> - </includes> - </release> -</grit>